diff --git a/src/oebuild/app/conf/plugins.yaml b/src/oebuild/app/conf/plugins.yaml index b44665a42d9c71cbcaf34c7e0379b2273c825fea..a45093e1fba6468c30623f1185dfa658bd3b6850 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 9b1c4823f93686ca8c7c1c093d0cce5c8c5525ea..f355680d90f9c7036f4f3c141d514dc888192b2b 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 0000000000000000000000000000000000000000..4743171ebc3cdcb457c0bbeada462af5707de1d8 --- /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 diff --git a/src/oebuild/app/plugins/manifest/manifest.py b/src/oebuild/app/plugins/manifest/manifest.py index 1eaca5e2604def23e7009eb995bb413ff83d5ac9..745fce8f85fabba3d6aa465f94d41a416e999d1c 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())