Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 8 commits into from Sep 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 18 additions & 0 deletions integration_tests/snaps/simple-ant/my-app/build.xml
@@ -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>
16 changes: 16 additions & 0 deletions integration_tests/snaps/simple-ant/snapcraft.yaml
@@ -0,0 +1,16 @@
name: simple-ant
version: 0
summary: test ant builds
description: |
Test ant builds and options.
confinement: strict
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mind adding grade: ... here?

grade: stable

parts:
a:
plugin: ant
source: my-app
ant-properties:
dist.dir: 'target'
ant-build-targets:
- artifacts
27 changes: 27 additions & 0 deletions integration_tests/test_ant_plugin.py
@@ -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))
52 changes: 44 additions & 8 deletions snapcraft/plugins/ant.py
Expand Up @@ -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
Expand All @@ -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)
Expand Down
44 changes: 36 additions & 8 deletions snapcraft/tests/test_plugin_ant.py
Expand Up @@ -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
Expand All @@ -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()
Expand All @@ -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,
Expand All @@ -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,
Expand Down