summaryrefslogtreecommitdiffstats
path: root/snap/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'snap/plugins')
-rw-r--r--snap/plugins/x-autotools-subsource.py66
-rw-r--r--snap/plugins/x-gyp-cmake.py100
-rw-r--r--snap/plugins/x-patched-python.py65
-rw-r--r--snap/plugins/x-qtbuilder.py204
4 files changed, 435 insertions, 0 deletions
diff --git a/snap/plugins/x-autotools-subsource.py b/snap/plugins/x-autotools-subsource.py
new file mode 100644
index 0000000000..330ea0b1b2
--- /dev/null
+++ b/snap/plugins/x-autotools-subsource.py
@@ -0,0 +1,66 @@
+# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
+#
+# Author: Marco Trevisan <marco@ubuntu.com>
+# Copyright (C) 2017-2018 Canonical Ltd
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3 as
+# published by the Free Software Foundation.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import snapcraft
+
+from snapcraft.internal import sources
+from snapcraft.plugins import autotools
+
+class Dict2Object(object):
+ def __init__(self, d):
+ for k, v in d.items():
+ setattr(self, k.replace('-', '_'), v)
+
+
+class AutotoolsSubsourcePlugin(autotools.AutotoolsPlugin):
+
+ @classmethod
+ def schema(cls):
+ schema = super().schema()
+
+ schema['properties']['sub-sources'] = {
+ 'type': 'array',
+ 'minitems': 0,
+ 'uniqueItems': True,
+ 'items': {
+ 'type': 'object',
+ 'additionalProperties': True,
+ },
+ 'default': [],
+ }
+
+ return schema
+
+ @classmethod
+ def get_pull_properties(cls):
+ return [
+ 'sub-sources',
+ ]
+
+ def pull(self):
+ super().pull()
+
+ for src in self.options.sub_sources:
+ [name] = src.keys()
+ [values] = src.values()
+
+ if 'source' in values:
+ dest = values['dest'] if 'dest' in values else ''
+ sources.get(os.path.join(self.sourcedir, dest),
+ os.path.join(self.build_basedir, dest),
+ Dict2Object(values))
diff --git a/snap/plugins/x-gyp-cmake.py b/snap/plugins/x-gyp-cmake.py
new file mode 100644
index 0000000000..94a5ba1a89
--- /dev/null
+++ b/snap/plugins/x-gyp-cmake.py
@@ -0,0 +1,100 @@
+# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
+#
+# Author: Marco Trevisan <marco@ubuntu.com>
+# Copyright (C) 2017-2018 Canonical Ltd
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3 as
+# published by the Free Software Foundation.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import snapcraft
+
+from snapcraft.plugins import cmake
+
+
+class GypCMakePlugin(cmake.CMakePlugin):
+ """A basic plugin for snapcraft that generates CMake files from gyp"""
+
+ @classmethod
+ def schema(cls):
+ schema = super().schema()
+
+ schema['properties']['gyp-file'] = {
+ 'type': 'string'
+ }
+
+ schema['properties']['build-type'] = {
+ 'type': 'string',
+ 'default': 'Release',
+ 'enum': ['Debug', 'Release'],
+ }
+
+ schema['properties']['environment'] = {
+ 'type': 'array',
+ 'minitems': 0,
+ 'uniqueItems': True,
+ 'items': {
+ 'type': 'object',
+ 'minitems': 0,
+ 'uniqueItems': True,
+ 'items': {
+ 'type': 'string',
+ },
+ },
+ 'default': [],
+ }
+
+ schema['required'].append('gyp-file')
+
+ schema['build-properties'].extend([
+ 'build-type',
+ 'gyp-file',
+ ])
+
+ return schema
+
+ def __init__(self, name, options, project):
+ super().__init__(name, options, project)
+ self.build_packages.extend([
+ 'binutils',
+ 'python',
+ ])
+ self.builddir = os.path.join(
+ self.build_basedir, 'out', self.options.build_type)
+
+ def build(self):
+ env = self._build_environment()
+ gyp_path = os.path.join(self.sourcedir, os.path.dirname(self.options.gyp_file))
+
+ for environ in self.options.environment:
+ [env_name] = list(environ)
+ env[env_name] = str(environ[env_name])
+
+ if not os.path.exists(os.path.join(self.builddir, 'CMakeLists.txt')):
+ gyp_command = ['gyp'] + self.options.configflags + ['--format=cmake']
+ gyp_command.append('--generator-output={}'.format(self.build_basedir))
+ gyp_command.append(os.path.basename(self.options.gyp_file))
+ self.run(gyp_command, cwd=gyp_path)
+
+ if not os.path.exists(os.path.join(self.builddir, 'Makefile')):
+ self.run(['cmake', '.'], env=env)
+
+ self.make(env=env)
+
+ if self.options.artifacts and self.options.build_type == 'Release':
+ for artifact in self.options.artifacts:
+ dest = os.path.join(self.installdir, artifact)
+ if os.path.isfile(dest):
+ mime_type = self.run_output(
+ 'file --mime-type -b {}'.format(dest).split())
+ if 'application/x-executable' in mime_type:
+ self.run(['strip', dest])
diff --git a/snap/plugins/x-patched-python.py b/snap/plugins/x-patched-python.py
new file mode 100644
index 0000000000..0444ac6676
--- /dev/null
+++ b/snap/plugins/x-patched-python.py
@@ -0,0 +1,65 @@
+# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
+#
+# Author: Marco Trevisan <marco@ubuntu.com>
+# Copyright (C) 2017-2018 Canonical Ltd
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3 as
+# published by the Free Software Foundation.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import snapcraft
+import requests
+
+from snapcraft.plugins import python
+
+class PatchedPythonPlugin(python.PythonPlugin):
+
+ @classmethod
+ def schema(cls):
+ schema = super().schema()
+
+ schema['properties']['patches'] = {
+ 'type': 'array',
+ 'minitems': 0,
+ 'uniqueItems': True,
+ 'items': {
+ 'type': 'string',
+ },
+ 'default': [],
+ }
+
+ schema['pull-properties'].extend([
+ 'patches',
+ ])
+
+ return schema
+
+ def pull(self):
+ super().pull()
+
+ for patch in self.options.patches:
+ patch_name = os.path.basename(patch)
+ patch_stamp = os.path.join(
+ self.sourcedir, '.snapcraft-patched-{}'.format(patch_name))
+
+ if not os.path.exists(patch_stamp):
+ if os.path.exists(patch):
+ patch_file = os.path.join(os.getcwd(), patch)
+ else:
+ patch_file = os.path.join(
+ self.sourcedir, 'snapcraft-patch-{}'.format(patch_name))
+ with open(patch_file, 'wb') as file:
+ file.write(requests.get(patch).content)
+
+ patch_cmd = 'git apply -v3 {}'.format(patch_file).split()
+ self.run(patch_cmd, cwd=self.sourcedir)
+ open(patch_stamp, 'a').close()
diff --git a/snap/plugins/x-qtbuilder.py b/snap/plugins/x-qtbuilder.py
new file mode 100644
index 0000000000..860cd448a4
--- /dev/null
+++ b/snap/plugins/x-qtbuilder.py
@@ -0,0 +1,204 @@
+# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
+#
+# Author: Marco Trevisan <marco@ubuntu.com>
+# Copyright (C) 2017-2018 Canonical Ltd
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3 as
+# published by the Free Software Foundation.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import shutil
+import snapcraft
+
+from snapcraft.plugins import make
+
+class QtBuilderPlugin(make.MakePlugin):
+
+ @classmethod
+ def schema(cls):
+ schema = super().schema()
+
+ schema['properties']['configflags'] = {
+ 'type': 'array',
+ 'minitems': 1,
+ 'uniqueItems': False,
+ 'items': {
+ 'type': 'string',
+ },
+ 'default': [],
+ }
+
+ schema['properties']['qt-source-git'] = {
+ 'type': 'string'
+ }
+
+ schema['properties']['qt-source-depth'] = {
+ 'type': 'integer',
+ 'default': 1
+ }
+
+ schema['properties']['qt-version'] = {
+ 'type': 'string'
+ }
+
+ schema['properties']['qt-patches-base-url'] = {
+ 'type': 'string'
+ }
+
+ schema['properties']['qt-patches-path'] = {
+ 'type': 'string'
+ }
+
+ schema['properties']['qt-submodules'] = {
+ 'type': 'array',
+ 'minitems': 0,
+ 'uniqueItems': True,
+ 'items': {
+ 'type': 'string',
+ },
+ 'default': [],
+ }
+
+ schema['properties']['qt-extra-plugins'] = {
+ 'type': 'array',
+ 'minitems': 0,
+ 'uniqueItems': True,
+ 'items': {
+ 'type': 'object',
+ 'minitems': 0,
+ 'uniqueItems': True,
+ 'items': {
+ 'type': 'string',
+ },
+ },
+ 'default': [],
+ }
+
+ schema['properties']['environment'] = {
+ 'type': 'array',
+ 'minitems': 0,
+ 'uniqueItems': True,
+ 'items': {
+ 'type': 'object',
+ 'minitems': 0,
+ 'uniqueItems': True,
+ 'items': {
+ 'type': 'string',
+ },
+ },
+ 'default': [],
+ }
+
+ schema['required'].append('qt-source-git')
+
+ schema['build-properties'].append('configflags')
+
+ return schema
+
+ @classmethod
+ def get_pull_properties(cls):
+ return [
+ 'qt-version',
+ 'qt-patches-base-url',
+ 'qt-patches-path',
+ 'qt-submodules',
+ 'qt-extra-plugins',
+ ]
+
+ def __init__(self, name, options, project):
+ super().__init__(name, options, project)
+ self.build_packages.extend(['g++', 'patch', 'perl', 'wget'])
+ self.options.source_depth = self.options.qt_source_depth
+
+ if self.options.qt_version:
+ if self.options.qt_version[0] == 'v':
+ self.options.source_branch = self.options.qt_version
+ self.options.qt_version = self.options.qt_version[1:]
+ else:
+ self.options.source_branch = '.'.join(
+ self.options.qt_version.split('.')[:-1])
+
+
+ def pull(self):
+ if not os.path.exists(os.path.join(self.sourcedir, '.git')) or \
+ not os.path.exists(os.path.join(self.sourcedir, 'init-repository')):
+ shutil.rmtree(self.sourcedir, ignore_errors=True)
+ command = 'git clone {} {}'.format(
+ self.options.qt_source_git, self.sourcedir).split()
+ if self.options.source_branch:
+ command.extend(['--branch', str(self.options.source_branch)])
+ if self.options.source_depth:
+ command.extend(['--depth', str(self.options.source_depth)])
+
+ self.run(command)
+
+ command = 'perl init-repository --branch -f'.split()
+ if len(self.options.qt_submodules):
+ command.extend('--module-subset={}'.format(
+ ','.join(self.options.qt_submodules)).split())
+ self.run(command, cwd=self.sourcedir)
+
+ if self.options.qt_version:
+ self.run("git submodule foreach git checkout v{}".format(
+ self.options.qt_version).split(), self.sourcedir)
+
+ patch_file_template = '${{name}}{}.diff'.format(
+ '_' + self.options.qt_version.replace('.', '_') \
+ if self.options.qt_version else '')
+
+ if self.options.qt_patches_base_url:
+ patch_uri_template = '{}/{}'.format(
+ self.options.qt_patches_base_url, patch_file_template)
+
+ patch_cmd = 'git submodule foreach -q'.split() + \
+ ['[ -e {touch_file} ] || ' \
+ 'wget -q -O - {patch_uri_template} | patch -p1 && ' \
+ 'touch {touch_file}'.format(
+ patch_uri_template=patch_uri_template,
+ touch_file='.snapcraft-qt-patched')]
+
+ self.run(patch_cmd, cwd=self.sourcedir)
+
+ if self.options.qt_patches_path:
+ patch_path_template = os.path.join(
+ os.getcwd(), self.options.qt_patches_path, patch_file_template)
+
+ patch_cmd = 'git submodule foreach -q'.split() + \
+ ['[ -e {patch} ] && git apply -v3 {patch} || true'.format(
+ patch=patch_path_template)]
+
+ self.run(patch_cmd, cwd=self.sourcedir)
+
+ for extra_plugin in self.options.qt_extra_plugins:
+ [framework] = list(extra_plugin)
+
+ final_path = os.path.join(self.sourcedir, 'qtbase', 'src',
+ 'plugins', framework)
+
+ for repo in extra_plugin[framework]:
+ repo_path = os.path.basename(repo)
+ if repo_path.endswith('.git'):
+ repo_path = repo_path[:-4]
+
+ if not os.path.exists(os.path.join(final_path, repo_path)):
+ command = 'git clone {}'.format(repo).split()
+ self.run(command, cwd=final_path)
+
+ def build(self):
+ env = {}
+
+ for environ in self.options.environment:
+ [env_name] = list(environ)
+ env[env_name] = str(environ[env_name])
+
+ self.run(['./configure'] + self.options.configflags, env=env)
+ super().build()