Benjamin Schubert pushed to branch bschubert/pipeline at BuildStream / buildstream
Commits:
-
542cdaf0
by Jürg Billeter at 2019-01-14T18:46:57Z
-
ff666e76
by James Ennis at 2019-01-14T18:46:57Z
-
273b0f55
by Tristan Van Berkom at 2019-01-14T20:24:57Z
-
2e3c2ea2
by Javier Jardón at 2019-01-14T22:26:04Z
-
d60d2e31
by Javier Jardón at 2019-01-15T00:39:22Z
-
605836c1
by Chandan Singh at 2019-01-15T00:57:05Z
-
006370af
by Chandan Singh at 2019-01-15T01:21:33Z
-
2028d982
by Benjamin Schubert at 2019-01-15T10:35:06Z
-
7ed23936
by Benjamin Schubert at 2019-01-15T10:35:45Z
7 changed files:
- .gitlab-ci.yml
- buildstream/_frontend/cli.py
- buildstream/_scheduler/queues/buildqueue.py
- buildstream/_scheduler/queues/fetchqueue.py
- buildstream/_scheduler/queues/pullqueue.py
- buildstream/element.py
- tests/completions/completions.py
Changes:
... | ... | @@ -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 |
- |
|
... | ... | @@ -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.
|
... | ... | @@ -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.
|
... | ... | @@ -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.
|
... | ... | @@ -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.
|
... | ... | @@ -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 |
#
|
... | ... | @@ -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
|