summaryrefslogtreecommitdiff
path: root/src/buildstream/plugins/elements/import.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/buildstream/plugins/elements/import.py')
-rw-r--r--src/buildstream/plugins/elements/import.py129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/buildstream/plugins/elements/import.py b/src/buildstream/plugins/elements/import.py
new file mode 100644
index 000000000..61e353dbc
--- /dev/null
+++ b/src/buildstream/plugins/elements/import.py
@@ -0,0 +1,129 @@
+#
+# Copyright (C) 2016 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:
+# Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
+
+"""
+import - Import sources directly
+================================
+Import elements produce artifacts directly from its sources
+without any kind of processing. These are typically used to
+import an SDK to build on top of or to overlay your build with
+some configuration data.
+
+The empty configuration is as such:
+ .. literalinclude:: ../../../src/buildstream/plugins/elements/import.yaml
+ :language: yaml
+"""
+
+import os
+from buildstream import Element, ElementError
+
+
+# Element implementation for the 'import' kind.
+class ImportElement(Element):
+ # pylint: disable=attribute-defined-outside-init
+
+ # This plugin has been modified to avoid the use of Sandbox.get_directory
+ BST_VIRTUAL_DIRECTORY = True
+
+ # Import elements do not run any commands
+ BST_RUN_COMMANDS = False
+
+ def configure(self, node):
+ self.node_validate(node, [
+ 'source', 'target'
+ ])
+
+ self.source = self.node_subst_member(node, 'source')
+ self.target = self.node_subst_member(node, 'target')
+
+ def preflight(self):
+ # Assert that we have at least one source to fetch.
+
+ sources = list(self.sources())
+ if not sources:
+ raise ElementError("{}: An import element must have at least one source.".format(self))
+
+ def get_unique_key(self):
+ return {
+ 'source': self.source,
+ 'target': self.target
+ }
+
+ def configure_sandbox(self, sandbox):
+ pass
+
+ def stage(self, sandbox):
+ pass
+
+ def assemble(self, sandbox):
+
+ # Stage sources into the input directory
+ # Do not mount workspaces as the files are copied from outside the sandbox
+ self._stage_sources_in_sandbox(sandbox, 'input', mount_workspaces=False)
+
+ rootdir = sandbox.get_virtual_directory()
+ inputdir = rootdir.descend('input')
+ outputdir = rootdir.descend('output', create=True)
+
+ # The directory to grab
+ inputdir = inputdir.descend(*self.source.strip(os.sep).split(os.sep))
+
+ # The output target directory
+ outputdir = outputdir.descend(*self.target.strip(os.sep).split(os.sep), create=True)
+
+ if inputdir.is_empty():
+ raise ElementError("{}: No files were found inside directory '{}'"
+ .format(self, self.source))
+
+ # Move it over
+ outputdir.import_files(inputdir)
+
+ # And we're done
+ return '/output'
+
+ def generate_script(self):
+ build_root = self.get_variable('build-root')
+ install_root = self.get_variable('install-root')
+ commands = []
+
+ # The directory to grab
+ inputdir = os.path.join(build_root, self.normal_name, self.source.lstrip(os.sep))
+ inputdir = inputdir.rstrip(os.sep)
+
+ # The output target directory
+ outputdir = os.path.join(install_root, self.target.lstrip(os.sep))
+ outputdir = outputdir.rstrip(os.sep)
+
+ # Ensure target directory parent exists but target directory doesn't
+ commands.append("mkdir -p {}".format(os.path.dirname(outputdir)))
+ commands.append("[ ! -e {outputdir} ] || rmdir {outputdir}".format(outputdir=outputdir))
+
+ # Move it over
+ commands.append("mv {} {}".format(inputdir, outputdir))
+
+ script = ""
+ for cmd in commands:
+ script += "(set -ex; {}\n) || exit 1\n".format(cmd)
+
+ return script
+
+
+# Plugin entry point
+def setup():
+ return ImportElement