From 96ba88470fc7d91cf449db6a2681f93d1222e43e Mon Sep 17 00:00:00 2001 From: panwentao Date: Mon, 27 Nov 2023 17:03:09 +0800 Subject: [PATCH 1/3] manifest: Modify minitest function parameters * Modify the - c command in the manifest function to the create command * Modify the - r command in the manifest function to the download command * In the newly added minifest function, if the user does not specify a path, they will search for the manifest.yaml file in the current oebuild working environment Signed-off-by: panwentao --- src/oebuild/app/plugins/manifest/manifest.py | 49 +++++++++----------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/src/oebuild/app/plugins/manifest/manifest.py b/src/oebuild/app/plugins/manifest/manifest.py index 1eaca5e..745fce8 100644 --- a/src/oebuild/app/plugins/manifest/manifest.py +++ b/src/oebuild/app/plugins/manifest/manifest.py @@ -38,6 +38,7 @@ class Manifest(OebuildCommand): def __init__(self): self.configure = Configure() + self.manifest_command = ['download', 'create'] super().__init__( 'manifest', 'generate manifest from oebuild workspace', @@ -53,27 +54,11 @@ class Manifest(OebuildCommand): parser_adder, usage=''' - %(prog)s [-c CREATE] [-r recover] [-m_dir MANIFEST_DIR] + %(prog)s [create CREATE] [download download] [-f MANIFEST_DIR] ''') - parser.add_argument('-c', - '--create', - dest = "is_create", - action = "store_true", - help=''' - create manifest from oebuild workspace src directory - ''') - - parser.add_argument('-r', - '--recover', - dest = "is_recover", - action = "store_true", - help=''' - restore repo version to oebuild workspace src directory from a manifest - ''') - - parser.add_argument('-m_dir', + parser.add_argument('-f', '--manifest_dir', dest='manifest_dir', help=''' @@ -84,20 +69,30 @@ class Manifest(OebuildCommand): return parser def do_run(self, args: argparse.Namespace, unknown = None): + if not self.configure.is_oebuild_dir(): + logger.error('your current directory had not finishd init') + sys.exit(-1) + + if not (unknown and unknown[0] in self.manifest_command): + unknown = ['-h'] + else: + command = unknown[0] + unknown = unknown[1:] + # perpare parse help command if self.pre_parse_help(args, unknown): return args = args.parse_args(unknown) - - if not self.configure.is_oebuild_dir(): - logger.error('your current directory had not finishd init') - sys.exit(-1) - - if args.is_create: - self._create_manifest(args.manifest_dir) - elif args.is_recover: - self._restore_manifest(args.manifest_dir) + manifest_dir = args.manifest_dir if args.manifest_dir else (self.configure.source_yocto_dir() + + '/.oebuild/manifest.yaml') + if command == 'create': + self._create_manifest(manifest_dir) + elif command == 'download': + if not os.path.exists(manifest_dir): + logger.error('The path is invalid, please check the path') + sys.exit(1) + self._restore_manifest(manifest_dir) def _create_manifest(self, manifest_dir): src_list = os.listdir(self.configure.source_dir()) -- Gitee From 5205262525d61711d28d94aa549f7cd6db08af73 Mon Sep 17 00:00:00 2001 From: panwentao Date: Thu, 14 Dec 2023 21:09:55 +0800 Subject: [PATCH 2/3] manifest: Add plugin management command * Add plugin management command Signed-off-by: panwentao --- src/oebuild/app/conf/plugins.yaml | 3 + src/oebuild/app/main.py | 20 +- .../app/plugins/m_plugins/m_plugins.py | 227 ++++++++++++++++++ 3 files changed, 243 insertions(+), 7 deletions(-) create mode 100644 src/oebuild/app/plugins/m_plugins/m_plugins.py diff --git a/src/oebuild/app/conf/plugins.yaml b/src/oebuild/app/conf/plugins.yaml index b44665a..a45093e 100644 --- a/src/oebuild/app/conf/plugins.yaml +++ b/src/oebuild/app/conf/plugins.yaml @@ -23,3 +23,6 @@ plugins: - name: menv class: Menv path: plugins/m_env/m_env.py +- name: mplugins + class: MPlugins + path: plugins/m_plugins/m_plugins.py \ No newline at end of file diff --git a/src/oebuild/app/main.py b/src/oebuild/app/main.py index 9b1c482..f355680 100644 --- a/src/oebuild/app/main.py +++ b/src/oebuild/app/main.py @@ -9,7 +9,7 @@ EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. ''' - +import os import sys import pathlib from collections import OrderedDict @@ -38,22 +38,28 @@ class OebuildApp: self.cmd = None try: plugins_dir = pathlib.Path(self.base_oebuild_dir,'app/conf','plugins.yaml') + append_plugins_dir = pathlib.Path(self.base_oebuild_dir, 'app/conf', 'append_plugins.yaml') self.command_ext = self.get_command_ext(oebuild_util.read_yaml(plugins_dir)['plugins']) + if os.path.exists(append_plugins_dir) and oebuild_util.read_yaml(append_plugins_dir): + self.command_ext = self.get_command_ext(oebuild_util.read_yaml(append_plugins_dir)['plugins'], + self.command_ext) self.command_spec = {} except Exception as e_p: raise e_p @staticmethod - def get_command_ext(plugins:list): + def get_command_ext(plugins: list, command_ext=None): ''' return command information object ''' - command_ext = OrderedDict() + if command_ext is None: + command_ext = OrderedDict() for app in plugins: - command_ext[app['name']] = _ExtCommand( - name=app['name'], - class_name=app['class'], - path=app['path']) + if 'status' not in app or app['status']: + command_ext[app['name']] = _ExtCommand( + name=app['name'], + class_name=app['class'], + path=app['path']) return command_ext diff --git a/src/oebuild/app/plugins/m_plugins/m_plugins.py b/src/oebuild/app/plugins/m_plugins/m_plugins.py new file mode 100644 index 0000000..4743171 --- /dev/null +++ b/src/oebuild/app/plugins/m_plugins/m_plugins.py @@ -0,0 +1,227 @@ +import argparse +import os +import pathlib +import re +import subprocess +import textwrap +import logging + +from oebuild.command import OebuildCommand +import oebuild.util as oebuild_util +from oebuild.configure import Configure + +logger = logging.getLogger() + + +class MPlugins(OebuildCommand): + + def __init__(self): + self.configure = Configure() + self.oebuild_plugins_commands = ['create', 'list', 'change-status', 'remove', 'sync'] + self.oebuild_plugins_yaml_path = pathlib.Path(oebuild_util.get_base_oebuild(), 'app/conf', + 'append_plugins.yaml') + self.oebuild_plugins_repository = pathlib.Path(oebuild_util.get_base_oebuild(), 'app/plugins/appends') + super().__init__( + 'mplugins', + ' Manage Personal Custom Plugins', + description=textwrap.dedent(''' + This is a plugin management function that supports users to customize plugins and add them to the oebuild + for use. Plugins only affect locally installed oebuilds, and supports viewing personal existing plugins and + uninstalling plugins.''' + )) + + def do_add_parser(self, parser_adder) -> argparse.ArgumentParser: + parser = self._parser( + parser_adder, + usage=''' + + %(prog)s [create list remove active][command] + create: -f Create a plugins -n plugins_name + list: View existing plugins + sync: -f -n Synchronize plugin modifications + remove: -n Delete specified plugins + change-status: -n change-status specified plugins +''') + parser.add_argument('-f', '--file', dest='file', + help=''' + this param is python file + ''' + ) + + parser.add_argument('-n', '--plugins_name', dest='plugins_name', + help=''' + this param is plugins name + ''' + ) + + parser.add_argument('-s', '--plugins_status', dest='plugins_status', default=False, + help=''' + this param is plugins status + ''' + ) + return parser + + def do_run(self, args: argparse.Namespace, unknown=None): + if not unknown: + unknown = ['-h'] + elif unknown[0] not in self.oebuild_plugins_commands or (len(set(unknown[1:]).intersection( + {'-f', '-n'})) == 0 and unknown[0] != 'list'): + unknown = ['-h'] + else: + command = unknown[0] + unknown = unknown[1:] + + if self.pre_parse_help(args, unknown): + return + args = args.parse_args(unknown) + + if not os.path.exists(self.oebuild_plugins_yaml_path.absolute()): + if not os.path.exists(os.path.dirname(self.oebuild_plugins_yaml_path.absolute())): + os.makedirs(os.path.dirname(self.oebuild_plugins_yaml_path.absolute())) + os.mknod(self.oebuild_plugins_yaml_path) + plugins_dict = oebuild_util.read_yaml(self.oebuild_plugins_yaml_path) + + if command in ['create', 'sync']: + if not args.plugins_name: + print(f'Please enter the correct command: oebuild mplugins {command} [-f] Create a plugins' + f' -n plugins_name') + return + + if args.plugins_name == 'mplugins': + print(' This command does not allow overwrite ') + return + + if args.file and os.path.exists(args.file): + def_name, class_name = self.query_method(args.file) + if not ('do_run' in def_name and 'do_add_parser' in def_name): + print('do_run or do_add_parser method does not exist') + return + if not os.path.exists(self.oebuild_plugins_repository): + os.mkdir(self.oebuild_plugins_repository) + file_path = pathlib.Path(self.oebuild_plugins_repository, args.file.split('/')[-1]) + file_name = args.file.split('/')[-1] + subprocess.check_output(f'cp {args.file} {file_path}', shell=True) + self.create_or_update_plugins_yaml(args.plugins_name, class_name, file_name, args.plugins_status) + print(f'{command.title()} Plugins successfully \n' + f'{"name".ljust(20)}{"status".ljust(20)}{"path"} \n' + f'{args.plugins_name.ljust(20)}{str(args.plugins_status).ljust(20)}{file_path}') + return + + elif command == 'list': + if plugins_dict and 'plugins' in plugins_dict: + print("""# oebuild plugins:\n#""") + print(f'{"name".ljust(20)}{"status".ljust(20)}{"path"}') + for plugins_data in plugins_dict['plugins']: + print(f'{plugins_data["name"].ljust(20)}{str(plugins_data["status"]).ljust(20)}' + f'{plugins_data["path"]}') + else: + print('No plugins has been created yet') + return + + elif command == 'change-status': + if plugins_dict and 'plugins' in plugins_dict: + for plugins_data in plugins_dict['plugins']: + if plugins_data['name'] == args.plugins_name: + plugins_data['status'] = args.plugins_status + oebuild_util.write_yaml(self.oebuild_plugins_yaml_path, plugins_dict) + print(f'change success') + return + print(f'the plugin {args.plugins_name} does not exist') + else: + print('No plugins has been created yet') + + elif command == 'remove': + if plugins_dict and 'plugins' in plugins_dict: + for plugins_data in plugins_dict['plugins']: + if plugins_data['name'] == args.plugins_name: + plugins_dict['plugins'].remove(plugins_data) + delete_path = pathlib.Path(oebuild_util.get_base_oebuild(), 'app', + plugins_data['path']) + subprocess.check_output(f'rm {delete_path}', shell=True) + oebuild_util.write_yaml(self.oebuild_plugins_yaml_path, plugins_dict) + print(f'delete success') + return + print(f'the plugin {args.plugins_name} does not exist') + else: + print('No plugins has been created yet') + + def create_or_update_plugins_yaml(self, plugins_name, class_name, python_file_name, plugins_status): + """ + + Args: + plugins_name: + class_name: + python_file_name: + plugins_status: + + Returns: + + """ + if not os.path.exists(self.oebuild_plugins_yaml_path.absolute()): + if not os.path.exists(os.path.dirname(self.oebuild_plugins_yaml_path.absolute())): + os.makedirs(os.path.dirname(self.oebuild_plugins_yaml_path.absolute())) + os.mknod(self.oebuild_plugins_yaml_path) + plugins_dict = oebuild_util.read_yaml(self.oebuild_plugins_yaml_path) + if plugins_dict and 'plugins' in plugins_dict: + plugins_list = self.input_or_update_dict(plugins_name, class_name, python_file_name, + plugins_status, plugins_dict['plugins']) + plugins_dict['plugins'] = plugins_list + oebuild_util.write_yaml(self.oebuild_plugins_yaml_path, plugins_dict) + return + + plugins_dict = {'plugins': [{'name': plugins_name, 'class': class_name, + 'path': f'plugins/appends/{python_file_name}', 'status': plugins_status}]} + oebuild_util.write_yaml(self.oebuild_plugins_yaml_path, plugins_dict) + + def input_or_update_dict(self, plugins_name, class_name, python_file_name, plugins_status, plugins_list): + """ + Modify or insert environmental data + Args: + plugins_name: Plugins Name + class_name: python class name + python_file_name: python file name + plugins_status: plugins status + plugins_list: Plugins List + + Returns: + + """ + insert_flag = True + for plugins_data in plugins_list: + if 'name' not in plugins_data: + print('plugins_name not exits') + return + if plugins_data['name'] == plugins_name: + while True: + user_input = input( + "Do you want to overwrite the path of the original plugins configuration(Y/N)") + if user_input.lower() == 'y': + plugins_data['class'] = class_name + if plugins_data['path'] != f'plugins/appends/{python_file_name}': + delete_path = pathlib.Path(oebuild_util.get_base_oebuild(), 'app', + plugins_data['path']) + subprocess.check_output(f'rm {delete_path}', shell=True) + plugins_data['path'] = f'plugins/appends/{python_file_name}' + plugins_data['status'] = plugins_status + break + elif user_input.lower() == 'n': + return [] + insert_flag = False + if insert_flag: + plugins_list.append({'name': plugins_name, 'class': class_name, + 'path': f'plugins/appends/{python_file_name}', 'status': plugins_status}) + return plugins_list + + def query_method(self, file_path): + file = open(file_path, 'r', encoding='UTF-8').readlines() + def_name = "" + class_name = "" + for file_line in file: + if file_line.startswith('def') or file_line.startswith(' def'): + if re.search(r'(?<=def)\s+\w+', file_line): + def_name += re.search(r'(?<=def)\s+\w+', file_line).group() + def_name += "," + if file_line.startswith('class') or file_line.startswith(' class'): + if re.search(r'(?<=class)\s+\w+', file_line) and not class_name: + class_name = re.search(r'(?<=class)\s+\w+', file_line).group().strip() + return def_name, class_name -- Gitee From bbf6a13ebb2e684b328c18f00250e37f1a0082db Mon Sep 17 00:00:00 2001 From: panwentao Date: Wed, 27 Dec 2023 10:12:40 +0800 Subject: [PATCH 3/3] manifest: Modify the command name and add an override to the oebuild plugin judgment * Modify the command name and add an override to the oebuild plugin judgment Signed-off-by: panwentao --- src/oebuild/app/main.py | 2 +- .../app/plugins/m_plugins/m_plugins.py | 53 ++++++++++++------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/oebuild/app/main.py b/src/oebuild/app/main.py index f355680..e6a2ce5 100644 --- a/src/oebuild/app/main.py +++ b/src/oebuild/app/main.py @@ -55,7 +55,7 @@ class OebuildApp: if command_ext is None: command_ext = OrderedDict() for app in plugins: - if 'status' not in app or app['status']: + if 'status' not in app or app['status'] == 'enable': command_ext[app['name']] = _ExtCommand( name=app['name'], class_name=app['class'], diff --git a/src/oebuild/app/plugins/m_plugins/m_plugins.py b/src/oebuild/app/plugins/m_plugins/m_plugins.py index 4743171..012a669 100644 --- a/src/oebuild/app/plugins/m_plugins/m_plugins.py +++ b/src/oebuild/app/plugins/m_plugins/m_plugins.py @@ -9,7 +9,7 @@ import logging from oebuild.command import OebuildCommand import oebuild.util as oebuild_util from oebuild.configure import Configure - +from oebuild.app.main import OebuildApp logger = logging.getLogger() @@ -17,10 +17,12 @@ class MPlugins(OebuildCommand): def __init__(self): self.configure = Configure() - self.oebuild_plugins_commands = ['create', 'list', 'change-status', 'remove', 'sync'] + self.oebuild_plugins_commands = ['install', 'list', 'enable', 'disable', 'remove'] self.oebuild_plugins_yaml_path = pathlib.Path(oebuild_util.get_base_oebuild(), 'app/conf', 'append_plugins.yaml') self.oebuild_plugins_repository = pathlib.Path(oebuild_util.get_base_oebuild(), 'app/plugins/appends') + plugins_dir = pathlib.Path(oebuild_util.get_base_oebuild(), 'app/conf', 'plugins.yaml') + self.command_ext = OebuildApp().get_command_ext(oebuild_util.read_yaml(plugins_dir)['plugins']) super().__init__( 'mplugins', ' Manage Personal Custom Plugins', @@ -36,11 +38,10 @@ class MPlugins(OebuildCommand): usage=''' %(prog)s [create list remove active][command] - create: -f Create a plugins -n plugins_name + install: -f install a plugins -n plugins_name list: View existing plugins - sync: -f -n Synchronize plugin modifications + enable/disable: enable/disable -n enable/disable plugin remove: -n Delete specified plugins - change-status: -n change-status specified plugins ''') parser.add_argument('-f', '--file', dest='file', help=''' @@ -54,11 +55,6 @@ class MPlugins(OebuildCommand): ''' ) - parser.add_argument('-s', '--plugins_status', dest='plugins_status', default=False, - help=''' - this param is plugins status - ''' - ) return parser def do_run(self, args: argparse.Namespace, unknown=None): @@ -81,7 +77,7 @@ class MPlugins(OebuildCommand): os.mknod(self.oebuild_plugins_yaml_path) plugins_dict = oebuild_util.read_yaml(self.oebuild_plugins_yaml_path) - if command in ['create', 'sync']: + if command == 'install': if not args.plugins_name: print(f'Please enter the correct command: oebuild mplugins {command} [-f] Create a plugins' f' -n plugins_name') @@ -91,6 +87,14 @@ class MPlugins(OebuildCommand): print(' This command does not allow overwrite ') return + if args.plugins_name in self.command_ext.keys(): + while True: + user_input = input( + f"Do you want to overwrite the existing plugins ({args.plugins_name}) in oebuild(Y/N)") + if user_input.lower() == 'y': + break + elif user_input.lower() == 'n': + return if args.file and os.path.exists(args.file): def_name, class_name = self.query_method(args.file) if not ('do_run' in def_name and 'do_add_parser' in def_name): @@ -101,12 +105,14 @@ class MPlugins(OebuildCommand): file_path = pathlib.Path(self.oebuild_plugins_repository, args.file.split('/')[-1]) file_name = args.file.split('/')[-1] subprocess.check_output(f'cp {args.file} {file_path}', shell=True) - self.create_or_update_plugins_yaml(args.plugins_name, class_name, file_name, args.plugins_status) + self.create_or_update_plugins_yaml(args.plugins_name, class_name, file_name) print(f'{command.title()} Plugins successfully \n' f'{"name".ljust(20)}{"status".ljust(20)}{"path"} \n' - f'{args.plugins_name.ljust(20)}{str(args.plugins_status).ljust(20)}{file_path}') - return + f'{args.plugins_name.ljust(20)}{"enable".ljust(20)}{file_path}') + else: + print(" Please check the file path ") + return elif command == 'list': if plugins_dict and 'plugins' in plugins_dict: print("""# oebuild plugins:\n#""") @@ -118,11 +124,11 @@ class MPlugins(OebuildCommand): print('No plugins has been created yet') return - elif command == 'change-status': + elif command in ['enable', 'disable']: if plugins_dict and 'plugins' in plugins_dict: for plugins_data in plugins_dict['plugins']: if plugins_data['name'] == args.plugins_name: - plugins_data['status'] = args.plugins_status + plugins_data['status'] = command oebuild_util.write_yaml(self.oebuild_plugins_yaml_path, plugins_dict) print(f'change success') return @@ -145,14 +151,13 @@ class MPlugins(OebuildCommand): else: print('No plugins has been created yet') - def create_or_update_plugins_yaml(self, plugins_name, class_name, python_file_name, plugins_status): + def create_or_update_plugins_yaml(self, plugins_name, class_name, python_file_name): """ Args: plugins_name: class_name: python_file_name: - plugins_status: Returns: @@ -164,13 +169,13 @@ class MPlugins(OebuildCommand): plugins_dict = oebuild_util.read_yaml(self.oebuild_plugins_yaml_path) if plugins_dict and 'plugins' in plugins_dict: plugins_list = self.input_or_update_dict(plugins_name, class_name, python_file_name, - plugins_status, plugins_dict['plugins']) + 'enable', plugins_dict['plugins']) plugins_dict['plugins'] = plugins_list oebuild_util.write_yaml(self.oebuild_plugins_yaml_path, plugins_dict) return plugins_dict = {'plugins': [{'name': plugins_name, 'class': class_name, - 'path': f'plugins/appends/{python_file_name}', 'status': plugins_status}]} + 'path': f'plugins/appends/{python_file_name}', 'status': 'enable'}]} oebuild_util.write_yaml(self.oebuild_plugins_yaml_path, plugins_dict) def input_or_update_dict(self, plugins_name, class_name, python_file_name, plugins_status, plugins_list): @@ -213,6 +218,14 @@ class MPlugins(OebuildCommand): return plugins_list def query_method(self, file_path): + """ + Check if the corresponding method is included in the Python file + Args: + file_path: + + Returns: + + """ file = open(file_path, 'r', encoding='UTF-8').readlines() def_name = "" class_name = "" -- Gitee