Source code for craft_parts.plugins.ant_plugin

# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright 2022 Canonical Ltd.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""The Ant plugin."""

import logging
from typing import Any, Dict, List, Optional, Set, cast

from overrides import override

from craft_parts import errors

from . import validator
from .base import JavaPlugin, PluginModel, extract_plugin_properties
from .properties import PluginProperties

logger = logging.getLogger(__name__)


[docs]class AntPluginProperties(PluginProperties, PluginModel): """The part properties used by the Ant plugin.""" ant_build_targets: List[str] = [] ant_build_file: Optional[str] = None ant_properties: Dict[str, str] = {} source: str
[docs] @classmethod @override def unmarshal(cls, data: Dict[str, Any]) -> "AntPluginProperties": """Populate make properties from the part specification. :param data: A dictionary containing part properties. :return: The populated plugin properties data object. :raise pydantic.ValidationError: If validation fails. """ plugin_data = extract_plugin_properties( data, plugin_name="ant", required=["source"] ) return cls(**plugin_data)
[docs]class AntPluginEnvironmentValidator(validator.PluginEnvironmentValidator): """Check the execution environment for the Ant plugin. :param part_name: The part whose build environment is being validated. :param env: A string containing the build step environment setup. """
[docs] @override def validate_environment( self, *, part_dependencies: Optional[List[str]] = None ) -> None: """Ensure the environment contains dependencies needed by the plugin. :param part_dependencies: A list of the parts this part depends on. :raises PluginEnvironmentValidationError: If ``ant`` is invalid and there are no parts named ant. """ version = self.validate_dependency( dependency="ant", plugin_name="ant", part_dependencies=part_dependencies, argument="-version", ) if not version.startswith("Apache Ant") and ( part_dependencies is None or "ant-deps" not in part_dependencies ): raise errors.PluginEnvironmentValidationError( part_name=self._part_name, reason=f"invalid ant version {version!r}", )
[docs]class AntPlugin(JavaPlugin): """A plugin for Apache Ant projects. The plugin requires the ``ant`` tool installed on the system. This can be achieved by adding the appropriate declarations to ``build-packages`` or ``build-snaps``, or by having it installed or built in a different part. In this case, the name of the part supplying ``ant`` must be "ant-deps". Additionally, Java projects need a dev kit (jdk) to build and a runtime environment (jre) to run. There are multiple choices here, but frequently adding ``default-jdk-headless`` to ``build-packages`` and ``default-jre-headless`` to ``stage-packages`` is enough. Once built, the plugin will create the following structure in the part's install dir (which will later be staged/primed/packaged): - A ``bin/java`` symlink pointing to the actual ``java`` binary provided by the jre; - A ``jar/`` directory containing the .jar files generated by the build. The ant plugin uses the common plugin keywords, plus the following ant- specific keywords: - ``ant-build-targets`` (list of strings) The ant targets to build. These are directly passed to the ``ant`` command line. - ``ant-build-file`` (str) The name of the main ant build file. Defaults to ``build.xml``. - ``ant-properties`` (dict of strings to strings) A series of key: value pairs that are passed to ant as properties (using the ``-D{key}={value}`` notation). """ properties_class = AntPluginProperties validator_class = AntPluginEnvironmentValidator
[docs] @override def get_build_snaps(self) -> Set[str]: """Return a set of required snaps to install in the build environment.""" return set()
[docs] @override def get_build_packages(self) -> Set[str]: """Return a set of required packages to install in the build environment.""" return set()
[docs] @override def get_build_environment(self) -> Dict[str, str]: """Return a dictionary with the environment to use in the build step.""" return {}
[docs] @override def get_build_commands(self) -> List[str]: """Return a list of commands to run during the build step.""" options = cast(AntPluginProperties, self._options) command = ["ant"] if options.ant_build_file: command.extend(["-f", options.ant_build_file]) for prop_name, prop_value in options.ant_properties.items(): command.append(f"-D{prop_name}={prop_value}") command.extend(options.ant_build_targets) return [ " ".join(command), ] + self._get_java_post_build_commands()