diff options
author | Jonathan Maw <jonathan.maw@codethink.co.uk> | 2018-02-26 17:54:04 +0000 |
---|---|---|
committer | Jonathan Maw <jonathan.maw@codethink.co.uk> | 2018-03-01 17:27:28 +0000 |
commit | b884fe14956ed004f3fb5d1a101dc594d01a56c4 (patch) | |
tree | 2251f01afa3b458a5fa83eacdaa0e5817304fe04 | |
parent | 42de997e993fb1f97b2f2f8e873294e8a7055f79 (diff) | |
download | buildstream-b884fe14956ed004f3fb5d1a101dc594d01a56c4.tar.gz |
Add Filter element
-rw-r--r-- | buildstream/plugins/elements/filter.py | 104 | ||||
-rw-r--r-- | buildstream/plugins/elements/filter.yaml | 29 | ||||
-rw-r--r-- | doc/source/main_authoring.rst | 1 |
3 files changed, 134 insertions, 0 deletions
diff --git a/buildstream/plugins/elements/filter.py b/buildstream/plugins/elements/filter.py new file mode 100644 index 000000000..b6d82e1f3 --- /dev/null +++ b/buildstream/plugins/elements/filter.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018 Codethink Limited +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see <http://www.gnu.org/licenses/>. +# +# Authors: +# Jonathan Maw <jonathan.maw@codethink.co.uk> + +"""Filter element + +This element copies a subset of the files in its dependencies. + +This is normally used to separate out the contents of an artifact +into multiple artifacts and define separate sets of dependencies, +in cases where a build produces multiple discrete "packages", +e.g. systemd and udev; gettext and libintl. + +This element expects precisely one build dependency, and multiple +runtime dependencies that are not the element that was the build +dependency. + +The default configuration and possible options are as such: + .. literalinclude:: ../../../buildstream/plugins/elements/filter.yaml + :language: yaml +""" + +from buildstream import Element, ElementError, Scope + + +class FilterElement(Element): + + # The filter element's output is it's dependencies, so + # we must rebuild if the dependencies change even when + # not in strict build plans. + BST_STRICT_REBUILD = True + + # This element ignores sources, so we should forbid them from being + # added, to reduce the potential for confusion + BST_FORBID_SOURCES = True + + def configure(self, node): + self.node_validate(node, [ + 'include', 'exclude', 'include-orphans' + ]) + + self.include = self.node_get_member(node, list, 'include') + self.exclude = self.node_get_member(node, list, 'exclude') + self.include_orphans = self.node_get_member(node, bool, 'include-orphans') + + def preflight(self): + # Exactly one build-depend is permitted + build_deps = list(self.dependencies(Scope.BUILD, recurse=False)) + if len(build_deps) != 1: + detail = "Full list of build-depends:\n" + detail += " \n".join([x.name for x in build_deps]) + raise ElementError("{}: {} element must have exactly 1 build-dependency, actually have {}" + .format(self, type(self).__name__, len(build_deps)), + detail=detail, reason="filter-bdepend-wrong-count") + + # That build-depend must not also be a runtime-depend + runtime_deps = list(self.dependencies(Scope.RUN, recurse=False)) + if build_deps[0] in runtime_deps: + detail = "Full list of runtime depends:\n" + detail += " \n".join([x.name for x in runtime_deps]) + raise ElementError("{}: {} element's build dependency must not also be a runtime dependency" + .format(self, type(self).__name__), + detail=detail, reason="filter-bdepend-also-rdepend") + + def get_unique_key(self): + key = { + 'include': sorted(self.include), + 'exclude': sorted(self.exclude), + 'orphans': self.include_orphans, + } + return key + + def configure_sandbox(self, sandbox): + pass + + def stage(self, sandbox): + pass + + def assemble(self, sandbox): + with self.timed_activity("Staging artifact", silent_nested=True): + for dep in self.dependencies(Scope.BUILD): + dep.stage_artifact(sandbox, include=self.include, + exclude=self.exclude, orphans=self.include_orphans) + return "" + + +def setup(): + return FilterElement diff --git a/buildstream/plugins/elements/filter.yaml b/buildstream/plugins/elements/filter.yaml new file mode 100644 index 000000000..627a00cce --- /dev/null +++ b/buildstream/plugins/elements/filter.yaml @@ -0,0 +1,29 @@ + +# Filter element configuration +config: + + # A list of domains to include from each artifact, as + # they were defined in the element's 'split-rules'. + # + # Since domains can be added, it is not an error to + # specify domains which may not exist for all of the + # elements in this composition. + # + # The default empty list indicates that all domains + # from each dependency should be included. + # + include: [] + + # A list of domains to exclude from each artifact, as + # they were defined in the element's 'split-rules'. + # + # In the case that a file is spoken for by a domain + # in the 'include' list and another in the 'exclude' + # list, then the file will be excluded. + exclude: [] + + # Whether to include orphan files which are not + # included by any of the 'split-rules' present on + # a given element. + # + include-orphans: False diff --git a/doc/source/main_authoring.rst b/doc/source/main_authoring.rst index 73d37f4d0..f23bfb7c1 100644 --- a/doc/source/main_authoring.rst +++ b/doc/source/main_authoring.rst @@ -57,6 +57,7 @@ General Elements * :mod:`compose <elements.compose>` - Compose the output of multiple elements * :mod:`script <elements.script>` - Run scripts to create output * :mod:`junction <elements.junction>` - Integrate subprojects +* :mod:`filter <elements.filter>` - Extract a subset of files from another element Build Elements |