Ant properties, build target, and destination directory options #752

Merged
merged 8 commits into from Sep 1, 2016
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project basedir="." default="init" name="my-app"
+ xmlns:artifact="antlib:org.apache.maven.artifact.ant">
+ <property environment="env"/>
+ <property name="basedir" value="."/>
+ <property name="build.dir" value="${basedir}/build"/>
+ <property name="dist.dir" value="${build.dir}/dist"/>
+ <target name="init">
+ <mkdir dir="${build.dir}"/>
+ <mkdir dir="${dist.dir}"/>
+ </target>
+ <target name="clean">
+ <delete dir="${build.dir}" />
+ </target>
+ <target name="artifacts" depends="init">
+ <touch file="${dist.dir}/foo.jar"/>
+ </target>
+</project>
@@ -0,0 +1,16 @@
+name: simple-ant
+version: 0
+summary: test ant builds
+description: |
+ Test ant builds and options.
+confinement: strict
@sergiusens

sergiusens Aug 30, 2016

Collaborator

mind adding grade: ... here?

+grade: stable
+
+parts:
+ a:
+ plugin: ant
+ source: my-app
+ ant-properties:
+ dist.dir: 'target'
+ ant-build-targets:
+ - artifacts
@@ -0,0 +1,27 @@
+# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
+#
+# Copyright (C) 2015, 2016 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 integration_tests
+
+
+class AntPluginTestCase(integration_tests.TestCase):
+
+ def test_build_ant_plugin(self):
+ project_dir = 'simple-ant'
+ self.run_snapcraft('prime', project_dir)
+ jar_path = os.path.join(project_dir, 'prime', 'jar', 'foo.jar')
+ self.assertTrue(os.path.exists(jar_path))
@@ -22,6 +22,17 @@
This plugin uses the common plugin keywords as well as those for "sources".
For more information check the 'plugins' topic for the former and the
'sources' topic for the latter.
+
+Additionally, this plugin uses the following plugin-specific keywords:
+
+ - ant-properties:
+ (object)
+ A dictionary of key-value pairs. Set the following properties when
+ running ant.
+
+ - ant-build-targets:
+ (list of strings)
+ Run the given ant targets.
"""
import glob
@@ -38,21 +49,46 @@
class AntPlugin(snapcraft.plugins.jdk.JdkPlugin):
+ @classmethod
+ def schema(cls):
+ schema = super().schema()
+ schema['properties']['ant-properties'] = {
+ 'type': 'object',
+ 'default': {},
+ }
+ schema['properties']['ant-build-targets'] = {
+ 'type': 'array',
+ 'uniqueItems': True,
+ 'items': {
+ 'type': 'string',
+ },
+ 'default': [],
+ }
+ return schema
+
def __init__(self, name, options, project):
super().__init__(name, options, project)
self.build_packages.append('ant')
def build(self):
super().build()
- self.run(['ant'])
+
+ command = ['ant']
+
+ if self.options.ant_build_targets:
+ command.extend(self.options.ant_build_targets)
+
+ for prop, value in self.options.ant_properties.items():
+ command.extend(['-D{}={}'.format(prop, value)])
+
+ self.run(command)
files = glob.glob(os.path.join(self.builddir, 'target', '*.jar'))
- if not files:
- raise RuntimeError('Could not find any built jar files for part')
- jardir = os.path.join(self.installdir, 'jar')
- os.makedirs(jardir)
- for f in files:
- base = os.path.basename(f)
- os.link(f, os.path.join(jardir, base))
+ if files:
+ jardir = os.path.join(self.installdir, 'jar')
+ os.makedirs(jardir)
+ for f in files:
+ base = os.path.basename(f)
+ os.link(f, os.path.join(jardir, base))
def env(self, root):
env = super().env(root)
@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
+import copy
from unittest import mock
import snapcraft
@@ -28,7 +29,8 @@ def setUp(self):
super().setUp()
class Options:
- ant_options = []
+ ant_properties = {}
+ ant_build_targets = None
self.options = Options()
self.project_options = snapcraft.ProjectOptions()
@@ -37,6 +39,24 @@ class Options:
self.ubuntu_mock = patcher.start()
self.addCleanup(patcher.stop)
+ def test_schema(self):
+ schema = ant.AntPlugin.schema()
+
+ properties = schema['properties']
+ for expected in ['ant-properties', 'ant-build-targets']:
+ self.assertTrue(
+ expected in properties,
+ 'Expected {!r} to be included in properties'.format(expected))
+
+ properties_type = schema['properties']['ant-properties']['type']
+ self.assertEqual(properties_type, 'object',
+ 'Expected "ant-properties" "type" to be "object", '
+ 'but it was "{}"'.format(properties_type))
+ build_targets_type = schema['properties']['ant-build-targets']['type']
+ self.assertEqual(build_targets_type, 'array',
+ 'Expected "ant-build-targets" "type" to be "object", '
+ 'but it was "{}"'.format(build_targets_type))
+
@mock.patch.object(ant.AntPlugin, 'run')
def test_build(self, run_mock):
plugin = ant.AntPlugin('test-part', self.options,
@@ -57,17 +77,25 @@ def side(l):
])
@mock.patch.object(ant.AntPlugin, 'run')
- def test_build_fail(self, run_mock):
- plugin = ant.AntPlugin('test-part', self.options,
+ def test_build_with_options(self, run_mock):
+ options = copy.deepcopy(self.options)
+ plugin = ant.AntPlugin('test-part', options,
self.project_options)
+ options.ant_build_targets = ['artifacts', 'jar']
+ options.ant_properties = {'basedir': '.',
+ 'dist.dir': plugin.installdir}
os.makedirs(plugin.sourcedir)
- with self.assertRaises(RuntimeError):
- plugin.build()
+ plugin.build()
- run_mock.assert_has_calls([
- mock.call(['ant']),
- ])
+ destination = '-Ddist.dir={}'.format(plugin.installdir)
+ basedir = '-Dbasedir=.'
+ args = run_mock.call_args[0][0]
+ self.assertEqual(args[0], 'ant')
+ self.assertEqual(args[1], 'artifacts')
+ self.assertEqual(args[2], 'jar')
+ self.assertIn(destination, args)
+ self.assertIn(basedir, args)
def test_env(self):
plugin = ant.AntPlugin('test-part', self.options,