Daniel Silverstone pushed to branch danielsilverstone-ct/further-optimisations at BuildStream / buildstream
Commits:
-
9b6c18e4
by Chandan Singh at 2019-02-12T10:20:52Z
-
126bc006
by Chandan Singh at 2019-02-12T10:23:44Z
-
dbce3434
by Chandan Singh at 2019-02-12T12:19:57Z
-
24d29a17
by Javier Jardón at 2019-02-12T12:27:42Z
-
80dcf65d
by Javier Jardón at 2019-02-12T12:27:42Z
-
58b84905
by Javier Jardón at 2019-02-12T12:27:42Z
-
95d9b9ae
by Javier Jardón at 2019-02-12T13:31:56Z
-
a39c4767
by Daniel Silverstone at 2019-02-12T15:12:30Z
-
cda03313
by Daniel Silverstone at 2019-02-12T15:12:30Z
-
b6f08e1b
by Daniel Silverstone at 2019-02-12T15:12:30Z
-
69ee11c6
by Daniel Silverstone at 2019-02-12T15:12:30Z
-
0928e570
by Daniel Silverstone at 2019-02-12T15:12:30Z
27 changed files:
- .gitlab-ci.yml
- buildstream/_context.py
- buildstream/_frontend/cli.py
- buildstream/_frontend/widget.py
- buildstream/_yaml.py
- man/bst-artifact-checkout.1
- man/bst-artifact-log.1
- man/bst-artifact-pull.1
- man/bst-artifact-push.1
- man/bst-artifact-server.1
- man/bst-artifact.1
- man/bst-build.1
- man/bst-help.1
- man/bst-init.1
- man/bst-shell.1
- man/bst-show.1
- man/bst-source-checkout.1
- man/bst-source-fetch.1
- man/bst-source-track.1
- man/bst-source.1
- man/bst-workspace-close.1
- man/bst-workspace-list.1
- man/bst-workspace-open.1
- man/bst-workspace-reset.1
- man/bst-workspace.1
- man/bst.1
- tests/frontend/show.py
Changes:
... | ... | @@ -53,26 +53,20 @@ tests-fedora-28: |
53 | 53 |
image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:28-master-46405991
|
54 | 54 |
<<: *tests
|
55 | 55 |
|
56 |
-tests-ubuntu-18.04:
|
|
57 |
- image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-ubuntu:18.04-master-46405991
|
|
56 |
+tests-fedora-29:
|
|
57 |
+ image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:29-master-47052095
|
|
58 | 58 |
<<: *tests
|
59 | 59 |
|
60 |
-tests-python-3.7-stretch:
|
|
61 |
- image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-python:3.7-stretch-master-46405991
|
|
60 |
+tests-ubuntu-18.04:
|
|
61 |
+ image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-ubuntu:18.04-master-46405991
|
|
62 | 62 |
<<: *tests
|
63 | 63 |
|
64 |
- variables:
|
|
65 |
- # Note that we explicitly specify TOXENV in this case because this
|
|
66 |
- # image has both 3.6 and 3.7 versions. python3.6 cannot be removed because
|
|
67 |
- # some of our base dependencies declare it as their runtime dependency.
|
|
68 |
- TOXENV: py37
|
|
69 |
- |
|
70 | 64 |
tests-centos-7.6:
|
71 | 65 |
<<: *tests
|
72 | 66 |
image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-centos:7.6.1810-master-46405991
|
73 | 67 |
|
74 |
-overnight-fedora-28-aarch64:
|
|
75 |
- image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:aarch64-28-master-46405991
|
|
68 |
+overnight-fedora-29-aarch64:
|
|
69 |
+ image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:aarch64-29-master-47052095
|
|
76 | 70 |
tags:
|
77 | 71 |
- aarch64
|
78 | 72 |
<<: *tests
|
... | ... | @@ -91,7 +85,7 @@ overnight-fedora-28-aarch64: |
91 | 85 |
tests-unix:
|
92 | 86 |
# Use fedora here, to a) run a test on fedora and b) ensure that we
|
93 | 87 |
# can get rid of ostree - this is not possible with debian-8
|
94 |
- image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:28-master-46405991
|
|
88 |
+ image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:29-master-47052095
|
|
95 | 89 |
<<: *tests
|
96 | 90 |
variables:
|
97 | 91 |
BST_FORCE_BACKEND: "unix"
|
... | ... | @@ -109,7 +103,7 @@ tests-unix: |
109 | 103 |
|
110 | 104 |
tests-fedora-missing-deps:
|
111 | 105 |
# Ensure that tests behave nicely while missing bwrap and ostree
|
112 |
- image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:28-master-46405991
|
|
106 |
+ image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:29-master-47052095
|
|
113 | 107 |
<<: *tests
|
114 | 108 |
|
115 | 109 |
script:
|
... | ... | @@ -128,7 +122,7 @@ tests-fedora-update-deps: |
128 | 122 |
# Check if the tests pass after updating requirements to their latest
|
129 | 123 |
# allowed version.
|
130 | 124 |
allow_failure: true
|
131 |
- image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:28-master-46405991
|
|
125 |
+ image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:29-master-47052095
|
|
132 | 126 |
<<: *tests
|
133 | 127 |
|
134 | 128 |
script:
|
... | ... | @@ -289,6 +283,7 @@ coverage: |
289 | 283 |
dependencies:
|
290 | 284 |
- tests-debian-9
|
291 | 285 |
- tests-fedora-28
|
286 |
+ - tests-fedora-29
|
|
292 | 287 |
- tests-fedora-missing-deps
|
293 | 288 |
- tests-ubuntu-18.04
|
294 | 289 |
- tests-unix
|
... | ... | @@ -361,14 +361,17 @@ class Context(): |
361 | 361 |
# (bool): Whether or not to use strict build plan
|
362 | 362 |
#
|
363 | 363 |
def get_strict(self):
|
364 |
+ if self._strict_build_plan is None:
|
|
365 |
+ # Either we're not overridden or we've never worked it out before
|
|
366 |
+ # so work out if we should be strict, and then cache the result
|
|
367 |
+ toplevel = self.get_toplevel_project()
|
|
368 |
+ overrides = self.get_overrides(toplevel.name)
|
|
369 |
+ self._strict_build_plan = _yaml.node_get(overrides, bool, 'strict', default_value=True)
|
|
364 | 370 |
|
365 | 371 |
# If it was set by the CLI, it overrides any config
|
366 |
- if self._strict_build_plan is not None:
|
|
367 |
- return self._strict_build_plan
|
|
368 |
- |
|
369 |
- toplevel = self.get_toplevel_project()
|
|
370 |
- overrides = self.get_overrides(toplevel.name)
|
|
371 |
- return _yaml.node_get(overrides, bool, 'strict', default_value=True)
|
|
372 |
+ # Ditto if we've already computed this, then we return the computed
|
|
373 |
+ # value which we cache here too.
|
|
374 |
+ return self._strict_build_plan
|
|
372 | 375 |
|
373 | 376 |
# get_cache_key():
|
374 | 377 |
#
|
... | ... | @@ -440,6 +440,9 @@ def show(app, elements, deps, except_, order, format_): |
440 | 440 |
%{public} Public domain data
|
441 | 441 |
%{workspaced} If the element is workspaced
|
442 | 442 |
%{workspace-dirs} A list of workspace directories
|
443 |
+ %{deps} A list of all dependencies
|
|
444 |
+ %{build-deps} A list of build dependencies
|
|
445 |
+ %{runtime-deps} A list of runtime dependencies
|
|
443 | 446 |
|
444 | 447 |
The value of the %{symbol} without the leading '%' character is understood
|
445 | 448 |
as a pythonic formatting string, so python formatting features apply,
|
... | ... | @@ -27,7 +27,7 @@ from ruamel import yaml |
27 | 27 |
import click
|
28 | 28 |
|
29 | 29 |
from . import Profile
|
30 |
-from .. import Element, Consistency
|
|
30 |
+from .. import Element, Consistency, Scope
|
|
31 | 31 |
from .. import _yaml
|
32 | 32 |
from .. import __version__ as bst_version
|
33 | 33 |
from .._exceptions import ImplError
|
... | ... | @@ -435,6 +435,27 @@ class LogLine(Widget): |
435 | 435 |
line = p.fmt_subst(
|
436 | 436 |
line, 'workspace-dirs', '')
|
437 | 437 |
|
438 |
+ # Dependencies
|
|
439 |
+ if "%{deps" in format_:
|
|
440 |
+ deps = [e.name for e in element.dependencies(Scope.ALL, recurse=False)]
|
|
441 |
+ line = p.fmt_subst(
|
|
442 |
+ line, 'deps',
|
|
443 |
+ yaml.safe_dump(deps, default_style=None).rstrip('\n'))
|
|
444 |
+ |
|
445 |
+ # Build Dependencies
|
|
446 |
+ if "%{build-deps" in format_:
|
|
447 |
+ build_deps = [e.name for e in element.dependencies(Scope.BUILD, recurse=False)]
|
|
448 |
+ line = p.fmt_subst(
|
|
449 |
+ line, 'build-deps',
|
|
450 |
+ yaml.safe_dump(build_deps, default_style=False).rstrip('\n'))
|
|
451 |
+ |
|
452 |
+ # Runtime Dependencies
|
|
453 |
+ if "%{runtime-deps" in format_:
|
|
454 |
+ runtime_deps = [e.name for e in element.dependencies(Scope.RUN, recurse=False)]
|
|
455 |
+ line = p.fmt_subst(
|
|
456 |
+ line, 'runtime-deps',
|
|
457 |
+ yaml.safe_dump(runtime_deps, default_style=False).rstrip('\n'))
|
|
458 |
+ |
|
438 | 459 |
report += line + '\n'
|
439 | 460 |
|
440 | 461 |
return report.rstrip('\n')
|
... | ... | @@ -365,8 +365,8 @@ _sentinel = object() |
365 | 365 |
#
|
366 | 366 |
def node_get(node, expected_type, key, indices=None, *, default_value=_sentinel, allow_none=False):
|
367 | 367 |
value = node.get(key, default_value)
|
368 |
- provenance = node_get_provenance(node)
|
|
369 | 368 |
if value is _sentinel:
|
369 |
+ provenance = node_get_provenance(node)
|
|
370 | 370 |
raise LoadError(LoadErrorReason.INVALID_DATA,
|
371 | 371 |
"{}: Dictionary did not contain expected key '{}'".format(provenance, key))
|
372 | 372 |
|
... | ... | @@ -914,6 +914,10 @@ RoundTripRepresenter.add_representer(SanitizedDict, |
914 | 914 |
SafeRepresenter.represent_dict)
|
915 | 915 |
|
916 | 916 |
|
917 |
+# Types we can short-circuit in node_sanitize for speed.
|
|
918 |
+__SANITIZE_SHORT_CIRCUIT_TYPES = (int, float, str, bool, tuple)
|
|
919 |
+ |
|
920 |
+ |
|
917 | 921 |
# node_sanitize()
|
918 | 922 |
#
|
919 | 923 |
# Returnes an alphabetically ordered recursive copy
|
... | ... | @@ -922,9 +926,21 @@ RoundTripRepresenter.add_representer(SanitizedDict, |
922 | 926 |
# Only dicts are ordered, list elements are left in order.
|
923 | 927 |
#
|
924 | 928 |
def node_sanitize(node):
|
929 |
+ # Short-circuit None which occurs ca. twice per element
|
|
930 |
+ if node is None:
|
|
931 |
+ return node
|
|
932 |
+ |
|
933 |
+ node_type = type(node)
|
|
934 |
+ # Next short-circuit integers, floats, strings, booleans, and tuples
|
|
935 |
+ if node_type in __SANITIZE_SHORT_CIRCUIT_TYPES:
|
|
936 |
+ return node
|
|
937 |
+ # Now short-circuit lists. Note this is only for the raw list
|
|
938 |
+ # type, CommentedSeq and others get caught later.
|
|
939 |
+ elif node_type is list:
|
|
940 |
+ return [node_sanitize(elt) for elt in node]
|
|
925 | 941 |
|
926 |
- if isinstance(node, collections.abc.Mapping):
|
|
927 |
- |
|
942 |
+ # Finally ChainMap and dict, and other Mappings need special handling
|
|
943 |
+ if node_type in (dict, ChainMap) or isinstance(node, collections.Mapping):
|
|
928 | 944 |
result = SanitizedDict()
|
929 | 945 |
|
930 | 946 |
key_list = [key for key, _ in node_items(node)]
|
... | ... | @@ -932,10 +948,12 @@ def node_sanitize(node): |
932 | 948 |
result[key] = node_sanitize(node[key])
|
933 | 949 |
|
934 | 950 |
return result
|
935 |
- |
|
951 |
+ # Catch the case of CommentedSeq and friends. This is more rare and so
|
|
952 |
+ # we keep complexity down by still using isinstance here.
|
|
936 | 953 |
elif isinstance(node, list):
|
937 | 954 |
return [node_sanitize(elt) for elt in node]
|
938 | 955 |
|
956 |
+ # Everything else (such as commented scalars) just gets returned as-is.
|
|
939 | 957 |
return node
|
940 | 958 |
|
941 | 959 |
|
... | ... | @@ -1064,15 +1082,52 @@ class ChainMap(collections.ChainMap): |
1064 | 1082 |
return default
|
1065 | 1083 |
|
1066 | 1084 |
|
1085 |
+# Node copying
|
|
1086 |
+#
|
|
1087 |
+# Unfortunately we copy nodes a *lot* and `isinstance()` is super-slow when
|
|
1088 |
+# things from collections.abc get involved. The result is the following
|
|
1089 |
+# intricate but substantially faster group of tuples and the use of `in`.
|
|
1090 |
+#
|
|
1091 |
+# If any of the {node,list}_{chain_,}_copy routines raise a ValueError
|
|
1092 |
+# then it's likely additional types need adding to these tuples.
|
|
1093 |
+ |
|
1094 |
+# When chaining a copy, these types are skipped since the ChainMap will
|
|
1095 |
+# retrieve them from the source node when needed. Other copiers might copy
|
|
1096 |
+# them, so we call them __QUICK_TYPES.
|
|
1097 |
+__QUICK_TYPES = (str, bool,
|
|
1098 |
+ yaml.scalarstring.PreservedScalarString,
|
|
1099 |
+ yaml.scalarstring.SingleQuotedScalarString,
|
|
1100 |
+ yaml.scalarstring.DoubleQuotedScalarString)
|
|
1101 |
+ |
|
1102 |
+# These types have to be iterated like a dictionary
|
|
1103 |
+__DICT_TYPES = (dict, ChainMap, yaml.comments.CommentedMap)
|
|
1104 |
+ |
|
1105 |
+# These types have to be iterated like a list
|
|
1106 |
+__LIST_TYPES = (list, yaml.comments.CommentedSeq)
|
|
1107 |
+ |
|
1108 |
+# These are the provenance types, which have to be cloned rather than any other
|
|
1109 |
+# copying tactic.
|
|
1110 |
+__PROVENANCE_TYPES = (Provenance, DictProvenance, MemberProvenance, ElementProvenance)
|
|
1111 |
+ |
|
1112 |
+# These are the directives used to compose lists, we need this because it's
|
|
1113 |
+# slightly faster during the node_final_assertions checks
|
|
1114 |
+__NODE_ASSERT_COMPOSITION_DIRECTIVES = ('(>)', '(<)', '(=)')
|
|
1115 |
+ |
|
1116 |
+ |
|
1067 | 1117 |
def node_chain_copy(source):
|
1068 | 1118 |
copy = ChainMap({}, source)
|
1069 | 1119 |
for key, value in source.items():
|
1070 |
- if isinstance(value, collections.abc.Mapping):
|
|
1120 |
+ value_type = type(value)
|
|
1121 |
+ if value_type in __DICT_TYPES:
|
|
1071 | 1122 |
copy[key] = node_chain_copy(value)
|
1072 |
- elif isinstance(value, list):
|
|
1123 |
+ elif value_type in __LIST_TYPES:
|
|
1073 | 1124 |
copy[key] = list_chain_copy(value)
|
1074 |
- elif isinstance(value, Provenance):
|
|
1125 |
+ elif value_type in __PROVENANCE_TYPES:
|
|
1075 | 1126 |
copy[key] = value.clone()
|
1127 |
+ elif value_type in __QUICK_TYPES:
|
|
1128 |
+ pass # No need to copy these, the chainmap deals with it
|
|
1129 |
+ else:
|
|
1130 |
+ raise ValueError("Unable to be quick about node_chain_copy of {}".format(value_type))
|
|
1076 | 1131 |
|
1077 | 1132 |
return copy
|
1078 | 1133 |
|
... | ... | @@ -1080,14 +1135,17 @@ def node_chain_copy(source): |
1080 | 1135 |
def list_chain_copy(source):
|
1081 | 1136 |
copy = []
|
1082 | 1137 |
for item in source:
|
1083 |
- if isinstance(item, collections.abc.Mapping):
|
|
1138 |
+ item_type = type(item)
|
|
1139 |
+ if item_type in __DICT_TYPES:
|
|
1084 | 1140 |
copy.append(node_chain_copy(item))
|
1085 |
- elif isinstance(item, list):
|
|
1141 |
+ elif item_type in __LIST_TYPES:
|
|
1086 | 1142 |
copy.append(list_chain_copy(item))
|
1087 |
- elif isinstance(item, Provenance):
|
|
1143 |
+ elif item_type in __PROVENANCE_TYPES:
|
|
1088 | 1144 |
copy.append(item.clone())
|
1089 |
- else:
|
|
1145 |
+ elif item_type in __QUICK_TYPES:
|
|
1090 | 1146 |
copy.append(item)
|
1147 |
+ else: # Fallback
|
|
1148 |
+ raise ValueError("Unable to be quick about list_chain_copy of {}".format(item_type))
|
|
1091 | 1149 |
|
1092 | 1150 |
return copy
|
1093 | 1151 |
|
... | ... | @@ -1095,14 +1153,17 @@ def list_chain_copy(source): |
1095 | 1153 |
def node_copy(source):
|
1096 | 1154 |
copy = {}
|
1097 | 1155 |
for key, value in source.items():
|
1098 |
- if isinstance(value, collections.abc.Mapping):
|
|
1156 |
+ value_type = type(value)
|
|
1157 |
+ if value_type in __DICT_TYPES:
|
|
1099 | 1158 |
copy[key] = node_copy(value)
|
1100 |
- elif isinstance(value, list):
|
|
1159 |
+ elif value_type in __LIST_TYPES:
|
|
1101 | 1160 |
copy[key] = list_copy(value)
|
1102 |
- elif isinstance(value, Provenance):
|
|
1161 |
+ elif value_type in __PROVENANCE_TYPES:
|
|
1103 | 1162 |
copy[key] = value.clone()
|
1104 |
- else:
|
|
1163 |
+ elif value_type in __QUICK_TYPES:
|
|
1105 | 1164 |
copy[key] = value
|
1165 |
+ else:
|
|
1166 |
+ raise ValueError("Unable to be quick about node_copy of {}".format(value_type))
|
|
1106 | 1167 |
|
1107 | 1168 |
ensure_provenance(copy)
|
1108 | 1169 |
|
... | ... | @@ -1112,14 +1173,17 @@ def node_copy(source): |
1112 | 1173 |
def list_copy(source):
|
1113 | 1174 |
copy = []
|
1114 | 1175 |
for item in source:
|
1115 |
- if isinstance(item, collections.abc.Mapping):
|
|
1176 |
+ item_type = type(item)
|
|
1177 |
+ if item_type in __DICT_TYPES:
|
|
1116 | 1178 |
copy.append(node_copy(item))
|
1117 |
- elif isinstance(item, list):
|
|
1179 |
+ elif item_type in __LIST_TYPES:
|
|
1118 | 1180 |
copy.append(list_copy(item))
|
1119 |
- elif isinstance(item, Provenance):
|
|
1181 |
+ elif item_type in __PROVENANCE_TYPES:
|
|
1120 | 1182 |
copy.append(item.clone())
|
1121 |
- else:
|
|
1183 |
+ elif item_type in __QUICK_TYPES:
|
|
1122 | 1184 |
copy.append(item)
|
1185 |
+ else:
|
|
1186 |
+ raise ValueError("Unable to be quick about list_copy of {}".format(item_type))
|
|
1123 | 1187 |
|
1124 | 1188 |
return copy
|
1125 | 1189 |
|
... | ... | @@ -1142,22 +1206,26 @@ def node_final_assertions(node): |
1142 | 1206 |
# indicates that the user intended to override a list which
|
1143 | 1207 |
# never existed in the underlying data
|
1144 | 1208 |
#
|
1145 |
- if key in ['(>)', '(<)', '(=)']:
|
|
1209 |
+ if key in __NODE_ASSERT_COMPOSITION_DIRECTIVES:
|
|
1146 | 1210 |
provenance = node_get_provenance(node, key)
|
1147 | 1211 |
raise LoadError(LoadErrorReason.TRAILING_LIST_DIRECTIVE,
|
1148 | 1212 |
"{}: Attempt to override non-existing list".format(provenance))
|
1149 | 1213 |
|
1150 |
- if isinstance(value, collections.abc.Mapping):
|
|
1214 |
+ value_type = type(value)
|
|
1215 |
+ |
|
1216 |
+ if value_type in __DICT_TYPES:
|
|
1151 | 1217 |
node_final_assertions(value)
|
1152 |
- elif isinstance(value, list):
|
|
1218 |
+ elif value_type in __LIST_TYPES:
|
|
1153 | 1219 |
list_final_assertions(value)
|
1154 | 1220 |
|
1155 | 1221 |
|
1156 | 1222 |
def list_final_assertions(values):
|
1157 | 1223 |
for value in values:
|
1158 |
- if isinstance(value, collections.abc.Mapping):
|
|
1224 |
+ value_type = type(value)
|
|
1225 |
+ |
|
1226 |
+ if value_type in __DICT_TYPES:
|
|
1159 | 1227 |
node_final_assertions(value)
|
1160 |
- elif isinstance(value, list):
|
|
1228 |
+ elif value_type in __LIST_TYPES:
|
|
1161 | 1229 |
list_final_assertions(value)
|
1162 | 1230 |
|
1163 | 1231 |
|
1 |
-.TH "BST ARTIFACT CHECKOUT" "1" "24-Jan-2019" "" "bst artifact checkout Manual"
|
|
1 |
+.TH "BST ARTIFACT CHECKOUT" "1" "12-Feb-2019" "" "bst artifact checkout Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-artifact\-checkout \- Checkout contents of an artifact
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST ARTIFACT LOG" "1" "24-Jan-2019" "" "bst artifact log Manual"
|
|
1 |
+.TH "BST ARTIFACT LOG" "1" "12-Feb-2019" "" "bst artifact log Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-artifact\-log \- Show logs of an artifact
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST ARTIFACT PULL" "1" "24-Jan-2019" "" "bst artifact pull Manual"
|
|
1 |
+.TH "BST ARTIFACT PULL" "1" "12-Feb-2019" "" "bst artifact pull Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-artifact\-pull \- Pull a built artifact
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST ARTIFACT PUSH" "1" "24-Jan-2019" "" "bst artifact push Manual"
|
|
1 |
+.TH "BST ARTIFACT PUSH" "1" "12-Feb-2019" "" "bst artifact push Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-artifact\-push \- Push a built artifact
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST-ARTIFACT-SERVER" "1" "24-Jan-2019" "" "bst-artifact-server Manual"
|
|
1 |
+.TH "BST-ARTIFACT-SERVER" "1" "12-Feb-2019" "" "bst-artifact-server Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst-artifact-server \- CAS Artifact Server
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST ARTIFACT" "1" "24-Jan-2019" "" "bst artifact Manual"
|
|
1 |
+.TH "BST ARTIFACT" "1" "12-Feb-2019" "" "bst artifact Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-artifact \- Manipulate cached artifacts
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST BUILD" "1" "24-Jan-2019" "" "bst build Manual"
|
|
1 |
+.TH "BST BUILD" "1" "12-Feb-2019" "" "bst build Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-build \- Build elements in a pipeline
|
4 | 4 |
.SH SYNOPSIS
|
... | ... | @@ -32,3 +32,6 @@ Allow tracking to cross junction boundaries |
32 | 32 |
.TP
|
33 | 33 |
\fB\-\-track\-save\fP
|
34 | 34 |
Deprecated: This is ignored
|
35 |
+.TP
|
|
36 |
+\fB\-r,\fP \-\-remote TEXT
|
|
37 |
+The URL of the remote cache (defaults to the first configured cache)
|
1 |
-.TH "BST HELP" "1" "24-Jan-2019" "" "bst help Manual"
|
|
1 |
+.TH "BST HELP" "1" "12-Feb-2019" "" "bst help Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-help \- Print usage information
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST INIT" "1" "24-Jan-2019" "" "bst init Manual"
|
|
1 |
+.TH "BST INIT" "1" "12-Feb-2019" "" "bst init Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-init \- Initialize a new BuildStream project
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST SHELL" "1" "24-Jan-2019" "" "bst shell Manual"
|
|
1 |
+.TH "BST SHELL" "1" "12-Feb-2019" "" "bst shell Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-shell \- Shell into an element's sandbox environment
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST SHOW" "1" "24-Jan-2019" "" "bst show Manual"
|
|
1 |
+.TH "BST SHOW" "1" "12-Feb-2019" "" "bst show Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-show \- Show elements in the pipeline
|
4 | 4 |
.SH SYNOPSIS
|
... | ... | @@ -43,6 +43,9 @@ the following symbols can be used in the format string: |
43 | 43 |
%{public} Public domain data
|
44 | 44 |
%{workspaced} If the element is workspaced
|
45 | 45 |
%{workspace-dirs} A list of workspace directories
|
46 |
+ %{deps} A list of all dependencies
|
|
47 |
+ %{build-deps} A list of build dependencies
|
|
48 |
+ %{runtime-deps} A list of runtime dependencies
|
|
46 | 49 |
.PP
|
47 | 50 |
The value of the %{symbol} without the leading '%' character is understood
|
48 | 51 |
as a pythonic formatting string, so python formatting features apply,
|
1 |
-.TH "BST SOURCE CHECKOUT" "1" "24-Jan-2019" "" "bst source checkout Manual"
|
|
1 |
+.TH "BST SOURCE CHECKOUT" "1" "12-Feb-2019" "" "bst source checkout Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-source\-checkout \- Checkout sources for an element
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST SOURCE FETCH" "1" "24-Jan-2019" "" "bst source fetch Manual"
|
|
1 |
+.TH "BST SOURCE FETCH" "1" "12-Feb-2019" "" "bst source fetch Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-source\-fetch \- Fetch sources in a pipeline
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST SOURCE TRACK" "1" "24-Jan-2019" "" "bst source track Manual"
|
|
1 |
+.TH "BST SOURCE TRACK" "1" "12-Feb-2019" "" "bst source track Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-source\-track \- Track new source references
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST SOURCE" "1" "24-Jan-2019" "" "bst source Manual"
|
|
1 |
+.TH "BST SOURCE" "1" "12-Feb-2019" "" "bst source Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-source \- Manipulate sources for an element
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST WORKSPACE CLOSE" "1" "24-Jan-2019" "" "bst workspace close Manual"
|
|
1 |
+.TH "BST WORKSPACE CLOSE" "1" "12-Feb-2019" "" "bst workspace close Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-workspace\-close \- Close workspaces
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST WORKSPACE LIST" "1" "24-Jan-2019" "" "bst workspace list Manual"
|
|
1 |
+.TH "BST WORKSPACE LIST" "1" "12-Feb-2019" "" "bst workspace list Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-workspace\-list \- List open workspaces
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST WORKSPACE OPEN" "1" "24-Jan-2019" "" "bst workspace open Manual"
|
|
1 |
+.TH "BST WORKSPACE OPEN" "1" "12-Feb-2019" "" "bst workspace open Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-workspace\-open \- Open a new workspace
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST WORKSPACE RESET" "1" "24-Jan-2019" "" "bst workspace reset Manual"
|
|
1 |
+.TH "BST WORKSPACE RESET" "1" "12-Feb-2019" "" "bst workspace reset Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-workspace\-reset \- Reset a workspace to its original state
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST WORKSPACE" "1" "24-Jan-2019" "" "bst workspace Manual"
|
|
1 |
+.TH "BST WORKSPACE" "1" "12-Feb-2019" "" "bst workspace Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst\-workspace \- Manipulate developer workspaces
|
4 | 4 |
.SH SYNOPSIS
|
1 |
-.TH "BST" "1" "24-Jan-2019" "" "bst Manual"
|
|
1 |
+.TH "BST" "1" "12-Feb-2019" "" "bst Manual"
|
|
2 | 2 |
.SH NAME
|
3 | 3 |
bst \- Build and manipulate BuildStream projects...
|
4 | 4 |
.SH SYNOPSIS
|
... | ... | @@ -400,3 +400,28 @@ def test_exceed_max_recursion_depth(cli, tmpdir, dependency_depth): |
400 | 400 |
assert result.exit_code == -1
|
401 | 401 |
|
402 | 402 |
shutil.rmtree(project_path)
|
403 |
+ |
|
404 |
+ |
|
405 |
+###############################################################
|
|
406 |
+# Testing format symbols #
|
|
407 |
+###############################################################
|
|
408 |
+@pytest.mark.datafiles(os.path.join(DATA_DIR, 'project'))
|
|
409 |
+@pytest.mark.parametrize("dep_kind, expected_deps", [
|
|
410 |
+ ('%{deps}', '[import-dev.bst, import-bin.bst]'),
|
|
411 |
+ ('%{build-deps}', '[import-dev.bst]'),
|
|
412 |
+ ('%{runtime-deps}', '[import-bin.bst]')
|
|
413 |
+])
|
|
414 |
+def test_format_deps(cli, datafiles, dep_kind, expected_deps):
|
|
415 |
+ project = os.path.join(datafiles.dirname, datafiles.basename)
|
|
416 |
+ target = 'checkout-deps.bst'
|
|
417 |
+ result = cli.run(project=project, silent=True, args=[
|
|
418 |
+ 'show',
|
|
419 |
+ '--deps', 'none',
|
|
420 |
+ '--format', '%{name}: ' + dep_kind,
|
|
421 |
+ target])
|
|
422 |
+ result.assert_success()
|
|
423 |
+ |
|
424 |
+ expected = '{name}: {deps}'.format(name=target, deps=expected_deps)
|
|
425 |
+ if result.output.strip() != expected:
|
|
426 |
+ raise AssertionError("Expected output:\n{}\nInstead received output:\n{}"
|
|
427 |
+ .format(expected, result.output))
|