def build_class_database(include_dirs, input_dirs):
    """
    Create the class database.

    Returns a dict() of DatabaseItem objects. The key is the class name e.g., Diffusion.

    Inputs:
        include_dirs[str,list]: A space separated str or a list of include directories.
        input_dirs[str,list]: A space separated str or a list of input file directories.
    """

    # Build the lists from strings
    if isinstance(include_dirs, str):
        include_dirs = [mooseutils.eval_path(x) for x in include_dirs.split()]
    if isinstance(input_dirs, str):
        input_dirs = [mooseutils.eval_path(x) for x in input_dirs.split()]

    # Locate filenames
    headers = _locate_filenames(include_dirs, '.h')
    inputs = _locate_filenames(input_dirs, '.i')

    # Create the database
    objects = dict()
    _process(objects, headers, DEFINITION_RE, _match_definition)
    _process(objects, headers, CHILD_RE, _match_child)
    _process(objects, inputs, INPUT_RE, _match_input)
    return objects
def build_class_database(include_dirs=None, input_dirs=None):
    """
    Create the class database.

    Returns a dict() of DatabaseItem objects. The key is the class name e.g., Diffusion.

    Inputs:
        include_dirs[list]: A space separated str or a list of include directories.
        input_dirs[list]: A space separated str or a list of input file directories.
    """

    # Handle environment variables
    if include_dirs:
        include_dirs = [mooseutils.eval_path(x) for x in include_dirs]
    else:
        include_dirs = [MooseDocs.ROOT_DIR]

    if input_dirs:
        input_dirs = [mooseutils.eval_path(x) for x in input_dirs]
    else:
        input_dirs = [MooseDocs.ROOT_DIR]

    # Locate filenames
    headers = _locate_filenames(include_dirs, '.h')
    inputs = _locate_filenames(input_dirs, '.i')

    # Create the database
    objects = dict()
    _process(objects, headers, DEFINITION_RE, _match_definition)
    _process(objects, headers, CHILD_RE, _match_child)
    _process(objects, inputs, INPUT_RE, _match_input)
    return objects
    def execute(self, **kwargs):
        """Perform app syntax checking"""

        # Check that the supplied content dir exists
        content_dir = mooseutils.eval_path(self.content_directory)
        if not os.path.isdir(content_dir):
            content_dir = os.path.join(self.working_dir, content_dir)
        if not os.path.isdir(content_dir):
            raise NotADirectoryError("'content_directory' input is not a directory: {}".format(content_dir))

        # Populate the available list of files
        file_cache = mooseutils.git_ls_files(content_dir)

        # Check that the supplied exe dir exists
        exe_dir = mooseutils.eval_path(self.exe_directory)
        if not os.path.isdir(exe_dir):
            exe_dir = os.path.join(self.working_dir, exe_dir)
        if not os.path.isdir(exe_dir):
            raise NotADirectoryError("'exe_directory' input is not a directory: {}".format(exe_dir))

        # Locate the executable
        exe = mooseutils.find_moose_executable(exe_dir, name=self.exe_name, show_error=False)
        if exe is None:
            raise OSError("An executable was not found in '{}' with a name '{}'.".format(exe_dir, self.exe_name))

        # Determine the application type (e.g., MooseTestApp)
        if self.app_types is None:
            out = subprocess.check_output([exe, '--type'], encoding='utf-8')
            match = re.search(r'^MooseApp Type:\s+(?P<type>.*?)$', out, flags=re.MULTILINE)
            if match:
                self.app_types = [match.group("type").replace('TestApp', 'App')]

        # Build syntax tree if not provided
        if self.app_syntax is None:

            # Get the removed/alias information
            remove = self._loadYamlFiles(self.remove)
            alias = self._loadYamlFiles(self.alias)
            unregister = self._loadYamlFiles(self.unregister)

            # Build the complete syntax tree
            self.app_syntax = moosesyntax.get_moose_syntax_tree(exe, remove=remove,
                                                                alias=alias, unregister=unregister)

        # Perform the checks
        kwargs.setdefault('syntax_prefix', mooseutils.eval_path(self.syntax_prefix))
        kwargs.setdefault('object_prefix', mooseutils.eval_path(self.object_prefix))
        kwargs.setdefault('allow_test_objects', self.allow_test_objects)
        logger = check_syntax(self.app_syntax, self.app_types, file_cache, **kwargs)

        return logger
Exemple #4
0
    def __initApplicationSyntax(self):
        """Initialize the application syntax."""

        start = time.time()
        LOG.info("Reading MOOSE application syntax...")
        exe = mooseutils.eval_path(self['executable'])
        exe = mooseutils.find_moose_executable(exe, show_error=False)

        if exe is None:
            LOG.error("Failed to locate a valid executable in %s.", self['executable'])
        else:
            try:
                self._app_syntax = app_syntax(exe,
                                              alias=self['alias'],
                                              remove=self['remove'],
                                              hide=self['hide'],
                                              allow_test_objects=self['allow-test-objects'])

                out = mooseutils.runExe(exe, ['--type'])
                match = re.search(r'^MooseApp Type:\s+(?P<type>.*?)$', out, flags=re.MULTILINE)
                if match:
                    self._app_type = match.group("type")
                else:
                    msg = "Failed to determine application type by running the following:\n"
                    msg += "    {} --type".format(exe)
                    LOG.error(msg)

            except Exception as e: #pylint: disable=broad-except
                msg = "Failed to load application executable from '%s', " \
                      "application syntax is being disabled:\n%s"
                self.setActive(False)
                LOG.error(msg, self.get('executable'), e.message)
        LOG.info("MOOSE application syntax complete [%s sec.]", time.time() - start)
Exemple #5
0
    def __init__(self, *args, **kwargs):
        command.CommandExtension.__init__(self, *args, **kwargs)

        self._app_type = None
        self._app_syntax = None
        if not self['disable'] and self['executable'] is not None:
            LOG.info("Reading MOOSE application syntax.")
            exe = mooseutils.eval_path(self['executable'])
            exe = mooseutils.find_moose_executable(exe, show_error=False)

            if exe is None:
                LOG.error("Failed to locate a valid executable in %s.",
                          self['executable'])
            else:
                try:
                    self._app_syntax = app_syntax(
                        exe,
                        alias=self['alias'],
                        remove=self['remove'],
                        hide=self['hide'],
                        allow_test_objects=self['allow-test-objects'])

                    out = mooseutils.runExe(exe, ['--type'])
                    match = re.search(r'^MooseApp Type:\s+(?P<type>.*?)$',
                                      out,
                                      flags=re.MULTILINE)
                    if match:
                        self._app_type = match.group("type")
                    else:
                        msg = "Failed to determine application type by running the following:\n"
                        msg += "    {} --type".format(exe)
                        LOG.error(msg)

                except Exception as e:  #pylint: disable=broad-except
                    msg = "Failed to load application executable from '%s', " \
                          "application syntax is being disabled:\n%s"
                    LOG.error(msg, self['executable'], e.message)

        LOG.info("Building MOOSE class database.")
        self._database = common.build_class_database(self['includes'],
                                                     self['inputs'])

        # Cache the syntax entries, search the tree is very slow
        if self._app_syntax:
            self._cache = dict()
            self._object_cache = dict()
            self._syntax_cache = dict()
            for node in anytree.PreOrderIter(self._app_syntax):
                if not node.removed:
                    self._cache[node.fullpath] = node
                    if node.alias:
                        self._cache[node.alias] = node
                    if isinstance(node, syntax.ObjectNode):
                        self._object_cache[node.fullpath] = node
                        if node.alias:
                            self._object_cache[node.alias] = node
                    elif isinstance(node, syntax.SyntaxNode):
                        self._syntax_cache[node.fullpath] = node
                        if node.alias:
                            self._syntax_cache[node.alias] = node
Exemple #6
0
    def execute(self, **kwargs):
        """
        Computes the percent complete, number missing items, and the pass/fail status
        """

        # Extract configuration parameters
        specs = self.specs or 'tests'

        # Get complete directory paths
        root_dir = mooseutils.git_root_dir()
        directories = [mooseutils.eval_path(d) for d in (self.directories or [root_dir])]
        for i, d in enumerate(directories):
            if not os.path.isdir(d):
                directories[i] = os.path.join(root_dir, d)
            if not os.path.isdir(directories[i]):
                raise NotADirectoryError("Supplied directory does not exist: {}".format(d))

        # Build Requirement objects and remove directory based dict
        req_dict = get_requirements_from_tests(directories, specs.split(), self.include_non_testable)
        requirements = []
        for values in req_dict.values():
            requirements += values

        # Populate the lists of tests for SQARequirementDiffReport
        self.test_names = set()
        for req in requirements:
            self.test_names.add((req.filename, req.name, req.line))

        # Get list of files to search
        if self.working_dirs is None: self.working_dirs = [mooseutils.git_root_dir()]
        file_list = SQAReport._getFiles(self.working_dirs)

        # Check the requirements
        logger = check_requirements(requirements, color_text=self.color_text, file_list=file_list, **kwargs)
        return logger
Exemple #7
0
    def __init__(self, *args, **kwargs):
        command.CommandExtension.__init__(self, *args, **kwargs)

        # Build requirements sets
        self.__requirements = dict()
        self.__dependencies = dict()
        for index, (category,
                    info) in enumerate(self.get('categories').iteritems(), 1):  #pylint: disable=no-member
            specs = info.get('specs', ['tests'])
            directories = []
            for d in info.get('directories'):
                path = mooseutils.eval_path(d)
                if not os.path.isdir(path):
                    path = os.path.join(MooseDocs.ROOT_DIR, d)
                if not os.path.isdir(path):
                    msg = "Input directory does not exist: %s"
                    LOG.error(msg, path)

                directories.append(path)

            # Create requirement database
            self.__requirements[category] = common.get_requirements(
                directories, specs, 'F', index)

            # Create dependency database
            self.__dependencies[category] = info.get('dependencies', [])

        # Storage for requirement matrix counting (see SQARequirementMatricCommand)
        self.__counts = collections.defaultdict(int)
Exemple #8
0
    def __initApplicationSyntax(self):
        """Initialize the application syntax."""

        start = time.time()
        LOG.info("Reading MOOSE application syntax...")
        exe = mooseutils.eval_path(self['executable'])
        exe = mooseutils.find_moose_executable(exe, name=self['app_name'], show_error=False)

        if exe is None:
            LOG.error("Failed to locate a valid executable in %s.", self['executable'])
        else:
            try:
                self._app_syntax = app_syntax(exe,
                                              alias=self['alias'],
                                              remove=self['remove'],
                                              hide=self['hide'],
                                              allow_test_objects=self['allow-test-objects'])

                out = mooseutils.runExe(exe, ['--type'])
                match = re.search(r'^MooseApp Type:\s+(?P<type>.*?)$', out, flags=re.MULTILINE)
                if match:
                    self._app_type = match.group("type")
                else:
                    msg = "Failed to determine application type by running the following:\n"
                    msg += "    {} --type".format(exe)
                    LOG.error(msg)

            except Exception as e:
                msg = "Failed to load application executable from '%s', " \
                      "application syntax is being disabled:\n%s"
                self.setActive(False)
                LOG.error(msg, exe, e)
        LOG.info("MOOSE application syntax complete [%s sec.]", time.time() - start)
Exemple #9
0
def doc_tree(items):
    """
    Create a tree of files for processing.

    Inputs:
        inputs: [list[dict(),...] A list of dict items, each dict entry must contain the 'root_dir'
                and 'content' fields that are passed to the doc_import function.
    """
    # Error checking
    if not isinstance(items, list) or any(not isinstance(x, dict)
                                          for x in items):
        LOG.error(
            'The supplied items must be a list of dict items, each with a "root_dir" and '
            'optionally a "content" entry.')
        return None

    # Define a dict for storing nodes by path
    nodes = dict()

    # Create the root node
    nodes[()] = page.DirectoryNode(source='')

    # Create the file tree
    for value in items:

        if 'root_dir' not in value:
            LOG.error(
                'The supplied items must be a list of dict items, each with a "root_dir" and '
                'optionally a "content" entry.')

        root = mooseutils.eval_path(value['root_dir'])
        if not os.path.isabs(root):
            root = os.path.join(MooseDocs.ROOT_DIR, root)

        # Update the project files
        MooseDocs.PROJECT_FILES.update(
            mooseutils.git_ls_files(mooseutils.git_root_dir(root)))

        files = doc_import(root, content=value.get('content', None))
        for filename in files:
            key = tuple(filename.replace(root, '').strip('/').split('/'))

            # Create directory nodes if they don't exist
            for i in range(1, len(key)):
                dir_key = key[:i]
                if dir_key not in nodes:
                    nodes[dir_key] = page.DirectoryNode(nodes[key[:i - 1]],
                                                        name=key[i - 1],
                                                        source=os.path.join(
                                                            root, *dir_key))

            # Create the file node, if it doesn't already exist. This enforces that the first
            # item in the supplied content lists is the page that is rendered.
            if key not in nodes:
                nodes[key] = create_file_node(nodes[key[:-1]], key[-1],
                                              filename)

    return nodes[()]
Exemple #10
0
 def _getFiles(locations):
     """Get complete list of files for the given *locations*."""
     file_list = list()
     for working_dir in locations:
         path = mooseutils.eval_path(working_dir)
         if mooseutils.git_is_repo(path):
             file_list += mooseutils.git_ls_files(path)
         else:
             file_list += glob.glob(os.path.join(path, '**', '*.*'),
                                    recursive=True)
     return file_list
Exemple #11
0
    def __init__(self, **kwargs):
        self._documents = dict()
        kwargs.setdefault('required_documents', INL_DOCUMENTS)
        for name in kwargs.get('required_documents'):
            doc = kwargs.pop(name, None)
            if doc is not None:
                doc = mooseutils.eval_path(doc)
            self._documents[name] = doc

        super().__init__(**kwargs)
        if self.working_dirs is None:
            self.working_dirs = [mooseutils.git_root_dir()]
Exemple #12
0
    def execute(self, **kwargs):
        """Determine the status"""
        file_list = list()
        for working_dir in self.working_dirs:
            path = mooseutils.eval_path(working_dir)
            if mooseutils.is_git_repo(path):
                file_list += mooseutils.git_ls_files(path)
            else:
                file_list += glob.glob(os.path.join(path, '**', '*.*'),
                                       recursive=True)

        logger = check_documents(self.documents, file_list, **kwargs)
        return logger
Exemple #13
0
    def __initApplicationSyntax(self):
        """Initialize the application syntax."""

        start = time.time()
        LOG.info("Reading MOOSE application syntax...")
        exe = mooseutils.eval_path(self['executable'])
        exe = mooseutils.find_moose_executable(exe,
                                               name=self['app_name'],
                                               show_error=False)
        self._app_exe = exe

        if exe is None:
            LOG.error("Failed to locate a valid executable in %s.",
                      self['executable'])
        else:
            try:
                self._app_syntax = moosesyntax.get_moose_syntax_tree(
                    exe,
                    remove=self['remove'],
                    alias=self['alias'],
                    unregister=self['unregister'])

                out = mooseutils.runExe(exe, ['--type'])
                match = re.search(r'^MooseApp Type:\s+(?P<type>.*?)$',
                                  out,
                                  flags=re.MULTILINE)
                if match:
                    self._app_type = match.group("type")
                else:
                    msg = "Failed to determine application type by running the following:\n"
                    msg += "    {} --type".format(exe)
                    LOG.error(msg)

            except Exception as e:
                msg = "Failed to load application executable from '{}' with the following error; " \
                      "application syntax is being disabled.\n".format(exe)
                msg += '\n{}\n'.format(
                    mooseutils.colorText(traceback.format_exc(), 'GREY'))
                msg += "This typically indicates that the application is not producing JSON output " \
                       "correctly, try running the following:\n" \
                       "    {} --json --allow-test-objects\n".format(exe)
                self.setActive(False)
                LOG.error(msg)

        # Enable test objects by removing the test flag (i.e., don't consider them test objects)
        if self['allow-test-objects'] and (self._app_syntax is not None):
            for node in moosetree.iterate(self._app_syntax):
                node.test = False

        LOG.info("MOOSE application syntax complete [%s sec.]",
                 time.time() - start)
Exemple #14
0
def main(options):
    """
    Main function for the build command.

    Inputs:
        options[argparse options]: Complete options from argparse, see MooseDocs/main.py
    """

    # Make sure "large_media" exists in MOOSE
    _init_large_media()

    # Create translator
    translator, _ = common.load_config(options.config)
    if options.destination:
        translator.update(destination=mooseutils.eval_path(options.destination))
    translator.init()

    # Replace "home" with local server
    if options.serve:
        home = 'http://127.0.0.1:{}'.format(options.port)
        translator.renderer.update(home=home)
    elif options.home:
        translator.renderer.update(home=options.home)

    # Dump page tree
    if options.dump:
        print translator.root

    # Clean when --files is NOT used or when --clean is used with --files.
    if ((options.files == []) or (options.files != [] and options.clean)) \
       and os.path.exists(translator['destination']):
        log = logging.getLogger('MooseDocs.build')
        log.info("Cleaning destination %s", translator['destination'])
        shutil.rmtree(translator['destination'])

    # Perform check
    if options.check:
        check(translator)

    # Perform build
    if options.files:
        for filename in options.files:
            node = translator.root.findall(filename)[0]
            node.build()
    else:
        translator.execute(options.num_threads)

    if options.serve:
        watcher = MooseDocsWatcher(translator, options)
        server = livereload.Server(watcher=watcher)
        server.serve(root=translator['destination'], host=options.host, port=options.port)
Exemple #15
0
def doc_tree(items):
    """
    Create a tree of files for processing.

    Inputs:
        inputs: [list[dict(),...] A list of dict items, each dict entry must contain the 'root_dir'
                and 'content' fields that are passed to the doc_import function.
    """
    # Error checking
    if not isinstance(items, list) or any(not isinstance(x, dict) for x in items):
        LOG.error('The supplied items must be a list of dict items, each with a "root_dir" and '
                  'optionally a "content" entry.')
        return None

    # Define a dict for storing nodes by path
    nodes = dict()

    # Create the root node
    nodes[()] = page.DirectoryNode(source='')

    # Create the file tree
    for value in items:

        if 'root_dir' not in value:
            LOG.error('The supplied items must be a list of dict items, each with a "root_dir" and '
                      'optionally a "content" entry.')

        root = mooseutils.eval_path(value['root_dir'])
        if not os.path.isabs(root):
            root = os.path.join(MooseDocs.ROOT_DIR, root)

        # Update the project files
        MooseDocs.PROJECT_FILES.update(mooseutils.git_ls_files(mooseutils.git_root_dir(root)))

        files = doc_import(root, content=value.get('content', None))
        for filename in files:
            key = tuple(filename.replace(root, '').strip('/').split('/'))

            # Create directory nodes if they don't exist
            for i in range(1, len(key)):
                dir_key = key[:i]
                if dir_key not in nodes:
                    nodes[dir_key] = page.DirectoryNode(nodes[key[:i-1]],
                                                        name=key[i-1],
                                                        source=os.path.join(root, *dir_key))

            # Create the file node
            nodes[key] = create_file_node(nodes[key[:-1]], key[-1], filename)

    return nodes[()]
Exemple #16
0
    def _loadYamlFiles(self, filenames):
        """Load the removed/alias yml files"""
        content = dict()
        if filenames is not None:
            for fname in filenames:
                yml_file = mooseutils.eval_path(fname)
                if not os.path.isdir(yml_file):
                    yml_file = os.path.join(self.working_dir, yml_file)

                if not os.path.isfile(yml_file):
                    raise NotADirectoryError("YAML file is not a directory: {}".format(fname))

                content.update({fname:yaml_load(yml_file)})
        return content
Exemple #17
0
    def __init__(self, *args, **kwargs):
        command.CommandExtension.__init__(self, *args, **kwargs)

        self._app_type = None
        self._app_syntax = None
        if not self['disable'] and self['executable'] is not None:
            LOG.info("Reading MOOSE application syntax.")
            exe = mooseutils.eval_path(self['executable'])
            exe = mooseutils.find_moose_executable(exe, show_error=False)

            if exe is None:
                LOG.error("Failed to locate a valid executable in %s.", self['executable'])
            else:
                try:
                    self._app_syntax = app_syntax(exe,
                                                  alias=self['alias'],
                                                  remove=self['remove'],
                                                  hide=self['hide'],
                                                  allow_test_objects=self['allow-test-objects'])

                    self._app_type = mooseutils.runExe(exe, ['--type']).strip(' \n')

                except Exception as e: #pylint: disable=broad-except
                    msg = "Failed to load application executable from '%s', " \
                          "application syntax is being disabled:\n%s"
                    LOG.error(msg, self['executable'], e.message)

        LOG.info("Building MOOSE class database.")
        self._database = common.build_class_database(self['includes'], self['inputs'])

        # Cache the syntax entries, search the tree is very slow
        if self._app_syntax:
            self._cache = dict()
            self._object_cache = dict()
            self._syntax_cache = dict()
            for node in anytree.PreOrderIter(self._app_syntax):
                if not node.removed:
                    self._cache[node.fullpath] = node
                    if node.alias:
                        self._cache[node.alias] = node
                    if isinstance(node, syntax.ObjectNode):
                        self._object_cache[node.fullpath] = node
                        if node.alias:
                            self._object_cache[node.alias] = node
                    elif isinstance(node, syntax.SyntaxNode):
                        self._syntax_cache[node.fullpath] = node
                        if node.alias:
                            self._syntax_cache[node.alias] = node
Exemple #18
0
    def __init__(self, *args, **kwargs):
        command.CommandExtension.__init__(self, *args, **kwargs)

        # Always include MOOSE and libMesh
        self['repos'].update(dict(moose="https://github.com/idaholab/moose",
                                  libmesh="https://github.com/libMesh/libmesh"))

        # Build requirements sets
        repos = self.get('repos')
        self.__has_civet = False
        self.__requirements = dict()
        self.__dependencies = dict()
        self.__remotes = dict()
        for index, (category, info) in enumerate(self.get('categories').items(), 1):
            specs = info.get('specs', ['tests'])
            repo = info.get('repo', 'default')
            directories = []

            for d in info.get('directories'):
                path = mooseutils.eval_path(d)
                if not os.path.isdir(path):
                    path = os.path.join(MooseDocs.ROOT_DIR, d)
                if not os.path.isdir(path):
                    msg = "Input directory does not exist: %s"
                    LOG.error(msg, path)

                directories.append(path)

            # Create requirement database
            self.__requirements[category] = common.get_requirements(directories, specs, 'F', index)

            # Create dependency database
            self.__dependencies[category] = info.get('dependencies', [])

            # Create remote repository database
            self.__remotes[category] = repos.get(repo, None)

        # Storage for requirement matrix counting (see SQARequirementMatricCommand)
        self.__counts = collections.defaultdict(int)

        # Deprecate 'url' and 'repo' config options
        url = self.get('url')
        repo = self.get('repo')
        if repo is not None:
            msg = "The 'url' and 'repo' config options for MooseDocs.extensions.sqa are deprecated,"\
                 " add the 'repos' option with a 'default' entry instead."
            LOG.warning(msg)
            self['repos'].update(dict(default="{}/{}".format(url, repo)))
Exemple #19
0
    def execute(self, **kwargs):
        """
        Computes the percent complete, number missing items, and the pass/fail status
        """

        # Extract configuration parameters
        working_dir = self.working_dir or mooseutils.git_root_dir()
        local_dirs = self.directories
        specs = self.specs or 'tests'

        # Get complete directory paths
        if local_dirs:
            directories = list()
            for local_dir in local_dirs:
                d = mooseutils.eval_path(local_dir)
                if not os.path.isdir(d):
                    d = os.path.join(working_dir, d)
                directories.append(d)
        else:
            directories = [working_dir]

        # Check that directories exist
        for d in directories:
            if not os.path.isdir(d):
                raise NotADirectoryError(
                    "Supplied directory does not exist: {}".format(d))

        # Build Requirement objects and remove directory based dict
        req_dict = get_requirements(directories, specs.split())
        requirements = []
        for values in req_dict.values():
            requirements += values

        # Populate the lists of tests for SQARequirementDiffReport
        self.test_names = set()
        for req in requirements:
            self.test_names.add((req.filename, req.name, req.line))

        # Check the requirements
        logger = check_requirements(requirements,
                                    color_text=self.color_text,
                                    **kwargs)

        return logger
Exemple #20
0
    def __init__(self, *args, **kwargs):
        command.CommandExtension.__init__(self, *args, **kwargs)

        self._app_type = None
        self._app_syntax = None
        if not self['disable'] and self['executable'] is not None:
            LOG.info("Reading MOOSE application syntax.")
            exe = mooseutils.eval_path(self['executable'])
            exe = mooseutils.find_moose_executable(exe, show_error=False)

            if exe is None:
                LOG.error("Failed to locate a valid executable in %s.", self['executable'])
            else:
                try:
                    self._app_syntax = app_syntax(exe,
                                                  alias=self['alias'],
                                                  remove=self['remove'],
                                                  hide=self['hide'],
                                                  allow_test_objects=self['allow-test-objects'])

                    self._app_type = mooseutils.runExe(exe, ['--type']).strip(' \n')

                except Exception as e: #pylint: disable=broad-except
                    msg = "Failed to load application executable from '%s', " \
                          "application syntax is being disabled:\n%s"
                    LOG.error(msg, self['executable'], e.message)

        LOG.info("Building MOOSE class database.")
        self._database = common.build_class_database(self['includes'], self['inputs'])

        # Cache the syntax entries, search the tree is very slow
        if self._app_syntax:
            self._cache = dict()
            self._object_cache = dict()
            self._syntax_cache = dict()
            for node in anytree.PreOrderIter(self._app_syntax):
                if not node.removed:
                    self._cache[node.fullpath] = node
                    if isinstance(node, syntax.ObjectNode):
                        self._object_cache[node.fullpath] = node
                    elif isinstance(node, syntax.SyntaxNode):
                        self._syntax_cache[node.fullpath] = node
Exemple #21
0
def get_files(items, in_ext, git_ls_files=True):
    """
    Get a list of files to consider given the content configuration.
    """

    filenames = []
    for value in items:

        if 'root_dir' not in value:
            LOG.error('The supplied items must be a list of dict items, each with a "root_dir" and '
                      'optionally a "content" entry.')

        root = mooseutils.eval_path(value['root_dir'])
        if not os.path.isabs(root):
            root = os.path.join(MooseDocs.ROOT_DIR, root)

        for fname in _doc_import(root, content=value.get('content', None)):
            filenames.append((root, fname))

    return filenames
Exemple #22
0
def get_files(items, in_ext, git_ls_files=True):
    """
    Get a list of files to consider given the content configuration.
    """

    filenames = []
    for value in items:

        if 'root_dir' not in value:
            LOG.error('The supplied items must be a list of dict items, each with a "root_dir" and '
                      'optionally a "content" entry.')

        root = mooseutils.eval_path(value['root_dir'])
        if not os.path.isabs(root):
            root = os.path.join(MooseDocs.ROOT_DIR, root)

        for fname in _doc_import(root, content=value.get('content', None)):
            filenames.append((root, fname))

    return filenames
Exemple #23
0
def main(options):
    """
    Main function for the build command.

    Inputs:
        options[argparse options]: Complete options from argparse, see MooseDocs/main.py
    """
    t = time.time()

    # Infinite nested dict
    tree = lambda: collections.defaultdict(tree)
    kwargs = tree()

    # Setup executioner
    if options.executioner:
        kwargs['Executioner']['type'] = options.executioner

    # Disable extensions
    if options.stable:
        pass
    elif options.fast:
        options.disable += ['MooseDocs.extensions.appsyntax', 'MooseDocs.extensions.navigation',
                            'MooseDocs.extensions.sqa', 'MooseDocs.extensions.civet',
                            'MooseDocs.extensions.gitutils']
    else:
        options.disable += ['MooseDocs.extensions.sqa', 'MooseDocs.extensions.civet',
                            'MooseDocs.extensions.gitutils']

    for name in options.disable:
        kwargs['Extensions'][name] = dict(active=False)

    if options.hide_source:
        kwargs['Extensions']['MooseDocs.extensions.modal']['show_source'] = False

    # Apply Translator settings
    if options.destination:
        kwargs['Translator']['destination'] = mooseutils.eval_path(options.destination)
    if options.profile:
        kwargs['Translator']['profile'] = True

    # Apply '--args' and override anything already set
    if options.args is not None:
        mooseutils.recursive_update(kwargs, options.args)

    # Create translators for the specified configuration files, provide kwargs to override them
    config_files = options.config if isinstance(options.config, list) else [options.config]
    subconfigs = len(config_files) > 1
    LOG.info("Loading configuration file{}".format('s' if subconfigs else ''))
    translators, contents, configurations = common.load_configs(config_files, **kwargs)

    # Initialize the translator objects
    for index, translator in enumerate(translators):
        if subconfigs:
            LOG.info('Initializing translator object loaded from %s', config_files[index])
        translator.init(contents[index])

        # init methods can add pages (e.g., civet.py), but don't add pages from another translator
        contents[index] = [page for page in translator.getPages() if page.translator is translator]

    # Identify the first translator in the list as the "primary" one for convenience
    primary = translators[0]
    pooled = sorted(primary.getPages(), key=(lambda p: p.local))

    # Dump page tree from content pool and syntax list from all translators with AppSyntax
    if options.dump:
        for page in pooled:
            print('{}: {}'.format(page.local, page.source))
        for index, translator in enumerate(translators):
            for extension in translator.extensions:
                if isinstance(extension, MooseDocs.extensions.appsyntax.AppSyntaxExtension):
                    if subconfigs:
                        LOG.info('Building syntax list specified by %s', config_files[index])
                    extension.preExecute()
                    print(extension.syntax)
                    break
        return 0

    # TODO: See `navigation.postExecute`
    #       The navigation "home" should be a markdown file, when all the apps update to this we
    #       can remove this as well as the use of it by CIVET
    home = options.home
    if options.serve and (home is not None) and (not home.endswith('.md')):
        home = 'http://127.0.0.1:{}'.format(options.port)

    if home is not None:
        for ext in primary.extensions:
            if 'home' in ext:
                ext.update(home=home)

    # Set default for --clean: clean when --files is NOT used.
    if options.clean is None:
        options.clean = options.files == []
    else:
        options.clean = options.clean.lower() in ['true', 'yes', '1']

    if options.clean and os.path.exists(primary.destination):
        LOG.info("Cleaning destination %s", primary.destination)
        shutil.rmtree(primary.destination)

    # Update contents lists if only building certain files
    if options.files:
        for index, translator in enumerate(translators):
            func = lambda p: (p in contents[index]
                              and any([p.local.startswith(f) for f in options.files]))
            contents[index] = translator.findPages(func)

    # Execute the read and tokenize methods on all translators
    for index, translator in enumerate(translators):
        if subconfigs:
            LOG.info('Reading content specified by %s', config_files[index])
        translator.execute(contents[index], num_threads=options.num_threads, render=False, write=False)

    # Finally, execute the render and write methods
    for index, translator in enumerate(translators):
        if subconfigs:
            LOG.info('Writing content specified by %s', config_files[index])
        translator.execute(contents[index], num_threads=options.num_threads, read=False, tokenize=False)

    LOG.info('Total Time [%s sec.]', time.time() - t)

    # Run live server and watch for content changes
    if options.serve:
        watcher = MooseDocsWatcher(translators, pooled, configurations, options.num_threads)
        server = livereload.Server(watcher=watcher)
        server.serve(root=primary.destination, host=options.host, port=options.port)

    return 0
Exemple #24
0
 def update(self, **kwargs):
     """Update configuration and handle destination."""
     dest = kwargs.get('destination', None)
     if dest is not None:
         kwargs['destination'] = mooseutils.eval_path(dest)
     mixins.ConfigObject.update(self, **kwargs)
Exemple #25
0
    def init(self):
        """(override) Generate test reports."""

        # Test result database
        self.__database = dict()

        # Only populate the database if the specified branch and author match current repository
        if mooseutils.git_is_branch(self.get('branch')) and \
           mooseutils.git_is_config('user.name', self.get('author')):

            start = time.time()
            LOG.info("Collecting CIVET results...")
            for name, category in self.get('remotes').items():
                working_dir = mooseutils.eval_path(
                    category.get('location', MooseDocs.ROOT_DIR))
                LOG.info("Gathering CIVET results for '%s' category in %s",
                         name, working_dir)
                hashes = None
                if category.get('download_test_results',
                                self.get('download_test_results', True)):
                    hashes = mooseutils.git_civet_hashes(
                        start=self.get('branch'),
                        author=self.get('author'),
                        working_dir=working_dir)
                    LOG.info(
                        "Downloading CIVET results for '%s' category in %s",
                        name, working_dir)

                local = mooseutils.eval_path(
                    category.get('test_results_cache',
                                 self.get('test_results_cache')))
                site = (category['url'], category['repo'])
                local_db = mooseutils.get_civet_results(
                    local=local,
                    hashes=hashes,
                    site=site,
                    cache=local,
                    possible=['OK', 'FAIL', 'DIFF', 'TIMEOUT'],
                    logger=LOG)
                self.__database.update(local_db)
            LOG.info("Collecting CIVET results complete [%s sec.]",
                     time.time() - start)

        if not self.__database and self.get('generate_test_reports', True):
            LOG.info(
                "CIVET test result reports are being disabled, it requires results to exist and the specified branch ('%s') and author ('%s') to match the current repository.",
                self.get('branch'), self.get('author'))
            self.update(generate_test_reports=False)

        if self.get('generate_test_reports', True):
            self.__has_test_reports = True
            start = time.time()
            LOG.info("Creating CIVET result pages...")

            report_root = self.get('test_reports_location')
            if not self.translator.findPage(
                    report_root, exact=True, throw_on_zero=False):
                self.translator.addPage(
                    pages.Directory(report_root, source=report_root))

            src = pages.Source('{}/index.md'.format(report_root),
                               source='{}/index.md'.format(report_root),
                               read=False,
                               tokenize=False)
            self.translator.addPage(src)

            count = 0
            for key, item in self.__database.items():
                name = 'result_{}'.format(count)
                self.__test_result_numbers[key] = name
                count += 1

                fullname = '{}/{}.md'.format(report_root, name)
                src = pages.Source(fullname,
                                   source=fullname,
                                   read=False,
                                   tokenize=False,
                                   key=key)
                self.translator.addPage(src)

            LOG.info("Creating CIVET result pages complete [%s sec.]",
                     time.time() - start)
Exemple #26
0
def main(options):
    """
    Main function for the build command.

    Inputs:
        options[argparse options]: Complete options from argparse, see MooseDocs/main.py
    """

    # Make sure "large_media" exists in MOOSE
    _init_large_media()

    # Setup executioner
    kwargs = dict()
    if options.executioner:
        kwargs['Executioner'] = {'type': options.executioner}

    # Create translator
    translator, _ = common.load_config(options.config, **kwargs)
    if options.destination:
        translator.update(
            destination=mooseutils.eval_path(options.destination))
    if options.profile:
        translator.executioner.update(profile=True)
    translator.init()

    # Disable slow extensions for --fast
    if options.fast:
        options.disable.append('appsyntax')
    # options.disable.append('navigation')

    # Disable extensions based on command line arguments
    if options.disable:
        for ext in translator.extensions:
            if ext.name in options.disable:  #pylint: disable=protected-access
                ext.setActive(False)

    # Replace "home" with local server
    if options.serve:
        for ext in translator.extensions:
            if 'home' in ext:
                ext.update(home='http://127.0.0.1:{}'.format(options.port),
                           set_initial=True)

    # Dump page tree
    if options.dump:
        print translator.root
        sys.exit()

    # Clean when --files is NOT used or when --clean is used with --files.
    if ((options.files == []) or (options.files != [] and options.clean)) \
       and os.path.exists(translator['destination']):
        log = logging.getLogger('MooseDocs.build')
        log.info("Cleaning destination %s", translator['destination'])
        shutil.rmtree(translator['destination'])

    # Perform check
    if options.check:
        check(translator)

    # Perform build
    if options.files:
        nodes = []
        for filename in options.files:
            nodes += translator.findPages(filename)
        translator.execute(options.num_threads, nodes)
    else:
        translator.execute(options.num_threads)

    if options.serve:
        watcher = MooseDocsWatcher(translator, options)
        server = livereload.Server(watcher=watcher)
        server.serve(root=translator['destination'],
                     host=options.host,
                     port=options.port)

    return 0
Exemple #27
0
def main(options):
    """
    Main function for the build command.

    Inputs:
        options[argparse options]: Complete options from argparse, see MooseDocs/main.py
    """

    # Make sure "large_media" exists in MOOSE
    _init_large_media()

    # Setup executioner
    kwargs = dict()
    if options.executioner:
        kwargs['Executioner'] = {'type':options.executioner}

    # Create translator
    translator, _ = common.load_config(options.config, **kwargs)
    if options.destination:
        translator.update(destination=mooseutils.eval_path(options.destination))
    if options.profile:
        translator.executioner.update(profile=True)
    translator.init()

    # Disable slow extensions for --fast
    if options.fast:
        options.disable.append('appsyntax')
        options.disable.append('navigation')

    # Disable extensions based on command line arguments
    if options.disable:
        for ext in translator.extensions:
            if ext.name in options.disable: #pylint: disable=protected-access
                ext.setActive(False)

    # Replace "home" with local server
    if options.serve:
        for ext in translator.extensions:
            if 'home' in ext:
                ext.update(home='http://127.0.0.1:{}'.format(options.port), set_initial=True)

    # Dump page tree
    if options.dump:
        for page in translator.content:
            print '{}: {}'.format(page.local, page.source)
        sys.exit()

    # Clean when --files is NOT used or when --clean is used with --files.
    if ((options.files == []) or (options.files != [] and options.clean)) \
       and os.path.exists(translator['destination']):
        log = logging.getLogger('MooseDocs.build')
        log.info("Cleaning destination %s", translator['destination'])
        shutil.rmtree(translator['destination'])

    # Perform check
    if options.check:
        check(translator)

    # Perform build
    if options.files:
        nodes = []
        for filename in options.files:
            nodes += translator.findPages(filename)
        translator.execute(options.num_threads, nodes)
    else:
        translator.execute(options.num_threads)

    if options.serve:
        watcher = MooseDocsWatcher(translator, options)
        server = livereload.Server(watcher=watcher)
        server.serve(root=translator['destination'], host=options.host, port=options.port)

    return 0
Exemple #28
0
    def execute(self, **kwargs):
        """Perform app syntax checking"""

        # Check that the supplied content dir exists
        content_dir = mooseutils.eval_path(self.content_directory)
        if not os.path.isdir(content_dir):
            content_dir = os.path.join(self.working_dir, content_dir)
        if not os.path.isdir(content_dir):
            raise NotADirectoryError(
                "'content_directory' input is not a directory: {}".format(
                    content_dir))

        # Populate the available list of files
        file_cache = mooseutils.git_ls_files(content_dir)

        # Check that the supplied exe dir exists
        exe_dir = mooseutils.eval_path(self.exe_directory)
        if not os.path.isdir(exe_dir):
            exe_dir = os.path.join(self.working_dir, exe_dir)
        if not os.path.isdir(exe_dir):
            raise NotADirectoryError(
                "'exe_directory' input is not a directory: {}".format(exe_dir))

        # Locate the executable
        exe = mooseutils.find_moose_executable(exe_dir,
                                               name=self.exe_name,
                                               show_error=False)
        if exe is None:
            raise OSError(
                "An executable was not found in '{}' with a name '{}'.".format(
                    exe_dir, self.exe_name))

        # Build syntax tree if not provided
        if self.app_syntax is None:

            # Get the hidden/removed/alias information
            hide = self._loadYamlFiles(self.hidden)
            remove = self._loadYamlFiles(self.remove)
            alias = self._loadYamlFiles(self.alias)
            unregister = self._loadYamlFiles(self.unregister)

            # Build the complete syntax tree
            self.app_syntax = moosesyntax.get_moose_syntax_tree(
                exe,
                hide=hide,
                remove=remove,
                alias=alias,
                unregister=unregister,
                allow_test_objects=self.allow_test_objects)

        # Determine the application type (e.g., MooseTestApp)
        if self.app_types is None:
            out = mooseutils.run_executable(exe, ['--type'])
            match = re.search(r'^MooseApp Type:\s+(?P<type>.*?)$',
                              out,
                              flags=re.MULTILINE)
            if match:
                self.app_types = [
                    match.group("type").replace('TestApp', 'App')
                ]

        # Perform the checks
        kwargs.setdefault('syntax_prefix',
                          mooseutils.eval_path(self.syntax_prefix))
        kwargs.setdefault('object_prefix',
                          mooseutils.eval_path(self.object_prefix))
        logger = check_syntax(self.app_syntax, self.app_types, file_cache,
                              **kwargs)

        # Create stub pages
        if self.generate_stubs:
            func = lambda n: (not n.removed) \
                             and ('_md_file' in n) \
                             and ((n['_md_file'] is None) or n['_is_stub']) \
                             and ((n.group in self.app_types) \
                                  or (n.groups() == set(self.app_types)))
            for node in moosetree.iterate(self.app_syntax, func):
                self._createStubPage(node)

        # Dump
        if self.dump_syntax:
            print(self.app_syntax)

        return logger
Exemple #29
0
 def update(self, **kwargs):
     """Update configuration and handle destination."""
     dest = kwargs.get('destination', None)
     if dest is not None:
         kwargs['destination'] = mooseutils.eval_path(dest)
     mixins.ConfigObject.update(self, **kwargs)
Exemple #30
0
    def preExecute(self):
        """Initialize requirement information"""

        # Clear any existing counts
        self.__counts.clear()

        # Do not repopulate
        if self.__requirements:
            return

        start = time.time()
        LOG.info("Gathering SQA requirement information...")

        repos = self.get('repos')
        for index, (category, info) in enumerate(self.get('categories').items(), 1):
            specs = info.get('specs', ['tests'])
            repo = info.get('repo', 'default')
            reports = info.get('reports', None)
            directories = []

            for d in info.get('directories'):
                path = mooseutils.eval_path(d)
                if not os.path.isdir(path):
                    path = os.path.join(MooseDocs.ROOT_DIR, d)
                if not os.path.isdir(path):
                    msg = "Input directory does not exist: %s"
                    LOG.error(msg, path)

                directories.append(path)

            # Create requirement database
            self.__requirements[category] = moosesqa.get_requirements(directories, specs, 'F', index)

            # Create dependency database
            self.__dependencies[category] = info.get('dependencies', [])

            # Create remote repository database
            self.__remotes[category] = repos.get(repo, None)

            # Create reports from included SQA apps (e.g., moose/modulus/stochastic_tools)
            if reports:
                self.__reports[category] = moosesqa.get_sqa_reports(reports)

        # Report for the entire app (e.g, moose/modules/doc)
        general_reports = self.get('reports')
        if general_reports is not None:
            self.__reports['__empty__'] = moosesqa.get_sqa_reports(general_reports)

        # The following attempts to save computation time by avoiding re-computing the application
        # syntax for each report. This is done by extracting the syntax from the appsyntax extension
        # and using it within the SQAMooseAppReport objects.

        # Get the syntax tree and executable info from the appsyntax extension
        app_syntax = None
        exe_dir = None
        exe_name = None
        for ext in self.translator.extensions:
            if isinstance(ext, appsyntax.AppSyntaxExtension):
                app_syntax = ext.syntax
                exe_dir, exe_name = os.path.split(ext.executable) if ext.executable else (None, None)
                break

        # Setup the SQAMooseAppReports to use the syntax from the running app
        for reports in self.__reports.values():
            for app_report in reports[2]:
                app_report.app_syntax = app_syntax
                app_report.exe_directory = exe_dir
                app_report.exe_name = exe_name.split('-')[0] if exe_name else None
                if app_syntax is None:
                    msg = 'Attempting to inject application syntax into SQAMooseAppReport, but the syntax does not exist.'
                    LOG.warning(msg)

        LOG.info("Gathering SQA requirement information complete [%s sec.]", time.time() - start)
Exemple #31
0
def main(options):
    """
    Main function for the build command.

    Inputs:
        options[argparse options]: Complete options from argparse, see MooseDocs/main.py
    """
    # Infinite nested dict
    tree = lambda: collections.defaultdict(tree)
    kwargs = tree()

    # Setup executioner
    if options.executioner:
        kwargs['Executioner']['type'] = options.executioner

    # Disable extensions
    if options.fast:
        options.disable += [
            'MooseDocs.extensions.appsyntax',
            'MooseDocs.extensions.navigation', 'MooseDocs.extensions.sqa',
            'MooseDocs.extensions.civet'
        ]
    for name in options.disable:
        kwargs['Extensions'][name] = dict(active=False)

    # Apply '--args' and override anything already set
    if options.args is not None:
        mooseutils.recursive_update(kwargs, options.args)

    # Create translator, provide kwargs to override content of file
    translator, _ = common.load_config(options.config, **kwargs)
    if options.destination:
        translator.update(
            destination=mooseutils.eval_path(options.destination))
    if options.profile:
        translator.executioner.update(profile=True)
    translator.init()

    # Replace "home" with local server
    home = options.home
    if options.serve:
        home = 'http://127.0.0.1:{}'.format(options.port)

    if home is not None:
        for ext in translator.extensions:
            if 'home' in ext:
                ext.update(home=home)

    # Dump page tree
    if options.dump:
        for page in translator.getPages():
            print('{}: {}'.format(page.local, page.source))
        for ext in translator.extensions:
            if isinstance(ext,
                          MooseDocs.extensions.appsyntax.AppSyntaxExtension):
                ext.preExecute()
                print(ext.syntax)
        return 0

    # Set default for --clean: clean when --files is NOT used.
    if options.clean is None:
        options.clean = options.files == []
    else:
        options.clean = options.clean.lower() in ['true', 'yes', '1']

    if options.clean and os.path.exists(translator['destination']):
        log = logging.getLogger('MooseDocs.build')
        log.info("Cleaning destination %s", translator['destination'])
        shutil.rmtree(translator['destination'])

    # Perform build
    if options.files:
        nodes = []
        for filename in options.files:
            nodes += translator.findPages(filename)
        translator.execute(nodes, options.num_threads)
    else:
        translator.execute(None, options.num_threads)

    if options.serve:
        watcher = MooseDocsWatcher(translator, options)
        server = livereload.Server(watcher=watcher)
        server.serve(root=translator['destination'],
                     host=options.host,
                     port=options.port)

    return 0
Exemple #32
0
def main(options):
    """
    Main function for the build command.

    Inputs:
        options[argparse options]: Complete options from argparse, see MooseDocs/main.py
    """

    # Make sure "large_media" exists in MOOSE
    _init_large_media()

    # Setup executioner
    kwargs = dict()
    if options.executioner:
        kwargs['Executioner'] = {'type':options.executioner}

    # Disable extensions
    if options.fast:
        options.disable += ['MooseDocs.extensions.appsyntax', 'MooseDocs.extensions.navigation',
                            'MooseDocs.extensions.sqa', 'MooseDocs.extensions.civet']

    kwargs['Extensions'] = dict()
    for name in options.disable:
        kwargs['Extensions'][name] = dict(active=False)

    # Create translator
    translator, _ = common.load_config(options.config, **kwargs)
    if options.destination:
        translator.update(destination=mooseutils.eval_path(options.destination))
    if options.profile:
        translator.executioner.update(profile=True)
    translator.init()

    # Replace "home" with local server
    home = options.home
    if options.serve:
        home = 'http://127.0.0.1:{}'.format(options.port)

    if home is not None:
        for ext in translator.extensions:
            if 'home' in ext:
                ext.update(home=home)

    # Dump page tree
    if options.dump:
        for page in translator.getPages():
            print('{}: {}'.format(page.local, page.source))
        sys.exit()

    # Set default for --clean: clean when --files is NOT used.
    if options.clean is None:
        options.clean = options.files == []
    else:
        options.clean = options.clean.lower() in ['true', 'yes', '1']

    if options.clean and os.path.exists(translator['destination']):
        log = logging.getLogger('MooseDocs.build')
        log.info("Cleaning destination %s", translator['destination'])
        shutil.rmtree(translator['destination'])

    # Perform check
    if options.check:
        check(translator)

    # Perform build
    if options.files:
        nodes = []
        for filename in options.files:
            nodes += translator.findPages(filename)
        translator.execute(nodes, options.num_threads)
    else:
        translator.execute(None, options.num_threads)

    if options.serve:
        watcher = MooseDocsWatcher(translator, options)
        server = livereload.Server(watcher=watcher)
        server.serve(root=translator['destination'], host=options.host, port=options.port)

    return 0
Exemple #33
0
    def init(self):
        """(override) Generate test reports."""

        # Test result database
        self.__database = dict()
        self.__hashes = None

        # Only populate the database if the specified branch and author match current repository
        start = time.time()
        LOG.info("Collecting CIVET results...")
        branch = self.get('branch')
        remotes = mooseutils.git_remotes()
        for name, category in self.get('remotes').items():
            LOG.info("Gathering CIVET results for '%s'.", name)
            if category.get('download_test_results', self.get('download_test_results', True)):
                repo_url = category.get('repo_url', 'https://github.com').rstrip('/')
                repo_url += '/{}'.format(category.get('repo'))

                remote = remotes.get(repo_url, None)
                if remote is None:
                    remote = '__MooseDocs.extensions.civet__'
                    mooseutils.git_add_and_fetch_remote(repo_url, remote, branch)
                else:
                    mooseutils.get_fetch_remote(remote, branch)

                self.__hashes = mooseutils.get_civet_hashes(f'{remote}/{branch}')
                LOG.info("Downloading CIVET results for '%s' category.", name)

            local = mooseutils.eval_path(category.get('test_results_cache', self.get('test_results_cache')))
            site = (category['url'], category['repo'])
            local_db = mooseutils.get_civet_results(local=local,
                                                    hashes=self.__hashes,
                                                    site=site,
                                                    cache=local,
                                                    possible=['OK', 'FAIL', 'DIFF', 'TIMEOUT'],
                                                    logger=LOG)
            self.__database.update(local_db)
        LOG.info("Collecting CIVET results complete [%s sec.]", time.time() - start)

        if not self.__database and self.get('generate_test_reports', True):
            LOG.info("CIVET test result reports are being disabled, it requires results to exist and the specified branch ('%s') to match the current repository.", self.get('branch'))
            self.update(generate_test_reports=False)

        if self.get('generate_test_reports', True):
            self.__has_test_reports = True

            start = time.time()
            LOG.info("Creating CIVET result pages...")

            result_pages = list()
            report_root = self.get('test_reports_location')
            if not self.translator.findPage(report_root, exact=True, throw_on_zero=False):
                result_pages.append(pages.Directory(report_root, source=report_root))

            result_pages.append(pages.Source('{}/index.md'.format(report_root),
                                             source='{}/index.md'.format(report_root),
                                             read=False, tokenize=False))

            count = 0
            for key, item in self.__database.items():
                name = 'result_{}'.format(count)
                self.__test_result_numbers[key] = name
                count += 1

                fullname = '{}/{}.md'.format(report_root, name)
                result_pages.append(pages.Source(fullname, source=fullname,
                                                 read=False, tokenize=False, key=key))

            self.translator.addPages(result_pages)
            self.translator.executioner.initPages(result_pages)

            LOG.info("Creating CIVET result pages complete [%s sec.]", time.time() - start)
Exemple #34
0
    def preExecute(self):
        """Initialize requirement information"""

        # Clear any existing counts
        self.__counts.clear()

        # Do not repopulate
        if self.__requirements:
            return

        start = time.time()
        LOG.info("Gathering SQA requirement information...")

        for category, info in self.get('categories').items():
            specs = info.get('specs', ['tests'])
            repo = info.get('repo', 'default')
            reports = info.get('reports', None)

            # Build the requirements, dependencies, remotes, and reports data structures
            directories = list()
            for d in info.get('directories', []):
                path = mooseutils.eval_path(d)
                if not os.path.isdir(path):
                    path = os.path.join(MooseDocs.ROOT_DIR, d)
                if not os.path.isdir(path):
                    msg = "Input directory does not exist: %s"
                    LOG.error(msg, path)
                    continue
                directories.append(path)

            # Create requirement database from tests
            self.__requirements[
                category] = moosesqa.get_requirements_from_tests(
                    directories, specs,
                    self.get('include_non_testable_requirements'))

            # Create dependency database
            self.__dependencies[category] = info.get('dependencies', [])

            # Create remote repository database
            repos = self.get('repos')
            self.__remotes[category] = repos.get(repo, None)

            # Create reports from included SQA apps (e.g., moose/modulus/stochastic_tools)
            if reports:
                self.__reports[category] = moosesqa.get_sqa_reports(reports)

        # Number the requirements
        for c, req_dict in enumerate(self.__requirements.values(), start=1):
            moosesqa.number_requirements(req_dict, c)

        # Report for the entire app (e.g, moose/modules/doc)
        general_reports = self.get('reports')
        if general_reports is not None:
            self.__reports['_empty_'] = moosesqa.get_sqa_reports(
                general_reports)

        # The following attempts to save computation time by avoiding re-computing the application
        # syntax for each report. This is done by extracting the syntax from the appsyntax extension
        # and using it within the SQAMooseAppReport objects.

        # Get the syntax tree and executable info from the appsyntax extension
        app_syntax = None
        exe_dir = None
        exe_name = None
        for ext in self.translator.extensions:
            if isinstance(ext, appsyntax.AppSyntaxExtension):
                app_syntax = ext.syntax
                exe_dir, exe_name = os.path.split(
                    ext.executable) if ext.executable else (None, None)
                break

        # Setup the SQAMooseAppReports to use the syntax from the running app
        for reports in self.__reports.values():
            for app_report in reports[2]:
                app_report.app_syntax = app_syntax
                app_report.exe_directory = exe_dir
                app_report.exe_name = exe_name.rsplit(
                    '-', maxsplit=1)[0] if exe_name else None
                if app_syntax is None:
                    msg = 'Attempting to inject application syntax into SQAMooseAppReport, but the syntax does not exist.'
                    LOG.warning(msg)

        # Set default collection and add RunException tests to FAILURE_ANALYSIS collection
        d_type = self['default_collection']
        for req_category in self.__requirements.values():
            for requirements in req_category.values():
                for req in requirements:
                    t_types = req.types
                    if (req.collections is
                            None) and (t_types is not None) and ('RunException'
                                                                 in t_types):
                        req.collections = set([d_type, 'FAILURE_ANALYSIS'])
                    elif (req.collections is None):
                        req.collections = set([d_type])

        LOG.info("Gathering SQA requirement information complete [%s sec.]",
                 time.time() - start)
Exemple #35
0
    def check(self, generate=False, groups=None, update=None, locations=None):
        """
        Check that the expected documentation exists.

        Return:
            True, False, or None, where True indicates that the page exists, False indicates the
            page does not exist or doesn't contain content, and None indicates that the page is
            hidden.
        """
        if self.is_root:
            return

        if self.removed:
            LOG.debug("Skipping documentation check for %s, it is REMOVED.", self.fullpath)
            return

        groups = groups if groups is not None else self.groups
        for group in groups:

            # Skip if the node is not in the desired groups
            if group not in self.groups:
                continue

            # Locate all the possible locations for the markdown
            filenames = set()
            for location in locations:
                install = mooseutils.eval_path(os.path.join(location, 'documentation', 'systems'))
                if not os.path.isabs(install):
                    filename = os.path.join(MooseDocs.ROOT_DIR, install, self.markdown())
                else:
                    filename = os.path.join(install, self.markdown())
                filenames.add((filename, os.path.isfile(filename)))

            # Determine the number of files that exist
            count = sum([x[1] for x in filenames])

            # Class description
            if isinstance(self, ObjectNode) and not self.description and not self.hidden:
                msg = "The class description is missing for %s, it can be added using the " \
                      "'addClassDescription' method from within the objects validParams function."
                LOG.error(msg, self.fullpath)

            # Error if multiple files exist
            if count > 1 and not self.hidden:
                msg = "Multiple markdown files were located for the '{}' syntax:". \
                      format(self.fullpath)
                for filename, exists in filenames:
                    if exists:
                        msg += '\n  {}'.format(filename)
                LOG.error(msg)

            # Error if no files exist
            elif count == 0:
                if not self.hidden:
                    msg = "No documentation for %s, documentation for this object should be " \
                          "created in one of the following locations:"
                    for filename, _ in filenames:
                        msg += '\n  {}'.format(filename)
                    msg += "\nIt is possible to generate stub pages for your documentation " \
                           "using the './moosedocs.py check --generate' command."

                    LOG.error(msg, self.fullpath)

                if generate:
                    if not os.path.exists(os.path.dirname(filename)):
                        os.makedirs(os.path.dirname(filename))
                    LOG.info('Creating stub page for %s %s', self.fullpath, filename)
                    with open(filename, 'w') as fid:
                        content = self._defaultContent()
                        if not isinstance(content, str):
                            raise TypeError("The _defaultContent method must return a str.")
                        fid.write(content)
            else:
                for name, exists in filenames:
                    if exists:
                        filename = name

                with open(filename, 'r') as fid:
                    lines = fid.readlines()

                if lines and self.STUB_HEADER in lines[0]:
                    if not self.hidden:
                        msg = "A MOOSE generated stub page for %s exists, but no content was " \
                              "added. Add documentation content to %s."
                        LOG.error(msg, self.fullpath, filename)

                    if update:
                        LOG.info("Updating stub page for %s in file %s.", self.fullpath, filename)
                        with open(filename, 'w') as fid:
                            content = self._defaultContent()
                            if not isinstance(content, str):
                                raise TypeError("The _defaultContent method must return a str.")
                            fid.write(content)


                elif self.hidden and isinstance(self, ObjectNode) and self.description:
                    msg = "The MOOSE syntax %s is listed has hidden; however, a modified page " \
                          "exists for the object, please remove the syntax from the list of " \
                          "hidden list."
                    LOG.error(msg, self.fullpath)
Exemple #36
0
    def check(self, generate=False, groups=None, update=None):
        """
        Check that the expected documentation exists.

        Return:
            True, False, or None, where True indicates that the page exists, False indicates the
            page does not exist or doesn't contain content, and None indicates that the page is
            hidden.
        """
        if self.is_root:
            return

        if self.removed:
            LOG.debug("Skipping documentation check for %s, it is REMOVED.", self.fullpath)
            return

        groups = groups if groups is not None else self.groups
        for group in groups:

            # Locate all the possible locations for the markdown
            filenames = []
            for group in self.groups:
                install = SyntaxNodeBase.DESTINATIONS.get(group,
                                                          'doc/content/documentation/systems')
                install = mooseutils.eval_path(install)
                if not os.path.isabs(install):
                    filename = os.path.join(MooseDocs.ROOT_DIR, install, self.markdown())
                else:
                    filename = os.path.join(install, self.markdown())
                filenames.append((filename, os.path.isfile(filename)))

            # Determine the number of files that exist
            count = sum([x[1] for x in filenames])

            # Class description
            if isinstance(self, ObjectNode) and not self.description and not self.hidden:
                msg = "The class description is missing for %s, it can be added using the " \
                      "'addClassDescription' method from within the objects validParams function."
                LOG.error(msg, self.fullpath)

            # Error if multiple files exist
            if count > 1 and not self.hidden:
                msg = "Multiple markdown files were located for the '{}' syntax:". \
                      format(self.fullpath)
                for filename, exists in filenames:
                    if exists:
                        msg += '\n  {}'.format(filename)
                LOG.error(msg)

            # Error if no files exist
            elif count == 0:
                if not self.hidden:
                    msg = "No documentation for %s, documentation for this object should be " \
                          "created in one of the following locations:"
                    for filename, _ in filenames:
                        msg += '\n  {}'.format(filename)
                    msg += "\nIt is possible to generate stub pages for your documentation " \
                           "using the './moosedocs.py check --generate' command."

                    LOG.error(msg, self.fullpath)

                if generate:
                    if not os.path.exists(os.path.dirname(filename)):
                        os.makedirs(os.path.dirname(filename))
                    LOG.info('Creating stub page for %s %s', self.fullpath, filename)
                    with open(filename, 'w') as fid:
                        content = self._defaultContent()
                        if not isinstance(content, str):
                            raise TypeError("The _defaultContent method must return a str.")
                        fid.write(content)
            else:
                for name, exists in filenames:
                    if exists:
                        filename = name

                with open(filename, 'r') as fid:
                    lines = fid.readlines()

                if lines and self.STUB_HEADER in lines[0]:
                    if not self.hidden:
                        msg = "A MOOSE generated stub page for %s exists, but no content was " \
                              "added. Add documentation content to %s."
                        LOG.error(msg, self.fullpath, filename)

                    if update:
                        LOG.info("Updating stub page for %s in file %s.", self.fullpath, filename)
                        with open(filename, 'w') as fid:
                            content = self._defaultContent()
                            if not isinstance(content, str):
                                raise TypeError("The _defaultContent method must return a str.")
                            fid.write(content)


                elif self.hidden and isinstance(self, ObjectNode) and self.description:
                    msg = "The MOOSE syntax %s is listed has hidden; however, a modified page " \
                          "exists for the object, please remove the syntax from the list of " \
                          "hidden list."
                    LOG.error(msg, self.fullpath)