[Notes] [Git][BuildStream/buildstream][master] 5 commits: _loader/loader.py: Refactor warnings about element names in one method



Title: GitLab

Tristan Van Berkom pushed to branch master at BuildStream / buildstream

Commits:

7 changed files:

Changes:

  • buildstream/_loader/loader.py
    ... ... @@ -99,7 +99,6 @@ class Loader():
    99 99
         # Returns: The toplevel LoadElement
    
    100 100
         def load(self, targets, rewritable=False, ticker=None, fetch_subprojects=False):
    
    101 101
     
    
    102
    -        invalid_elements = []
    
    103 102
             for filename in targets:
    
    104 103
                 if os.path.isabs(filename):
    
    105 104
                     # XXX Should this just be an assertion ?
    
    ... ... @@ -109,14 +108,8 @@ class Loader():
    109 108
                                     "path to the base project directory: {}"
    
    110 109
                                     .format(filename, self._basedir))
    
    111 110
     
    
    112
    -            if not filename.endswith(".bst"):
    
    113
    -                invalid_elements.append(filename)
    
    111
    +        self._warn_invalid_elements(targets)
    
    114 112
     
    
    115
    -        if invalid_elements:
    
    116
    -            self._warn("Target elements '{}' do not have expected file extension `.bst` "
    
    117
    -                       "Improperly named elements will not be discoverable by commands"
    
    118
    -                       .format(invalid_elements),
    
    119
    -                       warning_token=CoreWarnings.BAD_ELEMENT_SUFFIX)
    
    120 113
             # First pass, recursively load files and populate our table of LoadElements
    
    121 114
             #
    
    122 115
             deps = []
    
    ... ... @@ -280,12 +273,7 @@ class Loader():
    280 273
             self._elements[filename] = element
    
    281 274
     
    
    282 275
             # Load all dependency files for the new LoadElement
    
    283
    -        invalid_elements = []
    
    284 276
             for dep in element.deps:
    
    285
    -            if not dep.name.endswith(".bst"):
    
    286
    -                invalid_elements.append(dep.name)
    
    287
    -                continue
    
    288
    -
    
    289 277
                 if dep.junction:
    
    290 278
                     self._load_file(dep.junction, rewritable, ticker, fetch_subprojects, yaml_cache)
    
    291 279
                     loader = self._get_loader(dep.junction, rewritable=rewritable, ticker=ticker,
    
    ... ... @@ -300,11 +288,9 @@ class Loader():
    300 288
                                     "{}: Cannot depend on junction"
    
    301 289
                                     .format(dep.provenance))
    
    302 290
     
    
    303
    -        if invalid_elements:
    
    304
    -            self._warn("The following dependencies do not have expected file extension `.bst`: {} "
    
    305
    -                       "Improperly named elements will not be discoverable by commands"
    
    306
    -                       .format(invalid_elements),
    
    307
    -                       warning_token=CoreWarnings.BAD_ELEMENT_SUFFIX)
    
    291
    +        deps_names = [dep.name for dep in element.deps]
    
    292
    +        self._warn_invalid_elements(deps_names)
    
    293
    +
    
    308 294
             return element
    
    309 295
     
    
    310 296
         # _check_circular_deps():
    
    ... ... @@ -679,3 +665,69 @@ class Loader():
    679 665
     
    
    680 666
             message = Message(None, MessageType.WARN, brief)
    
    681 667
             self._context.message(message)
    
    668
    +
    
    669
    +    # Print warning messages if any of the specified elements have invalid names.
    
    670
    +    #
    
    671
    +    # Valid filenames should end with ".bst" extension.
    
    672
    +    #
    
    673
    +    # Args:
    
    674
    +    #    elements (list): List of element names
    
    675
    +    #
    
    676
    +    # Raises:
    
    677
    +    #     (:class:`.LoadError`): When warning_token is considered fatal by the project configuration
    
    678
    +    #
    
    679
    +    def _warn_invalid_elements(self, elements):
    
    680
    +
    
    681
    +        # invalid_elements
    
    682
    +        #
    
    683
    +        # A dict that maps warning types to the matching elements.
    
    684
    +        invalid_elements = {
    
    685
    +            CoreWarnings.BAD_ELEMENT_SUFFIX: [],
    
    686
    +            CoreWarnings.BAD_CHARACTERS_IN_NAME: [],
    
    687
    +        }
    
    688
    +
    
    689
    +        for filename in elements:
    
    690
    +            if not filename.endswith(".bst"):
    
    691
    +                invalid_elements[CoreWarnings.BAD_ELEMENT_SUFFIX].append(filename)
    
    692
    +            if not self._valid_chars_name(filename):
    
    693
    +                invalid_elements[CoreWarnings.BAD_CHARACTERS_IN_NAME].append(filename)
    
    694
    +
    
    695
    +        if invalid_elements[CoreWarnings.BAD_ELEMENT_SUFFIX]:
    
    696
    +            self._warn("Target elements '{}' do not have expected file extension `.bst` "
    
    697
    +                       "Improperly named elements will not be discoverable by commands"
    
    698
    +                       .format(invalid_elements[CoreWarnings.BAD_ELEMENT_SUFFIX]),
    
    699
    +                       warning_token=CoreWarnings.BAD_ELEMENT_SUFFIX)
    
    700
    +        if invalid_elements[CoreWarnings.BAD_CHARACTERS_IN_NAME]:
    
    701
    +            self._warn("Target elements '{}' have invalid characerts in their name."
    
    702
    +                       .format(invalid_elements[CoreWarnings.BAD_CHARACTERS_IN_NAME]),
    
    703
    +                       warning_token=CoreWarnings.BAD_CHARACTERS_IN_NAME)
    
    704
    +
    
    705
    +    # Check if given filename containers valid characters.
    
    706
    +    #
    
    707
    +    # Args:
    
    708
    +    #    name (str): Name of the file
    
    709
    +    #
    
    710
    +    # Returns:
    
    711
    +    #    (bool): True if all characters are valid, False otherwise.
    
    712
    +    #
    
    713
    +    def _valid_chars_name(self, name):
    
    714
    +        for char in name:
    
    715
    +            char_val = ord(char)
    
    716
    +
    
    717
    +            # 0-31 are control chars, 127 is DEL, and >127 means non-ASCII
    
    718
    +            if char_val <= 31 or char_val >= 127:
    
    719
    +                return False
    
    720
    +
    
    721
    +            # Disallow characters that are invalid on Windows. The list can be
    
    722
    +            # found at https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file
    
    723
    +            #
    
    724
    +            # Note that although : (colon) is not allowed, we do not raise
    
    725
    +            # warnings because of that, since we use it as a separator for
    
    726
    +            # junctioned elements.
    
    727
    +            #
    
    728
    +            # We also do not raise warnings on slashes since they are used as
    
    729
    +            # path separators.
    
    730
    +            if char in r'<>"|?*':
    
    731
    +                return False
    
    732
    +
    
    733
    +        return True

  • buildstream/types.py
    ... ... @@ -105,6 +105,12 @@ class CoreWarnings():
    105 105
         is referenced either on the command line or by another element
    
    106 106
         """
    
    107 107
     
    
    108
    +    BAD_CHARACTERS_IN_NAME = "bad-characters-in-name"
    
    109
    +    """
    
    110
    +    This warning will be produces when filename for a target contains invalid
    
    111
    +    characters in its name.
    
    112
    +    """
    
    113
    +
    
    108 114
     
    
    109 115
     # _KeyStrength():
    
    110 116
     #
    

  • doc/source/format_declaring.rst
    ... ... @@ -526,3 +526,27 @@ read-only variables are also dynamically declared by BuildStream:
    526 526
       build, support for this is conditional on the element type
    
    527 527
       and the build system used (any element using 'make' can
    
    528 528
       implement this).
    
    529
    +
    
    530
    +
    
    531
    +Naming elements
    
    532
    +---------------
    
    533
    +When naming the element files, use the following rules:
    
    534
    +
    
    535
    +* The name of the file must have ``.bst`` extension.
    
    536
    +
    
    537
    +* All characters in the name must be printable 7-bit ASCII characters.
    
    538
    +
    
    539
    +* Following characters are reserved and must not be part of the name:
    
    540
    +
    
    541
    +  - ``<`` (less than)
    
    542
    +  - ``>`` (greater than)
    
    543
    +  - ``:`` (colon)
    
    544
    +  - ``"`` (double quote)
    
    545
    +  - ``/`` (forward slash)
    
    546
    +  - ``\`` (backslash)
    
    547
    +  - ``|`` (vertical bar)
    
    548
    +  - ``?`` (question mark)
    
    549
    +  - ``*`` (asterisk)
    
    550
    +
    
    551
    +BuildStream will attempt to raise warnings when any of these rules are violated
    
    552
    +but that may not always be possible.

  • tests/frontend/buildcheckout.py
    ... ... @@ -85,6 +85,20 @@ def test_build_invalid_suffix_dep(datafiles, cli, strict, hardlinks):
    85 85
         result.assert_main_error(ErrorDomain.LOAD, "bad-element-suffix")
    
    86 86
     
    
    87 87
     
    
    88
    +@pytest.mark.datafiles(DATA_DIR)
    
    89
    +def test_build_invalid_filename_chars(datafiles, cli):
    
    90
    +    project = os.path.join(datafiles.dirname, datafiles.basename)
    
    91
    +    result = cli.run(project=project, args=strict_args(['build', 'invalid-chars|<>-in-name.bst'], 'non-strict'))
    
    92
    +    result.assert_main_error(ErrorDomain.LOAD, "bad-characters-in-name")
    
    93
    +
    
    94
    +
    
    95
    +@pytest.mark.datafiles(DATA_DIR)
    
    96
    +def test_build_invalid_filename_chars_dep(datafiles, cli):
    
    97
    +    project = os.path.join(datafiles.dirname, datafiles.basename)
    
    98
    +    result = cli.run(project=project, args=strict_args(['build', 'invalid-chars-in-dep.bst'], 'non-strict'))
    
    99
    +    result.assert_main_error(ErrorDomain.LOAD, "bad-characters-in-name")
    
    100
    +
    
    101
    +
    
    88 102
     @pytest.mark.datafiles(DATA_DIR)
    
    89 103
     @pytest.mark.parametrize("deps", [("run"), ("none"), ("build")])
    
    90 104
     def test_build_checkout_deps(datafiles, cli, deps):
    

  • tests/frontend/project/elements/invalid-chars-in-dep.bst
    1
    +kind: stack
    
    2
    +description: |
    
    3
    +
    
    4
    +  This element itself has a valid name, but depends on elements that have
    
    5
    +  invalid names. This should also result in a warning.
    
    6
    +
    
    7
    +depends:
    
    8
    +- invalid-chars|<>-in-name.bst

  • tests/frontend/project/elements/invalid-chars|<>-in-name.bst
    1
    +kind: stack
    
    2
    +description: |
    
    3
    +  The name of this files contains characters that are not allowed by
    
    4
    +  BuildStream, using it should raise a warning.

  • tests/frontend/project/project.conf
    ... ... @@ -5,3 +5,4 @@ element-path: elements
    5 5
     
    
    6 6
     fatal-warnings:
    
    7 7
     - bad-element-suffix
    
    8
    +- bad-characters-in-name



  • [Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]