From 00b0ae7ba439a5a420095175b3bedd52c569db51 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Wed, 19 Apr 2023 20:55:42 +1000 Subject: PyParted and a large rewrite of the underlying partitioning (#1604) * Invert mypy files * Add optional pre-commit hooks * New profile structure * Serialize profiles * Use profile instead of classmethod * Custom profile setup * Separator between back * Support profile import via url * Move profiles module * Refactor files * Remove symlink * Add user to docker group * Update schema description * Handle list services * mypy fixes * mypy fixes * Rename profilesv2 to profiles * flake8 * mypy again * Support selecting DM * Fix mypy * Cleanup * Update greeter setting * Update schema * Revert toml changes * Poc external dependencies * Dependency support * New encryption menu * flake8 * Mypy and flake8 * Unify lsblk command * Update bootloader configuration * Git hooks * Fix import * Pyparted * Remove custom font setting * flake8 * Remove default preview * Manual partitioning menu * Update structure * Disk configuration * Update filesystem * luks2 encryption * Everything works until installation * Btrfsutil * Btrfs handling * Update btrfs * Save encryption config * Fix pipewire issue * Update mypy version * Update all pre-commit * Update package versions * Revert audio/pipewire * Merge master PRs * Add master changes * Merge master changes * Small renaming * Pull master changes * Reset disk enc after disk config change * Generate locals * Update naming * Fix imports * Fix broken sync * Fix pre selection on table menu * Profile menu * Update profile * Fix post_install * Added python-pyparted to PKGBUILD, this requires [testing] to be enabled in order to run makepkg. Package still works via python -m build etc. * Swaped around some setuptools logic in pyproject Since we define `package-data` and `packages` there should be no need for: ``` [tool.setuptools.packages.find] where = ["archinstall", "archinstall.*"] ``` * Removed pyproject collisions. Duplicate definitions. * Made sure pyproject.toml includes languages * Add example and update README * Fix pyproject issues * Generate locale * Refactor imports * Simplify imports * Add profile description and package examples * Align code * Fix mypy * Simplify imports * Fix saving config * Fix wrong luks merge * Refactor installation * Fix cdrom device loading * Fix wrongly merged code * Fix imports and greeter * Don't terminate on partprobe error * Use specific path on partprobe from luks * Update archinstall/lib/disk/device_model.py Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com> * Update archinstall/lib/disk/device_model.py Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com> * Update github workflow to test archinstall installation * Update sway merge * Generate locales * Update workflow --------- Co-authored-by: Daniel Girtler Co-authored-by: Anton Hvornum Co-authored-by: Anton Hvornum Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com> --- archinstall/lib/output.py | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) (limited to 'archinstall/lib/output.py') diff --git a/archinstall/lib/output.py b/archinstall/lib/output.py index 709a7382..d65f835f 100644 --- a/archinstall/lib/output.py +++ b/archinstall/lib/output.py @@ -2,7 +2,7 @@ import logging import os import sys from pathlib import Path -from typing import Dict, Union, List, Any, Callable +from typing import Dict, Union, List, Any, Callable, Optional from .storage import storage from dataclasses import asdict, is_dataclass @@ -11,7 +11,12 @@ from dataclasses import asdict, is_dataclass class FormattedOutput: @classmethod - def values(cls, o: Any, class_formatter: str = None, filter_list: List[str] = None) -> Dict[str, Any]: + def values( + cls, + o: Any, + class_formatter: Optional[Union[str, Callable]] = None, + filter_list: List[str] = [] + ) -> Dict[str, Any]: """ the original values returned a dataclass as dict thru the call to some specific methods this version allows thru the parameter class_formatter to call a dynamicly selected formatting method. Can transmit a filter list to the class_formatter, @@ -25,7 +30,8 @@ class FormattedOutput: elif hasattr(o, class_formatter) and callable(getattr(o, class_formatter)): func = getattr(o, class_formatter) return func(filter_list) - # kept as to make it backward compatible + + raise ValueError('Unsupported formatting call') elif hasattr(o, 'as_json'): return o.as_json() elif hasattr(o, 'json'): @@ -36,7 +42,13 @@ class FormattedOutput: return o.__dict__ @classmethod - def as_table(cls, obj: List[Any], class_formatter: Union[str, Callable] = None, filter_list: List[str] = None) -> str: + def as_table( + cls, + obj: List[Any], + class_formatter: Optional[Union[str, Callable]] = None, + filter_list: List[str] = [], + capitalize: bool = False + ) -> str: """ variant of as_table (subtly different code) which has two additional parameters filter which is a list of fields which will be shon class_formatter a special method to format the outgoing data @@ -46,6 +58,7 @@ class FormattedOutput: As_table_filter can be a drop in replacement for as_table """ raw_data = [cls.values(o, class_formatter, filter_list) for o in obj] + # determine the maximum column size column_width: Dict[str, int] = {} for o in raw_data: @@ -55,14 +68,20 @@ class FormattedOutput: column_width[k] = max([column_width[k], len(str(v)), len(k)]) if not filter_list: - filter_list = (column_width.keys()) + filter_list = list(column_width.keys()) + # create the header lines output = '' key_list = [] for key in filter_list: width = column_width[key] - key = key.replace('!', '') + key = key.replace('!', '').replace('_', ' ') + + if capitalize: + key = key.capitalize() + key_list.append(key.ljust(width)) + output += ' | '.join(key_list) + '\n' output += '-' * len(output) + '\n' @@ -82,6 +101,20 @@ class FormattedOutput: return output + @classmethod + def as_columns(cls, entries: List[str], cols: int) -> str: + chunks = [] + output = '' + + for i in range(0, len(entries), cols): + chunks.append(entries[i:i + cols]) + + for row in chunks: + out_fmt = '{: <30} ' * len(row) + output += out_fmt.format(*row) + '\n' + + return output + class Journald: @staticmethod @@ -204,6 +237,6 @@ def log(*args :str, **kwargs :Union[str, int, Dict[str, Union[str, int]]]) -> No # Finally, print the log unless we skipped it based on level. # We use sys.stdout.write()+flush() instead of print() to try and # fix issue #94 - if kwargs.get('level', logging.INFO) != logging.DEBUG or storage['arguments'].get('verbose', False): + if kwargs.get('level', logging.INFO) != logging.DEBUG or storage.get('arguments', {}).get('verbose', False): sys.stdout.write(f"{string}\n") sys.stdout.flush() -- cgit v1.2.3-70-g09d2