[Notes] [Git][BuildStream/buildstream][bschubert/pipeline] 9 commits: _frontend/cli.py: Also check original args for --config in bash completion



Title: GitLab

Benjamin Schubert pushed to branch bschubert/pipeline at BuildStream / buildstream

Commits:

7 changed files:

Changes:

  • .gitlab-ci.yml
    ... ... @@ -96,7 +96,6 @@ tests-unix:
    96 96
         # Since the unix platform is required to run as root, no user change required
    
    97 97
         - ${TEST_COMMAND}
    
    98 98
     
    
    99
    -
    
    100 99
     tests-fedora-missing-deps:
    
    101 100
       # Ensure that tests behave nicely while missing bwrap and ostree
    
    102 101
       image: buildstream/testsuite-fedora:28-5da27168-32c47d1c
    
    ... ... @@ -114,6 +113,22 @@ tests-fedora-missing-deps:
    114 113
     
    
    115 114
         - ${TEST_COMMAND}
    
    116 115
     
    
    116
    +tests-fedora-update-deps:
    
    117
    +  # Check if the tests pass after updating requirements to their latest
    
    118
    +  # allowed version.
    
    119
    +  allow_failure: true
    
    120
    +  image: buildstream/testsuite-fedora:28-5da27168-32c47d1c
    
    121
    +  <<: *tests
    
    122
    +
    
    123
    +  script:
    
    124
    +    - useradd -Um buildstream
    
    125
    +    - chown -R buildstream:buildstream .
    
    126
    +
    
    127
    +    - make --always-make --directory requirements
    
    128
    +    - cat requirements/*.txt
    
    129
    +
    
    130
    +    - su buildstream -c "${TEST_COMMAND}"
    
    131
    +
    
    117 132
     # Lint separately from testing
    
    118 133
     lint:
    
    119 134
       stage: test
    
    ... ... @@ -146,7 +161,7 @@ docs:
    146 161
       stage: test
    
    147 162
       variables:
    
    148 163
         BST_EXT_URL: git+https://gitlab.com/BuildStream/bst-external.git
    
    149
    -    BST_EXT_REF: 573843768f4d297f85dc3067465b3c7519a8dcc3 # 0.7.0
    
    164
    +    BST_EXT_REF: 0.9.0-0-g63a19e8068bd777bd9cd59b1a9442f9749ea5a85
    
    150 165
         FD_SDK_REF: freedesktop-sdk-18.08.25-0-g250939d465d6dd7768a215f1fa59c4a3412fc337
    
    151 166
       before_script:
    
    152 167
       - |
    

  • buildstream/_frontend/cli.py
    ... ... @@ -2,6 +2,7 @@ import os
    2 2
     import sys
    
    3 3
     from contextlib import ExitStack
    
    4 4
     from fnmatch import fnmatch
    
    5
    +from functools import partial
    
    5 6
     from tempfile import TemporaryDirectory
    
    6 7
     
    
    7 8
     import click
    
    ... ... @@ -111,14 +112,25 @@ def complete_target(args, incomplete):
    111 112
         return complete_list
    
    112 113
     
    
    113 114
     
    
    114
    -def complete_artifact(args, incomplete):
    
    115
    +def complete_artifact(orig_args, args, incomplete):
    
    115 116
         from .._context import Context
    
    116 117
         ctx = Context()
    
    117 118
     
    
    118 119
         config = None
    
    119
    -    for i, arg in enumerate(args):
    
    120
    -        if arg in ('-c', '--config'):
    
    121
    -            config = args[i + 1]
    
    120
    +    if orig_args:
    
    121
    +        for i, arg in enumerate(orig_args):
    
    122
    +            if arg in ('-c', '--config'):
    
    123
    +                try:
    
    124
    +                    config = orig_args[i + 1]
    
    125
    +                except IndexError:
    
    126
    +                    pass
    
    127
    +    if args:
    
    128
    +        for i, arg in enumerate(args):
    
    129
    +            if arg in ('-c', '--config'):
    
    130
    +                try:
    
    131
    +                    config = args[i + 1]
    
    132
    +                except IndexError:
    
    133
    +                    pass
    
    122 134
         ctx.load(config)
    
    123 135
     
    
    124 136
         # element targets are valid artifact names
    
    ... ... @@ -128,8 +140,9 @@ def complete_artifact(args, incomplete):
    128 140
         return complete_list
    
    129 141
     
    
    130 142
     
    
    131
    -def override_completions(cmd, cmd_param, args, incomplete):
    
    143
    +def override_completions(orig_args, cmd, cmd_param, args, incomplete):
    
    132 144
         """
    
    145
    +    :param orig_args: original, non-completion args
    
    133 146
         :param cmd_param: command definition
    
    134 147
         :param args: full list of args typed before the incomplete arg
    
    135 148
         :param incomplete: the incomplete text to autocomplete
    
    ... ... @@ -150,7 +163,7 @@ def override_completions(cmd, cmd_param, args, incomplete):
    150 163
                     cmd_param.opts == ['--track-except']):
    
    151 164
                 return complete_target(args, incomplete)
    
    152 165
             if cmd_param.name == 'artifacts':
    
    153
    -            return complete_artifact(args, incomplete)
    
    166
    +            return complete_artifact(orig_args, args, incomplete)
    
    154 167
     
    
    155 168
         raise CompleteUnhandled()
    
    156 169
     
    
    ... ... @@ -161,7 +174,7 @@ def override_main(self, args=None, prog_name=None, complete_var=None,
    161 174
         # Hook for the Bash completion.  This only activates if the Bash
    
    162 175
         # completion is actually enabled, otherwise this is quite a fast
    
    163 176
         # noop.
    
    164
    -    if main_bashcomplete(self, prog_name, override_completions):
    
    177
    +    if main_bashcomplete(self, prog_name, partial(override_completions, args)):
    
    165 178
     
    
    166 179
             # If we're running tests we cant just go calling exit()
    
    167 180
             # from the main process.
    

  • buildstream/_scheduler/queues/buildqueue.py
    ... ... @@ -71,9 +71,6 @@ class BuildQueue(Queue):
    71 71
             return element._assemble()
    
    72 72
     
    
    73 73
         def status(self, element):
    
    74
    -        # state of dependencies may have changed, recalculate element state
    
    75
    -        element._update_state()
    
    76
    -
    
    77 74
             if not element._is_required():
    
    78 75
                 # Artifact is not currently required but it may be requested later.
    
    79 76
                 # Keep it in the queue.
    

  • buildstream/_scheduler/queues/fetchqueue.py
    ... ... @@ -44,9 +44,6 @@ class FetchQueue(Queue):
    44 44
             element._fetch()
    
    45 45
     
    
    46 46
         def status(self, element):
    
    47
    -        # state of dependencies may have changed, recalculate element state
    
    48
    -        element._update_state()
    
    49
    -
    
    50 47
             if not element._is_required():
    
    51 48
                 # Artifact is not currently required but it may be requested later.
    
    52 49
                 # Keep it in the queue.
    

  • buildstream/_scheduler/queues/pullqueue.py
    ... ... @@ -39,9 +39,6 @@ class PullQueue(Queue):
    39 39
                 raise SkipJob(self.action_name)
    
    40 40
     
    
    41 41
         def status(self, element):
    
    42
    -        # state of dependencies may have changed, recalculate element state
    
    43
    -        element._update_state()
    
    44
    -
    
    45 42
             if not element._is_required():
    
    46 43
                 # Artifact is not currently required but it may be requested later.
    
    47 44
                 # Keep it in the queue.
    

  • buildstream/element.py
    ... ... @@ -197,6 +197,7 @@ class Element(Plugin):
    197 197
     
    
    198 198
             self.__runtime_dependencies = []        # Direct runtime dependency Elements
    
    199 199
             self.__build_dependencies = []          # Direct build dependency Elements
    
    200
    +        self.__reverse_build_dependencies = []  # Direct reverse dependency Elements
    
    200 201
             self.__sources = []                     # List of Sources
    
    201 202
             self.__weak_cache_key = None            # Our cached weak cache key
    
    202 203
             self.__strict_cache_key = None          # Our cached cache key for strict builds
    
    ... ... @@ -439,6 +440,16 @@ class Element(Plugin):
    439 440
             if should_yield and (recurse or recursed) and scope != Scope.BUILD:
    
    440 441
                 yield self
    
    441 442
     
    
    443
    +    def reverse_build_dependencies(self):
    
    444
    +        def recurse_rdeps(element):
    
    445
    +            yield element
    
    446
    +
    
    447
    +            for rdep in element.__reverse_build_dependencies:
    
    448
    +                yield from recurse_rdeps(rdep)
    
    449
    +
    
    450
    +        for rdep in self.__reverse_build_dependencies:
    
    451
    +            yield from recurse_rdeps(rdep)
    
    452
    +
    
    442 453
         def search(self, scope, name):
    
    443 454
             """Search for a dependency by name
    
    444 455
     
    
    ... ... @@ -930,6 +941,7 @@ class Element(Plugin):
    930 941
             for meta_dep in meta.build_dependencies:
    
    931 942
                 dependency = Element._new_from_meta(meta_dep)
    
    932 943
                 element.__build_dependencies.append(dependency)
    
    944
    +            dependency.__reverse_build_dependencies.append(element)
    
    933 945
     
    
    934 946
             return element
    
    935 947
     
    
    ... ... @@ -1306,6 +1318,9 @@ class Element(Plugin):
    1306 1318
     
    
    1307 1319
             self._update_state()
    
    1308 1320
     
    
    1321
    +        for reverse_dep in self.reverse_build_dependencies():
    
    1322
    +            reverse_dep._update_state()
    
    1323
    +
    
    1309 1324
         # _track():
    
    1310 1325
         #
    
    1311 1326
         # Calls track() on the Element sources
    
    ... ... @@ -1503,6 +1518,9 @@ class Element(Plugin):
    1503 1518
             self._update_state()
    
    1504 1519
     
    
    1505 1520
             if self._get_workspace() and self._cached_success():
    
    1521
    +            for rdep in self.reverse_build_dependencies():
    
    1522
    +                rdep._update_state()
    
    1523
    +
    
    1506 1524
                 assert utils._is_main_process(), \
    
    1507 1525
                     "Attempted to save workspace configuration from child process"
    
    1508 1526
                 #
    

  • tests/completions/completions.py
    ... ... @@ -281,3 +281,44 @@ def test_argument_element_invalid(datafiles, cli, project, cmd, word_idx, expect
    281 281
     ])
    
    282 282
     def test_help_commands(cli, cmd, word_idx, expected):
    
    283 283
         assert_completion(cli, cmd, word_idx, expected)
    
    284
    +
    
    285
    +
    
    286
    +@pytest.mark.datafiles(os.path.join(DATA_DIR, 'project'))
    
    287
    +def test_argument_artifact(cli, tmpdir, datafiles):
    
    288
    +    project = os.path.join(datafiles.dirname, datafiles.basename)
    
    289
    +
    
    290
    +    # Build an import element with no dependencies (as there will only be ONE cache key)
    
    291
    +    result = cli.run(project=project, args=['build', 'import-bin.bst'])  # Has no dependencies
    
    292
    +    result.assert_success()
    
    293
    +
    
    294
    +    # Get the key and the artifact ref ($project/$element_name/$key)
    
    295
    +    key = cli.get_element_key(project, 'import-bin.bst')
    
    296
    +    artifact = os.path.join('test', 'import-bin', key)
    
    297
    +
    
    298
    +    # Test autocompletion of the artifact
    
    299
    +    cmds = [
    
    300
    +        'bst artifact log ',
    
    301
    +        'bst artifact log t',
    
    302
    +        'bst artifact log test/'
    
    303
    +    ]
    
    304
    +
    
    305
    +    for i, cmd in enumerate(cmds):
    
    306
    +        word_idx = 3
    
    307
    +        result = cli.run(project=project, cwd=project, env={
    
    308
    +            '_BST_COMPLETION': 'complete',
    
    309
    +            'COMP_WORDS': cmd,
    
    310
    +            'COMP_CWORD': str(word_idx)
    
    311
    +        })
    
    312
    +        words = []
    
    313
    +        if result.output:
    
    314
    +            words = result.output.splitlines()  # This leaves an extra space on each e.g. ['foo.bst ']
    
    315
    +            words = [word.strip() for word in words]
    
    316
    +
    
    317
    +            if i == 0:
    
    318
    +                expected = PROJECT_ELEMENTS + [artifact]  # We should now be able to see the artifact
    
    319
    +            elif i == 1:
    
    320
    +                expected = ['target.bst', artifact]
    
    321
    +            elif i == 2:
    
    322
    +                expected = [artifact]
    
    323
    +
    
    324
    +            assert expected == words



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