Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 108-integration-tests-not-idempotent-and-self-contained
  • 131-behavior-of-except-argument-is-frustrating-and-confusing
  • 132-loading-external-plugins-works-without-explicit-requirement-in-project-conf
  • 135-expire-artifacts-in-local-cache
  • 135-expire-artifacts-in-local-cache-clean
  • 138-aborting-bst-push-command-causes-stack-trace-3
  • 142-potentially-printing-provenance-more-than-once-in-loaderrors
  • 188-trigger-external-commands-on-certain-events
  • 214-filter-workspacing-rework
  • 218-allow-specifying-the-chroot-binary-to-use-for-sandboxes-on-unix-platforms
  • 239-use-pylint-for-linting
  • 372-allow-queues-to-run-auxilliary-jobs-after-an-element-s-job-finishes
  • 380-untagged-bst
  • 463-make-dependency-type-default-to-build
  • 537-mirror-fallback-does-not-work-for-git
  • 64-clarify-about-plugins-importing-other-plugins
  • 716-add-example-with-build-directory-outside-of-source-directory
  • 716-add-example-with-build-directory-outside-of-source-directory-2
  • 81-non-empty-read-only-directories-not-handled-during-bst-build-and-others
  • BenjaminSchubert/fix-quota-tests
  • Qinusty/235-manifest
  • Qinusty/397
  • Qinusty/470-bst-track-yaml-indent
  • Qinusty/553-backport-1.2
  • Qinusty/663-missing-cache-key-workspace-open
  • Qinusty/backport-576
  • Qinusty/backport-skipped-562
  • Qinusty/gitlab-ci
  • Qinusty/gitlab-ci-duration
  • Qinusty/message-helpers
  • Qinusty/pytest_cache_gitignore
  • abderrahim/cached-failure
  • abderrahim/cachekey-strictrebuild
  • abderrahim/cleanup-speedup
  • abderrahim/makemaker
  • abderrahim/resolve-remotes
  • abderrahim/source-cache
  • abderrahim/stage-artifact-scriptelement
  • abderrahim/virtual-extract
  • adamjones/contributing
  • adamjones/contribution-guide
  • aevri/assert_no_unexpected_size_writes
  • aevri/casdprocessmanager2
  • aevri/check_spawn_ci_working
  • aevri/enable_spawn_ci_4
  • aevri/enable_spawn_ci_6
  • aevri/enable_spawn_ci_7
  • aevri/json_artifact_meta
  • aevri/picklable_jobs
  • aevri/plugin_venvs
  • aevri/provenance_scope
  • aevri/pylint_ignore_argsdiff
  • aevri/safe_noninteractive
  • aevri/win32
  • aevri/win32_minimal
  • aevri/win32_minimal_seemstowork_20190829
  • aevri/win32_receive_signals
  • aevri/win32_temptext
  • alexfazakas/add-bst-init-argument
  • alexfazakas/use-merge-trains
  • always-do-linting
  • another-segfault
  • becky/locally_downloaded_files
  • becky/shell_launch_errors
  • bschubert/add-isolated-tests
  • bschubert/isort
  • bschubert/merge-parent-child-job
  • bschubert/more-mypy
  • bschubert/no-multiprocessing-bak
  • bschubert/no-multiprocessing-full
  • bschubert/optimize-deps
  • bschubert/optimize-element-init
  • bschubert/optimize-loader-sorting
  • bschubert/optimize-mapping-node
  • bschubert/optimize-splits
  • bschubert/remove-multiline-switch-for-re
  • bschubert/remove-parent-child-pipe
  • bschubert/remove-pip-source
  • bschubert/standardize-source-tests
  • bschubert/test-plugins
  • bschubert/update-coverage
  • bst-1
  • bst-1.0
  • bst-1.2
  • bst-1.4
  • bst-pull
  • bst-push
  • buildbox-pre-will
  • cache-key-v0
  • caching_build_trees
  • cascache_timeouts
  • chandan/automate-pypi-release
  • chandan/cli-deps
  • chandan/contrib-dependencies
  • chandan/element-cache
  • chandan/enums
  • chandan/extras-require
  • chandan/macos-multiprocessing
  • chandan/moar-parallelism
  • chandan/moar-runners
  • 1.0.0
  • 1.0.1
  • 1.1.0
  • 1.1.1
  • 1.1.2
  • 1.1.3
  • 1.1.4
  • 1.1.5
  • 1.1.6
  • 1.1.7
  • 1.2.0
  • 1.2.1
  • 1.2.2
  • 1.2.3
  • 1.2.4
  • 1.2.5
  • 1.2.6
  • 1.2.7
  • 1.2.8
  • 1.3.0
  • 1.3.1
  • 1.4.0
  • 1.4.1
  • 1.4.2
  • 1.4.3
  • 1.5.0
  • 1.5.1
  • 1.6.0
  • 1.6.1
  • 1.91.0
  • 1.91.1
  • 1.91.2
  • 1.91.3
  • 1.93.0
  • 1.93.1
  • 1.93.2
  • 1.93.3
  • 1.93.4
  • 1.93.5
  • CROSS_PLATFORM_SEPT_2017
  • PRE_CAS_MERGE_JULY_2018
  • bst-1-branchpoint
  • bst-1.2-branchpoint
  • bst-1.4-branchpoint
144 results

Target

Select target project
  • willsalmon/buildstream
  • CumHoleZH/buildstream
  • tchaik/buildstream
  • DCotyPortfolio/buildstream
  • jesusoctavioas/buildstream
  • patrickmmartin/buildstream
  • franred/buildstream
  • tintou/buildstream
  • alatiera/buildstream
  • martinblanchard/buildstream
  • neverdie22042524/buildstream
  • Mattlk13/buildstream
  • PServers/buildstream
  • phamnghia610909/buildstream
  • chiaratolentino/buildstream
  • eysz7-x-x/buildstream
  • kerrick1/buildstream
  • matthew-yates/buildstream
  • twofeathers/buildstream
  • mhadjimichael/buildstream
  • pointswaves/buildstream
  • Mr.JackWilson/buildstream
  • Tw3akG33k/buildstream
  • AlexFazakas/buildstream
  • eruidfkiy/buildstream
  • clamotion2/buildstream
  • nanonyme/buildstream
  • wickyjaaa/buildstream
  • nmanchev/buildstream
  • bojorquez.ja/buildstream
  • mostynb/buildstream
  • highpit74/buildstream
  • Demo112/buildstream
  • ba2014sheer/buildstream
  • tonimadrino/buildstream
  • usuario2o/buildstream
  • Angelika123456/buildstream
  • neo355/buildstream
  • corentin-ferlay/buildstream
  • coldtom/buildstream
  • wifitvbox81/buildstream
  • 358253885/buildstream
  • seanborg/buildstream
  • SotK/buildstream
  • DouglasWinship/buildstream
  • karansthr97/buildstream
  • louib/buildstream
  • bwh-ct/buildstream
  • robjh/buildstream
  • we88c0de/buildstream
  • zhengxian5555/buildstream
51 results
Select Git revision
  • 108-integration-tests-not-idempotent-and-self-contained
  • 131-behavior-of-except-argument-is-frustrating-and-confusing
  • 132-loading-external-plugins-works-without-explicit-requirement-in-project-conf
  • 135-expire-artifacts-in-local-cache
  • 135-expire-artifacts-in-local-cache-clean
  • 138-aborting-bst-push-command-causes-stack-trace-3
  • 142-potentially-printing-provenance-more-than-once-in-loaderrors
  • 188-trigger-external-commands-on-certain-events
  • 214-filter-workspacing-rework
  • 218-allow-specifying-the-chroot-binary-to-use-for-sandboxes-on-unix-platforms
  • 239-use-pylint-for-linting
  • 372-allow-queues-to-run-auxilliary-jobs-after-an-element-s-job-finishes
  • 380-untagged-bst
  • 463-make-dependency-type-default-to-build
  • 537-mirror-fallback-does-not-work-for-git
  • 64-clarify-about-plugins-importing-other-plugins
  • 716-add-example-with-build-directory-outside-of-source-directory
  • 716-add-example-with-build-directory-outside-of-source-directory-2
  • 81-non-empty-read-only-directories-not-handled-during-bst-build-and-others
  • BenjaminSchubert/fix-quota-tests
  • Qinusty/235-manifest
  • Qinusty/397
  • Qinusty/470-bst-track-yaml-indent
  • Qinusty/553-backport-1.2
  • Qinusty/663-missing-cache-key-workspace-open
  • Qinusty/backport-576
  • Qinusty/backport-skipped-562
  • Qinusty/gitlab-ci
  • Qinusty/gitlab-ci-duration
  • Qinusty/message-helpers
  • Qinusty/pytest_cache_gitignore
  • abderrahim/cached-failure
  • abderrahim/cachekey-strictrebuild
  • abderrahim/cleanup-speedup
  • abderrahim/makemaker
  • abderrahim/resolve-remotes
  • abderrahim/source-cache
  • abderrahim/stage-artifact-scriptelement
  • abderrahim/virtual-extract
  • adamjones/contributing
  • adamjones/contribution-guide
  • aevri/assert_no_unexpected_size_writes
  • aevri/casdprocessmanager2
  • aevri/check_spawn_ci_working
  • aevri/enable_spawn_ci_4
  • aevri/enable_spawn_ci_6
  • aevri/enable_spawn_ci_7
  • aevri/json_artifact_meta
  • aevri/picklable_jobs
  • aevri/plugin_venvs
  • aevri/provenance_scope
  • aevri/pylint_ignore_argsdiff
  • aevri/safe_noninteractive
  • aevri/win32
  • aevri/win32_minimal
  • aevri/win32_minimal_seemstowork_20190829
  • aevri/win32_receive_signals
  • aevri/win32_temptext
  • alexfazakas/add-bst-init-argument
  • alexfazakas/use-merge-trains
  • always-do-linting
  • another-segfault
  • becky/locally_downloaded_files
  • becky/shell_launch_errors
  • bschubert/add-isolated-tests
  • bschubert/isort
  • bschubert/merge-parent-child-job
  • bschubert/more-mypy
  • bschubert/no-multiprocessing-bak
  • bschubert/no-multiprocessing-full
  • bschubert/optimize-deps
  • bschubert/optimize-element-init
  • bschubert/optimize-loader-sorting
  • bschubert/optimize-mapping-node
  • bschubert/optimize-splits
  • bschubert/remove-multiline-switch-for-re
  • bschubert/remove-parent-child-pipe
  • bschubert/remove-pip-source
  • bschubert/standardize-source-tests
  • bschubert/test-plugins
  • bschubert/update-coverage
  • bst-1
  • bst-1.0
  • bst-1.2
  • bst-1.4
  • bst-pull
  • bst-push
  • buildbox-pre-will
  • cache-key-v0
  • caching_build_trees
  • cascache_timeouts
  • chandan/automate-pypi-release
  • chandan/cli-deps
  • chandan/contrib-dependencies
  • chandan/element-cache
  • chandan/enums
  • chandan/extras-require
  • chandan/macos-multiprocessing
  • chandan/moar-parallelism
  • chandan/moar-runners
  • 1.0.0
  • 1.0.1
  • 1.1.0
  • 1.1.1
  • 1.1.2
  • 1.1.3
  • 1.1.4
  • 1.1.5
  • 1.1.6
  • 1.1.7
  • 1.2.0
  • 1.2.1
  • 1.2.2
  • 1.2.3
  • 1.2.4
  • 1.2.5
  • 1.2.6
  • 1.2.7
  • 1.2.8
  • 1.3.0
  • 1.3.1
  • 1.4.0
  • 1.4.1
  • 1.4.2
  • 1.4.3
  • 1.5.0
  • 1.5.1
  • 1.6.0
  • 1.6.1
  • 1.91.0
  • 1.91.1
  • 1.91.2
  • 1.91.3
  • 1.93.0
  • 1.93.1
  • 1.93.2
  • 1.93.3
  • 1.93.4
  • 1.93.5
  • CROSS_PLATFORM_SEPT_2017
  • PRE_CAS_MERGE_JULY_2018
  • bst-1-branchpoint
  • bst-1.2-branchpoint
  • bst-1.4-branchpoint
144 results
Show changes
Commits on Source (8)
Showing
with 173 additions and 16 deletions
......@@ -370,6 +370,7 @@ Dependency dictionary:
- filename: foo.bst
type: build
junction: baseproject.bst
strict: false
Attributes:
......@@ -400,6 +401,16 @@ Attributes:
The ``junction`` attribute is available since :ref:`format version 1 <project_format_version>`
* ``strict``
This attribute can be used to specify that this element should
be rebuilt when the dependency changes, even when
:ref:`strict mode <user_config_strict_mode>` has been turned off.
This is appropriate whenever a dependency's output is consumed
verbatim in the output of the depending element, for instance
when static linking is in use.
Cross-junction dependencies
~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
......@@ -201,6 +201,8 @@ configuration will be used as fallback.
instance-name: main
.. _user_config_strict_mode:
Strict build plan
~~~~~~~~~~~~~~~~~
The strict build plan option decides whether you want elements
......
......@@ -39,18 +39,21 @@ cdef int _next_synthetic_counter():
# A link from a LoadElement to its dependencies.
#
# Keeps a link to one of the current Element's dependencies, together with
# its dependency type.
# its dependency attributes.
#
# Args:
# element (LoadElement): a LoadElement on which there is a dependency
# dep_type (str): the type of dependency this dependency link is
# strict (bint): whether the dependency is strict
cdef class Dependency:
cdef readonly LoadElement element
cdef readonly str dep_type
cdef readonly bint strict
def __cinit__(self, LoadElement element, str dep_type):
def __cinit__(self, LoadElement element, str dep_type, bint strict):
self.element = element
self.dep_type = dep_type
self.strict = strict
# LoadElement():
......
......@@ -124,7 +124,7 @@ class Loader():
dummy_target = LoadElement(Node.from_dict({}), "", self)
# Pylint is not very happy with Cython and can't understand 'dependencies' is a list
dummy_target.dependencies.extend( # pylint: disable=no-member
Dependency(element, Symbol.RUNTIME)
Dependency(element, Symbol.RUNTIME, False)
for element in target_elements
)
......@@ -344,7 +344,7 @@ class Loader():
# All is well, push the dependency onto the LoadElement
# Pylint is not very happy with Cython and can't understand 'dependencies' is a list
current_element[0].dependencies.append( # pylint: disable=no-member
Dependency(dep_element, dep.dep_type))
Dependency(dep_element, dep.dep_type, dep.strict))
else:
# We do not have any more dependencies to load for this
# element on the queue, report any invalid dep names
......@@ -499,6 +499,8 @@ class Loader():
meta_element.build_dependencies.append(meta_dep)
if dep.dep_type != 'build':
meta_element.dependencies.append(meta_dep)
if dep.strict:
meta_element.strict_dependencies.append(meta_dep)
element.meta_done = True
......
......@@ -56,5 +56,6 @@ class MetaElement():
self.sandbox = sandbox or Node.from_dict({})
self.build_dependencies = []
self.dependencies = []
self.strict_dependencies = []
self.first_pass = first_pass
self.is_junction = kind == "junction"
......@@ -44,6 +44,7 @@ class Symbol():
DIRECTORY = "directory"
JUNCTION = "junction"
SANDBOX = "sandbox"
STRICT = "strict"
# Dependency()
......@@ -63,6 +64,7 @@ cdef class Dependency:
cdef public str name
cdef public str dep_type
cdef public str junction
cdef public bint strict
def __init__(self,
Node dep,
......@@ -75,13 +77,14 @@ cdef class Dependency:
self.name = dep.as_str()
self.dep_type = default_dep_type
self.junction = None
self.strict = False
elif type(dep) is MappingNode:
if default_dep_type:
(<MappingNode> dep).validate_keys(['filename', 'junction'])
(<MappingNode> dep).validate_keys(['filename', 'junction', 'strict'])
dep_type = default_dep_type
else:
(<MappingNode> dep).validate_keys(['filename', 'type', 'junction'])
(<MappingNode> dep).validate_keys(['filename', 'type', 'junction', 'strict'])
# Make type optional, for this we set it to None
dep_type = (<MappingNode> dep).get_str(<str> Symbol.TYPE, None)
......@@ -95,11 +98,32 @@ cdef class Dependency:
self.name = (<MappingNode> dep).get_str(<str> Symbol.FILENAME)
self.dep_type = dep_type
self.junction = (<MappingNode> dep).get_str(<str> Symbol.JUNCTION, None)
self.strict = (<MappingNode> dep).get_bool(<str> Symbol.STRICT, False)
# Here we disallow explicitly setting 'strict' to False.
#
# This is in order to keep the door open to allowing the project.conf
# set the default of dependency 'strict'-ness which might be useful
# for projects which use mostly static linking and the like, in which
# case we can later interpret explicitly non-strict dependencies
# as an override of the project default.
#
if self.strict == False and Symbol.STRICT in dep:
provenance = dep.get_scalar(Symbol.STRICT).get_provenance()
raise LoadError("{}: Setting 'strict' to False is unsupported"
.format(provenance), LoadErrorReason.INVALID_DATA)
else:
raise LoadError("{}: Dependency is not specified as a string or a dictionary".format(self.provenance),
LoadErrorReason.INVALID_DATA)
# Only build dependencies are allowed to be strict
#
if self.strict and self.dep_type == Symbol.RUNTIME:
raise LoadError("{}: Runtime dependency {} specified as `strict`.".format(self.provenance, self.name),
LoadErrorReason.INVALID_DATA,
detail="Only dependencies required at build time may be declared `strict`.")
# `:` characters are not allowed in filename if a junction was
# explicitly specified
if self.junction and ':' in self.name:
......
......@@ -208,6 +208,7 @@ class Element(Plugin):
self.__runtime_dependencies = [] # Direct runtime dependency Elements
self.__build_dependencies = [] # Direct build dependency Elements
self.__strict_dependencies = [] # Direct build dependency subset which require strict rebuilds
self.__reverse_build_deps = set() # Direct reverse build dependency Elements
self.__reverse_runtime_deps = set() # Direct reverse runtime dependency Elements
self.__build_deps_without_strict_cache_key = None # Number of build dependencies without a strict key
......@@ -989,6 +990,10 @@ class Element(Plugin):
dependency = Element._new_from_meta(meta_dep, task)
element.__build_dependencies.append(dependency)
dependency.__reverse_build_deps.add(element)
if meta_dep in meta.strict_dependencies:
element.__strict_dependencies.append(dependency)
no_of_build_deps = len(element.__build_dependencies)
element.__build_deps_without_strict_cache_key = no_of_build_deps
element.__build_deps_without_cache_key = no_of_build_deps
......@@ -3107,17 +3112,22 @@ class Element(Plugin):
if self.__weak_cache_key is None:
# Calculate weak cache key
#
# Weak cache key includes names of direct build dependencies
# but does not include keys of dependencies.
if self.BST_STRICT_REBUILD:
dependencies = [
e._get_cache_key(strength=_KeyStrength.WEAK)
for e in self.dependencies(Scope.BUILD)
]
else:
dependencies = [
[e.project_name, e.name] for e in self.dependencies(Scope.BUILD, recurse=False)
]
# so as to only trigger rebuilds when the shape of the
# dependencies change.
#
# Some conditions cause dependencies to be strict, such
# that this element will be rebuilt anyway if the dependency
# changes even in non strict mode, for these cases we just
# encode the dependency's weak cache key instead of it's name.
#
dependencies = [
e._get_cache_key(strength=_KeyStrength.WEAK)
if self.BST_STRICT_REBUILD or e in self.__strict_dependencies
else [e.project_name, e.name]
for e in self.dependencies(Scope.BUILD)
]
self.__weak_cache_key = self._calculate_cache_key(dependencies)
......
......@@ -50,6 +50,20 @@ def test_invalid_dependency_type(cli, datafiles):
result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA)
@pytest.mark.datafiles(DATA_DIR)
def test_invalid_strict_dependency(cli, datafiles):
project = os.path.join(str(datafiles), 'dependencies1')
result = cli.run(project=project, args=['show', 'invalidstrict.bst'])
result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA)
@pytest.mark.datafiles(DATA_DIR)
def test_invalid_non_strict_dependency(cli, datafiles):
project = os.path.join(str(datafiles), 'dependencies1')
result = cli.run(project=project, args=['show', 'invalidnonstrict.bst'])
result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA)
@pytest.mark.datafiles(DATA_DIR)
def test_circular_dependency(cli, datafiles):
project = os.path.join(str(datafiles), 'dependencies1')
......
kind: manual
description: |
This is an invalid non strict dependency because it is
currently illegal to explicitly set a dependency to be
non-strict (even though this is the default).
depends:
- filename: firstdep.bst
strict: false
kind: manual
description: |
This is an invalid strict dependency because runtime
dependencies cannot be strict.
runtime-depends:
- filename: firstdep.bst
strict: true
......@@ -560,3 +560,57 @@ def test_max_jobs(cli, datafiles, cli_value, config_value):
else:
# Check that we got the explicitly set value
assert loaded_value == int(expected_value)
# This tests that cache keys behave as expected when
# dependencies have been specified as `strict` and
# when building in strict mode.
#
# This test will:
#
# * Build the target once (and assert that it is cached)
# * Modify some local files which are imported
# by an import element which the target depends on
# * Assert that the cached state of the target element
# is as expected
#
# We run the test twice, once with an element which strict
# depends on the changing import element, and one which
# depends on it regularly.
#
@pytest.mark.datafiles(os.path.join(DATA_DIR, 'strict-depends'))
@pytest.mark.parametrize("target, expected_state", [
("non-strict-depends.bst", "cached"),
("strict-depends.bst", "waiting"),
])
def test_strict_dependencies(cli, datafiles, target, expected_state):
project = str(datafiles)
# Configure non strict mode, this will have
# an effect on the build and the `bst show`
# commands run via cli.get_element_states()
cli.configure({
'projects': {
'test': {
'strict': False
}
}
})
result = cli.run(project=project, silent=True, args=['build', target])
result.assert_success()
states = cli.get_element_states(project, ['base.bst', target])
assert states['base.bst'] == 'cached'
assert states[target] == 'cached'
# Now modify the file, effectively causing the common base.bst
# dependency to change it's cache key
hello_path = os.path.join(project, 'files', 'hello.txt')
with open(hello_path, 'w') as f:
f.write("Goodbye")
# Now assert that we have the states we expect as a result
states = cli.get_element_states(project, ['base.bst', target])
assert states['base.bst'] == 'buildable'
assert states[target] == expected_state
kind: import
sources:
- kind: local
path: files
kind: stack
build-depends:
- base.bst
kind: stack
build-depends:
- filename: base.bst
strict: true
pony
name: test
element-path: elements