From aa4f711b6bb66b0288a759de49ae8563f2a1473f Mon Sep 17 00:00:00 2001 From: Kenneth Belitzky Date: Sat, 28 Sep 2024 19:27:47 -0300 Subject: [PATCH 1/5] Refactor import and info commands to improve structure handling --- struct_module/commands/import.py | 63 ++++++++++++++++++++++++++++++++ struct_module/commands/info.py | 56 ++++++++++++++++++++++++---- 2 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 struct_module/commands/import.py diff --git a/struct_module/commands/import.py b/struct_module/commands/import.py new file mode 100644 index 0000000..c5a3156 --- /dev/null +++ b/struct_module/commands/import.py @@ -0,0 +1,63 @@ +from struct_module.commands import Command +import os +import yaml + +# Import command class +# This class is responsible for importing a structure definition given a file path. It will create the structure in the base path provided. +class ImportCommand(Command): + def __init__(self, parser): + super().__init__(parser) + parser.add_argument('import_from', type=str, help='Directory to import the structure from') + parser.add_argument('-o', '--output-path', type=str, help='Path to the output directory', default='.') + parser.set_defaults(func=self.execute) + + def execute(self, args): + self.logger.info(f"Importing structure from {args.import_from} to {args.output_path}") + + self._import_structure(args) + + + def _import_structure(self, args): + # Check if the import_from directory exists + if not os.path.exists(args.import_from): + self.logger.error(f"Directory not found: {args.import_from}") + return + + # Define the path for the structure.yaml file + structure_definition = os.path.join(args.output_path, 'structure.yaml') + + # Check if the output_path exists, if not, create it + if not os.path.exists(args.output_path): + self.logger.warning(f"Output path not found: {args.output_path}, creating it") + os.makedirs(args.output_path) + + # Check if the structure.yaml file already exists + if os.path.exists(structure_definition): + self.logger.warning(f"Structure definition already exists at {structure_definition}") + # Ask the user if they want to overwrite the existing structure.yaml file + if input("Do you want to overwrite it? (y/N) ").lower() != 'y': + return + + # Initialize the structure dictionary + generated_structure = { + 'structure': [], + 'folders': [], + 'variables': [] + } + + for root, dirs, files in os.walk(args.import_from): + for file in files: + self.logger.info(f"Processing file {file}") + file_path = os.path.join(root, file) + relative_path = os.path.relpath(file_path, args.import_from) + generated_structure['structure'].append( + { + 'path': relative_path, + 'content': open(file_path, 'r').read() + } + ) + + with open(structure_definition, 'w') as f: + self.logger.info(f"Writing structure definition to {structure_definition}") + yaml.dump(generated_structure, f) + diff --git a/struct_module/commands/info.py b/struct_module/commands/info.py index e995c03..2d477e2 100644 --- a/struct_module/commands/info.py +++ b/struct_module/commands/info.py @@ -1,15 +1,55 @@ +import os +import yaml + from struct_module.commands import Command -# Info command class +# Info command class for exposing information about the structure class InfoCommand(Command): def __init__(self, parser): super().__init__(parser) + parser.add_argument('structure_definition', type=str, help='Name of the structure definition') + parser.add_argument('-s', '--structures-path', type=str, help='Path to structure definitions') + + parser.set_defaults(func=self.execute) def execute(self, args): - print("STRUCT 1.0.0") - print("") - print("Generate project structure from YAML configuration.") - print("Commands:") - print(" generate Generate the project structure") - print(" validate Validate the YAML configuration file") - print(" info Show information about the package") + self.logger.info(f"Getting info for structure {args.structure_definition}") + + self._get_info(args) + + def _get_info(self, args): + if args.structure_definition.startswith("file://") and args.structure_definition.endswith(".yaml"): + with open(args.structure_definition[7:], 'r') as f: + config = yaml.safe_load(f) + else: + if args.structures_path is None: + this_file = os.path.dirname(os.path.realpath(__file__)) + file_path = os.path.join(this_file, "..", "contribs", f"{args.structure_definition}.yaml") + else: + file_path = os.path.join(args.structures_path, f"{args.structure_definition}.yaml") + # show error if file is not found + if not os.path.exists(file_path): + self.logger.error(f"File not found: {file_path}") + return + with open(file_path, 'r') as f: + config = yaml.safe_load(f) + + print("Structure definition:") + print(f" - Name: {args.structure_definition}") + print(f" - Description: {config.get('description', 'No description')}") + + if config.get('structure'): + print(f" - Structure:") + for item in config.get('structure', []): + for name, content in item.items(): + print(f" - {name}: ") + # indent all lines of content + for line in content.get('content', content.get('file', 'Not defined')).split('\n'): + print(f" {line}") + + if config.get('folders'): + print(f" - Folders:") + for folder in config.get('folders', []): + print(f" - {folder}: {folder.get('struct', 'No structure')}") + + From 4168d8629864e50276a74d0ee263fad760e26b76 Mon Sep 17 00:00:00 2001 From: Kenneth Belitzky Date: Mon, 3 Feb 2025 22:04:21 -0300 Subject: [PATCH 2/5] Enhance output formatting in InfoCommand for better readability --- struct_module/commands/import.py | 86 ++++++++++++++++---------------- struct_module/commands/info.py | 19 +++---- 2 files changed, 53 insertions(+), 52 deletions(-) diff --git a/struct_module/commands/import.py b/struct_module/commands/import.py index c5a3156..d386717 100644 --- a/struct_module/commands/import.py +++ b/struct_module/commands/import.py @@ -18,46 +18,46 @@ def execute(self, args): def _import_structure(self, args): - # Check if the import_from directory exists - if not os.path.exists(args.import_from): - self.logger.error(f"Directory not found: {args.import_from}") - return - - # Define the path for the structure.yaml file - structure_definition = os.path.join(args.output_path, 'structure.yaml') - - # Check if the output_path exists, if not, create it - if not os.path.exists(args.output_path): - self.logger.warning(f"Output path not found: {args.output_path}, creating it") - os.makedirs(args.output_path) - - # Check if the structure.yaml file already exists - if os.path.exists(structure_definition): - self.logger.warning(f"Structure definition already exists at {structure_definition}") - # Ask the user if they want to overwrite the existing structure.yaml file - if input("Do you want to overwrite it? (y/N) ").lower() != 'y': - return - - # Initialize the structure dictionary - generated_structure = { - 'structure': [], - 'folders': [], - 'variables': [] - } - - for root, dirs, files in os.walk(args.import_from): - for file in files: - self.logger.info(f"Processing file {file}") - file_path = os.path.join(root, file) - relative_path = os.path.relpath(file_path, args.import_from) - generated_structure['structure'].append( - { - 'path': relative_path, - 'content': open(file_path, 'r').read() - } - ) - - with open(structure_definition, 'w') as f: - self.logger.info(f"Writing structure definition to {structure_definition}") - yaml.dump(generated_structure, f) - + raise NotImplementedError("This method needs to be implemented") + # # Check if the import_from directory exists + # if not os.path.exists(args.import_from): + # self.logger.error(f"Directory not found: {args.import_from}") + # return + + # # Define the path for the structure.yaml file + # structure_definition = os.path.join(args.output_path, 'structure.yaml') + + # # Check if the output_path exists, if not, create it + # if not os.path.exists(args.output_path): + # self.logger.warning(f"Output path not found: {args.output_path}, creating it") + # os.makedirs(args.output_path) + + # # Check if the structure.yaml file already exists + # if os.path.exists(structure_definition): + # self.logger.warning(f"Structure definition already exists at {structure_definition}") + # # Ask the user if they want to overwrite the existing structure.yaml file + # if input("Do you want to overwrite it? (y/N) ").lower() != 'y': + # return + + # # Initialize the structure dictionary + # generated_structure = { + # 'structure': [], + # 'folders': [], + # 'variables': [] + # } + + # for root, dirs, files in os.walk(args.import_from): + # for file in files: + # self.logger.info(f"Processing file {file}") + # file_path = os.path.join(root, file) + # relative_path = os.path.relpath(file_path, args.import_from) + # generated_structure['structure'].append( + # { + # 'path': relative_path, + # 'content': open(file_path, 'r').read() + # } + # ) + + # with open(structure_definition, 'w') as f: + # self.logger.info(f"Writing structure definition to {structure_definition}") + # yaml.dump(generated_structure, f) diff --git a/struct_module/commands/info.py b/struct_module/commands/info.py index 258dc0c..16cd79d 100644 --- a/struct_module/commands/info.py +++ b/struct_module/commands/info.py @@ -34,21 +34,22 @@ def _get_info(self, args): with open(file_path, 'r') as f: config = yaml.safe_load(f) - print("Structure definition:") - print(f" - Name: {args.structure_definition}") - print(f" - Description: {config.get('description', 'No description')}") + print("📒 Structure definition\n") + print(f" 📌 Name: {args.structure_definition}\n") + print(f" 📌 Description: {config.get('description', 'No description')}\n") if config.get('structure'): - print(f" - Structure:") + print(f" 📌 Structure:") for item in config.get('structure', []): for name, content in item.items(): - print(f" - {name}: ") + print(f" - {name} ") # indent all lines of content - for line in content.get('content', content.get('file', 'Not defined')).split('\n'): - print(f" {line}") + # for line in content.get('content', content.get('file', 'Not defined')).split('\n'): + # print(f" {line}") if config.get('folders'): - print(f" - Folders:") + print(f" 📌 Folders:") for folder in config.get('folders', []): - print(f" - {folder}: {folder.get('struct', 'No structure')}") + print(f" - {folder}") + # print(f" - {folder}: {folder.get('struct', 'No structure')}") From e23d95d9eeab1a02bcae491e6ca56e4414a594cd Mon Sep 17 00:00:00 2001 From: Kenneth Belitzky Date: Mon, 3 Feb 2025 22:09:34 -0300 Subject: [PATCH 3/5] Remove unnecessary blank lines in ListCommand and get_current_repo functions --- struct_module/commands/list.py | 3 --- struct_module/utils.py | 1 - 2 files changed, 4 deletions(-) diff --git a/struct_module/commands/list.py b/struct_module/commands/list.py index 0bfc1dc..fce81ef 100644 --- a/struct_module/commands/list.py +++ b/struct_module/commands/list.py @@ -44,6 +44,3 @@ def _list_structures(self, args): print("\nUse 'struct generate' to generate the structure") print("Note: Structures with '+' sign are custom structures") - - - diff --git a/struct_module/utils.py b/struct_module/utils.py index a0a74a7..7389586 100644 --- a/struct_module/utils.py +++ b/struct_module/utils.py @@ -34,4 +34,3 @@ def get_current_repo(): project_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..") - From 26e8f0224221ea7dc314c18d76c58ce827be6b29 Mon Sep 17 00:00:00 2001 From: Kenneth Belitzky Date: Mon, 3 Feb 2025 22:14:51 -0300 Subject: [PATCH 4/5] Refactor devcontainer configuration by removing unused features and adding customization for VSCode extensions --- .devcontainer/devcontainer.json | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f909b96..c13b94b 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,14 +5,7 @@ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile "image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye", "features": { - "ghcr.io/devcontainers/features/python:1": { - "installTools": true, - "version": "latest" - }, - "ghcr.io/lentzi90/features/yamlfmt:0": { - "version": "v0.14.0" - }, - "ghcr.io/gvatsal60/dev-container-features/pre-commit:1": {} + }, // Features to add to the dev container. More info: https://containers.dev/features. @@ -25,7 +18,12 @@ "postCreateCommand": "bash ./scripts/devcontainer_start.sh", // Configure tool-specific properties. - // "customizations": {}, + "customizations": { + "vscode": { + "extensions": [ + ] + } + }, // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. "remoteUser": "root" From e96feeec93a2eb5638c029bb2a16728b7d8f2a17 Mon Sep 17 00:00:00 2001 From: Kenneth Belitzky Date: Mon, 3 Feb 2025 22:17:18 -0300 Subject: [PATCH 5/5] Remove unnecessary blank line in InfoCommand class for cleaner code --- struct_module/commands/info.py | 1 - 1 file changed, 1 deletion(-) diff --git a/struct_module/commands/info.py b/struct_module/commands/info.py index 16cd79d..6dbafc5 100644 --- a/struct_module/commands/info.py +++ b/struct_module/commands/info.py @@ -52,4 +52,3 @@ def _get_info(self, args): for folder in config.get('folders', []): print(f" - {folder}") # print(f" - {folder}: {folder.get('struct', 'No structure')}") -