From cc123cad99e441fc395a14584804e7ee8fafba96 Mon Sep 17 00:00:00 2001 From: Sergio Schvezov Date: Fri, 16 Dec 2016 07:23:11 +0200 Subject: [PATCH] pluginhandler: build scriptlet support (#988) LP: #1642371 Signed-off-by: Sergio Schvezov --- .vscode/launch.json | 33 +++++++++++++++++++ .../snaps/scriptlet-build/Makefile | 7 ++++ .../snaps/scriptlet-build/snapcraft.yaml | 17 ++++++++++ integration_tests/test_scriptlets.py | 21 +++++++----- schema/snapcraft.yaml | 3 ++ snapcraft/__init__.py | 14 ++++++++ snapcraft/internal/pluginhandler/__init__.py | 6 +++- units.py | 4 +++ 8 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 integration_tests/snaps/scriptlet-build/Makefile create mode 100644 integration_tests/snaps/scriptlet-build/snapcraft.yaml create mode 100644 units.py diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..eefcfc3b06 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,33 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Python", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config.python.pythonPath}", + "program": "${file}", + "cwd": "${workspaceRoot}", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + }, + { + "name": "Unit Test", + "type": "python", + "request": "launch", + "stopOnEntry": false, + "pythonPath": "${config.python.pythonPath}", + "program": "${workspaceRoot}/units.py", + "cwd": "${workspaceRoot}", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + } + ] +} \ No newline at end of file diff --git a/integration_tests/snaps/scriptlet-build/Makefile b/integration_tests/snaps/scriptlet-build/Makefile new file mode 100644 index 0000000000..f02586f476 --- /dev/null +++ b/integration_tests/snaps/scriptlet-build/Makefile @@ -0,0 +1,7 @@ +# -*- Mode: Makefile; indent-tabs-mode:t; tab-width: 4 -*- + +build: + touch build-build + +move-to-dest: + touch $(DESTDIR)/build-install diff --git a/integration_tests/snaps/scriptlet-build/snapcraft.yaml b/integration_tests/snaps/scriptlet-build/snapcraft.yaml new file mode 100644 index 0000000000..06a6fecfdb --- /dev/null +++ b/integration_tests/snaps/scriptlet-build/snapcraft.yaml @@ -0,0 +1,17 @@ +name: build-scriptlet-test +version: '0.1' +summary: Runs the build scriptlet for a part +description: | + Runs the shell script defined in `build` overriding the plugins + build directives. + +grade: devel +confinement: devmode + +parts: + build-scriptlet-test: + source: . + plugin: make + build: | + make build + make move-to-dest DESTDIR=$SNAPCRAFT_PART_INSTALL diff --git a/integration_tests/test_scriptlets.py b/integration_tests/test_scriptlets.py index 87147a6ad2..e03793ea44 100644 --- a/integration_tests/test_scriptlets.py +++ b/integration_tests/test_scriptlets.py @@ -29,16 +29,21 @@ def test_prepare_scriptlet(self): installdir = os.path.join( project_dir, 'parts', 'prepare-scriptlet-test', 'install') - prepared_file_path = os.path.join(installdir, 'prepared') + touch_file_path = os.path.join(installdir, 'prepared') + self.assertThat(touch_file_path, FileExists()) - installdir = os.path.join( - project_dir, 'parts', 'prepare-and-install', 'install') - built_file_path = os.path.join(installdir, 'built') - installed_file_path = os.path.join(installdir, 'installed') + def test_build_scriptlet(self): + project_dir = 'scriptlet-build' + self.run_snapcraft('build', project_dir) - self.assertThat(prepared_file_path, FileExists()) - self.assertThat(built_file_path, FileExists()) - self.assertThat(installed_file_path, FileExists()) + partdir = os.path.join(project_dir, 'parts', 'build-scriptlet-test') + builddir = os.path.join(partdir, 'build') + installdir = os.path.join(partdir, 'install') + + touch_file_path = os.path.join(builddir, 'build-build') + self.assertThat(touch_file_path, FileExists()) + touch_file_path = os.path.join(installdir, 'build-install') + self.assertThat(touch_file_path, FileExists()) def test_install_scriptlet(self): project_dir = 'scriptlet-install' diff --git a/schema/snapcraft.yaml b/schema/snapcraft.yaml index d12cf2557a..eb4880ee1f 100644 --- a/schema/snapcraft.yaml +++ b/schema/snapcraft.yaml @@ -210,6 +210,9 @@ properties: install: type: string default: '' + build: + type: string + default: '' prepare: type: string default: '' diff --git a/snapcraft/__init__.py b/snapcraft/__init__.py index e09b6e985c..f505581a3e 100644 --- a/snapcraft/__init__.py +++ b/snapcraft/__init__.py @@ -237,6 +237,20 @@ cd scripts ./bootstrap.sh + - build: shell script + + If present, the shell script defined here is run instead of the `build` + step of the plugin. The working directory is the base build directory + for the given part. The defined script is run with `/bin/sh`. + + For example: + + plugin: make + build: | + make project + make test + make special-install + - install: shell script If present, the shell script defined here is run after the `build` step diff --git a/snapcraft/internal/pluginhandler/__init__.py b/snapcraft/internal/pluginhandler/__init__.py index 58e47cf292..265562f7fa 100644 --- a/snapcraft/internal/pluginhandler/__init__.py +++ b/snapcraft/internal/pluginhandler/__init__.py @@ -390,7 +390,11 @@ def ignore(directory, files): script_runner = ScriptRunner(builddir=self.code.build_basedir) script_runner.run(scriptlet=self._part_properties.get('prepare')) - self.code.build() + build_scriptlet = self._part_properties.get('build') + if build_scriptlet: + script_runner.run(scriptlet=build_scriptlet) + else: + self.code.build() script_runner.run(scriptlet=self._part_properties.get('install')) self.mark_build_done() diff --git a/units.py b/units.py new file mode 100644 index 0000000000..a80e21f063 --- /dev/null +++ b/units.py @@ -0,0 +1,4 @@ +import unittest + +unittest.main('snapcraft.tests.pluginhandler.test_scriptlets', + argv=['ScriptletsTestCase']) # noqa \ No newline at end of file