Example #1
0
    def _load_tasks(self, herringfile, settings):
        """
        Loads the given herringfile then loads any herringlib files.

        :param herringfile: the herringfile path
        :type herringfile: str
        :return: None
        """
        herringfile_path = Path(herringfile).parent
        library_paths = self._locate_library(herringfile_path, settings)

        self.union_dir = mkdir_p(os.path.join(tempfile.mkdtemp(), 'herringlib'))
        for src_dir in [os.path.abspath(str(path)) for path in reversed(library_paths)]:
            if not settings.json:
                info("src_dir: %s" % src_dir)
            for src_root, dirs, files in os.walk(src_dir):
                files = [f for f in files if not (f[0] == '.' or f.endswith('.pyc'))]
                dirs[:] = [d for d in dirs if not (d[0] == '.' or d == '__pycache__')]
                rel_root = os.path.relpath(src_root, start=src_dir)
                dest_root = os.path.join(self.union_dir, rel_root)
                mkdir_p(dest_root)
                for basename in [name for name in files]:
                    src_name = os.path.join(src_root, basename)
                    dest_name = os.path.join(dest_root, basename)
                    try:
                        shutil.copy(src_name, dest_name)
                    except shutil.Error:
                        pass

        self._load_modules(herringfile, [Path(self.union_dir)])
Example #2
0
    def setup(self):
        """
        Command Line Interface.

        Exits the application in the following conditions:

            * user requested the applications version,
            * user requested help or longhelp,
            * can not find the herringfile.

        :return: None
        """

        parser, settings, argv = HerringSettings().parse()

        Logger.set_verbose(not settings.quiet)
        Logger.set_debug(settings.herring_debug)

        TaskWithArgs.argv = argv
        TaskWithArgs.kwargs = ArgumentHelper.argv_to_dict(argv)

        if settings.longhelp:
            info(sys.modules['herring'].__doc__)
            exit(0)

        if settings.version:
            info("Herring version %s" % self._load_version())
            exit(0)

        return settings
Example #3
0
 def task_lookup(task_name_):
     info("Running: {name} ({description})".format(name=task_name_,
                                                   description=HerringTasks[task_name_]['description']))
     TaskWithArgs.arg_prompt = HerringTasks[task_name_]['arg_prompt']
     try:
         return HerringTasks[task_name_]['task']
     except Exception as ex:
         error(str(ex))
Example #4
0
    def _header(self, message):
        """
        Output table header message followed by a horizontal rule.

        :param message: the table header text
         :type message: str
        :return: None
        """
        (console_width, console_height) = get_terminal_size()
        info(message)
        info("=" * console_width)
Example #5
0
 def _populate_union_dir(self, union_dir, library_paths, output_json):
     for src_dir in [os.path.abspath(str(path)) for path in reversed(library_paths)]:
         if not output_json:
             info("src_dir: %s" % src_dir)
         for src_root, dirs, files in os.walk(src_dir):
             files[:] = filter(lambda file_: not file_.startswith('.') and not file_.endswith('.pyc'), files)
             dirs[:] = filter(lambda dir_: not dir_.startswith('.') and dir_ != '__pycache__', dirs)
             rel_root = os.path.relpath(src_root, start=src_dir)
             dest_root = os.path.join(union_dir, rel_root)
             mkdir_p(dest_root)
             # for basename in [name for name in files]:
             for basename in files:
                 try:
                     shutil.copy(os.path.join(src_root, basename), os.path.join(dest_root, basename))
                 except shutil.Error:
                     pass
Example #6
0
    def _row_list(self, c1_value, c2_value, c1_width, c2_width):
        """
        Output the two columns in the table row.

        :param c1_value: value for first column
         :type c1_value: str
        :param c2_value: value for second column
         :type c2_value: str
        :param c1_width: width (number of characters) for first column
         :type c1_width: int
        :param c2_width: width (number of characters) for second column
         :type c2_width: int
        :return: None
        """
        # values = textwrap.fill(self._unindent(c2_value), c2_width).split("\n")
        values = textwrap.fill(c2_value, c2_width).split("\n")
        info(ROW_FORMAT.format(c1_value, values[0], width1=c1_width, width2=c2_width))
        for line in values[1:]:
            info(ROW_FORMAT.format(' ', line, width1=c1_width, width2=c2_width))
Example #7
0
    def show_depends(self, tasks, herring_tasks, settings):
        """
        Shows the tasks and their dependencies.

        :param tasks: generator for list of task names to show.
        :type tasks: iterator
        :param herring_tasks: all of the herring tasks
        :type herring_tasks: dict
        :param settings: the application settings
        :return: None
        """
        if settings.json:
            info('[')
            for name, description, dependencies, dependent_of, kwargs, arg_prompt, width in tasks:
                info(json.dumps({'name': name,
                                 'description': description,
                                 'dependencies': dependencies,
                                 'dependent_of': dependent_of,
                                 'kwargs': kwargs,
                                 'arg_prompt': arg_prompt}))
            info(']')
        else:
            self._header("Show tasks and their dependencies")
            for name, description, dependencies, dependent_of, kwargs, arg_prompt, width in tasks:
                self._row(name=name,
                          description=description.strip().splitlines()[0],
                          dependencies=dependencies,
                          dependent_of=dependent_of,
                          max_name_length=width)
            self._footer(herring_tasks)
Example #8
0
    def run_tasks(task_list):
        """
        Runs the tasks given on the command line.

        :param task_list: a task name or a list of task names to run
        :type task_list: str|list
        :return: None
        """
        if not is_sequence(task_list):
            task_list = [task_list]

        verified_task_list = HerringApp._verified_tasks(task_list)
        debug("task_list: {tasks}".format(tasks=task_list))
        debug("verified_task_list: {tasks}".format(tasks=verified_task_list))
        if not verified_task_list:
            raise ValueError('No tasks given.  Run "herring -T" to see available tasks.')
        TaskWithArgs.argv = list([arg for arg in task_list if arg not in verified_task_list])

        for task_name in HerringApp._resolve_dependencies(verified_task_list, HerringTasks):
            info("Running: {name} ({description})".format(name=task_name,
                                                          description=HerringTasks[task_name]['description']))
            TaskWithArgs.arg_prompt = HerringTasks[task_name]['arg_prompt']
            HerringTasks[task_name]['task']()
Example #9
0
 def _footer(self, tasks):
     tasks_help = []
     for task_name in tasks:
         task = tasks[task_name]
         if task['help']:
             tasks_help.append("{name}:  {help}".format(name=task_name, help=task['help']))
     if tasks_help:
         info('')
         info('Notes:')
         info("\n".join(tasks_help))
Example #10
0
    def show_task_usages(self, tasks, herring_tasks, settings):
        """
        Shows the tasks.

        :param tasks: generator for list of task names to show.
        :type tasks: iterator
        :param herring_tasks: all of the herring tasks
        :type herring_tasks: dict
        :param settings: the application settings
        :return: None
        """
        if settings.json:
            info('[')
            for name, description, dependencies, dependent_of, kwargs, arg_prompt, width in tasks:
                info(json.dumps({'name': name,
                                 'description': description,
                                 'dependencies': dependencies,
                                 'dependent_of': dependent_of,
                                 'kwargs': kwargs,
                                 'arg_prompt': arg_prompt}))
            info(']')
        else:
            self._header("Show task usages")
            for name, description, dependencies, dependent_of, kwargs, arg_prompt, width in tasks:
                info("#" * 40)
                info("# herring %s" % name)
                info(textwrap.dedent(description).replace("\n\n", "\n").strip())
                info('')
            self._footer(herring_tasks)
Example #11
0
 def show_environment(self):
     """Show the runtime environment for herring"""
     info('os.environ: {data}'.format(data=pformat(os.environ)))
     info('sys.argv: {data}'.format(data=pformat(sys.argv)))
     info('sys.executable: {data}'.format(data=pformat(sys.executable)))
     info('sys.path: {data}'.format(data=pformat(sys.path)))
     info('sys.platform: {data}'.format(data=pformat(sys.platform)))
     info('sys.version_info: {data}'.format(data=pformat(sys.version_info)))
Example #12
0
    def execute(self, cli, settings):
        """
        Execute the tasks specified in the _settings object.

        Currently:

            * settings.list_task asserted shows the available tasks.
            * settings.list_dependencies asserted shows the available tasks
              and their dependencies.
            * settings.list_all_tasks asserted modifies the listing to include
              tasks that do not have a docstring.
            * if both settings.list_task and settings.list_dependencies are
              deasserted, then run the tasks from settings.tasks

        :param cli: the command line interface instance
        :type cli: herring.HerringCLI
        :param settings: the application settings
        :return: None
        """
        try:
            HerringFile.settings = settings
            herring_file = self._find_herring_file(settings.herringfile)
            HerringFile.directory = str(os.path.realpath(os.path.dirname(herring_file)))
            sys.path.insert(1, HerringFile.directory)

            herringfile_is_nonempty = self._is_herring_file_nonempty(herring_file)

            global debug_mode
            global verbose_mode
            debug_mode = settings.debug
            verbose_mode = not settings.quiet

            # the tasks are always ran with the current working directory
            # set to the directory that contains the herringfile
            os.chdir(HerringFile.directory)

            if not settings.json:
                info("Using: %s" % herring_file)

            if not settings.json and settings.environment:
                cli.show_environment()

            with HerringLoader(settings) as loader:
                loader.load_tasks(herring_file)  # populates HerringTasks

                task_list = list(self._get_tasks_list(HerringTasks,
                                                      settings.list_all_tasks,
                                                      herringfile_is_nonempty,
                                                      settings.tasks))

                if settings.list_tasks:
                    cli.show_tasks(self._get_tasks(task_list), HerringTasks, settings)
                elif settings.list_task_usages:
                    cli.show_task_usages(self._get_tasks(task_list), HerringTasks, settings)
                elif settings.list_dependencies:
                    cli.show_depends(self._get_tasks(task_list), HerringTasks, settings)
                else:
                    try:
                        HerringRunner.run_tasks(settings.tasks)
                    except Exception as ex:
                        fatal(ex)
        except ValueError as ex:
            fatal(ex)
Example #13
0
    def execute(self, cli, settings):
        """
        Execute the tasks specified in the _settings object.

        Currently:

            * settings.list_task asserted shows the available tasks.
            * settings.list_dependencies asserted shows the available tasks
              and their dependencies.
            * settings.list_all_tasks asserted modifies the listing to include
              tasks that do not have a docstring.
            * if both settings.list_task and settings.list_dependencies are
              deasserted, then run the tasks from settings.tasks

        :param cli: the command line interface instance
        :type cli: herring.HerringCLI
        :param settings: the application settings
        :return: None
        """
        try:
            HerringFile.settings = settings
            herring_file = self._find_herring_file(settings.herringfile)
            HerringFile.directory = str(os.path.realpath(os.path.dirname(herring_file)))
            sys.path.insert(1, HerringFile.directory)

            configured_herringfile = self._configured_herring_file(herring_file)

            global debug_mode
            global verbose_mode
            debug_mode = settings.debug
            verbose_mode = not settings.quiet

            # the tasks are always ran with the current working directory
            # set to the directory that contains the herringfile
            os.chdir(HerringFile.directory)

            if not settings.json:
                info("Using: %s" % herring_file)

            if not settings.json and settings.environment:
                cli.show_environment()

            self._load_tasks(herring_file, settings)
            task_list = list(self._get_tasks_list(HerringTasks, settings.list_all_tasks, configured_herringfile))

            # if we are doing a show (-T, -D, -U) and we give another parameter, then only show
            # tasks that contain the parameter.  Example:  "-T doc" will show only the "doc" tasks.
            if settings.tasks:
                abridged_task_list = []
                for task_ in settings.tasks:
                    abridged_task_list.extend(list([t for t in task_list if task_ in t['name']]))
                task_list = abridged_task_list

            if settings.list_tasks:
                cli.show_tasks(self._get_tasks(task_list), HerringTasks, settings)
            elif settings.list_task_usages:
                cli.show_task_usages(self._get_tasks(task_list), HerringTasks, settings)
            elif settings.list_dependencies:
                cli.show_depends(self._get_tasks(task_list), HerringTasks, settings)
            else:
                try:
                    HerringApp.run_tasks(settings.tasks)
                except Exception as ex:
                    fatal(ex)
        except ValueError as ex:
            fatal(ex)
        finally:
            if self.union_dir is not None and not settings.leave_union_dir:
                # noinspection PyTypeChecker
                shutil.rmtree(os.path.dirname(self.union_dir))