Source code for craft_parts.plugins.cargo_use_plugin
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-## Copyright 2025 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 cargo-use plugin.This plugin copy the content of the Rust repository to the local crates registry."""importshutilimportsysfromtypingimportLiteralfromoverridesimportoverridefromcraft_partsimporterrorsfrom.baseimportPluginfrom.propertiesimportPluginPropertiesifsys.version_info>=(3,11):importtomllibelse:# Python 3.10 compatibilityimporttomliastomllibCARGO_TOML_TEMPLATE="""\[source.craft-parts]directory = "{registry_dir}"[source.apt]directory = "/usr/share/cargo/registry"[source.crates-io]replace-with = "craft-parts""""
[docs]classCargoUsePluginProperties(PluginProperties,frozen=True):"""The part properties used by the cargo-use plugin."""plugin:Literal["cargo-use"]="cargo-use"source:str# pyright: ignore[reportGeneralTypeIssues]
[docs]classCargoUsePlugin(Plugin):"""Copy the content of the Rust repository and ."""properties_class=CargoUsePluginProperties
[docs]@overridedefget_build_snaps(self)->set[str]:"""Return a set of required snaps to install in the build environment."""returnset()
[docs]@overridedefget_pull_commands(self)->list[str]:"""Return a list commands to retrieve dependencies during the pull step."""return[]
[docs]@overridedefget_build_packages(self)->set[str]:"""Return a set of required packages to install in the build environment."""returnset()
[docs]@overridedefget_build_environment(self)->dict[str,str]:"""Return a dictionary with the environment to use in the build step."""return{}
[docs]@overridedefget_build_commands(self)->list[str]:"""Return a list of commands to run during the build step."""workspace_dir=self._part_info.work_dirregistry_dir=workspace_dir/"cargo-registry"registry_dir.mkdir(exist_ok=True)part_registry_target=registry_dir/self._get_cargo_registry_dir_name()ifpart_registry_target.exists():# as we don't track files we have to delete previous content# to avoid conflicts on rebuildshutil.rmtree(part_registry_target)part_registry_target.mkdir()cargo_config=self._part_info.work_dir/"cargo/config.toml"ifnotcargo_config.exists():cargo_config.parent.mkdir(exist_ok=True,parents=True)cargo_config.write_text(CARGO_TOML_TEMPLATE.format(registry_dir=registry_dir))checksum_file=part_registry_target/".cargo-checksum.json"ifnotchecksum_file.exists():# create checksum_filechecksum_file.write_text('{"files":{}}')return[f'cp --archive --link --no-dereference . "{part_registry_target}"']
def_get_cargo_registry_dir_name(self)->str:"""Create a name for the cargo-registry directory based on Cargo.toml."""cargo_toml=self._part_info.part_src_subdir/"Cargo.toml"ifnotcargo_toml.exists():raiseerrors.PartsError("Cannot use 'cargo-use' plugin on non-Rust project.")try:parsed_toml=tomllib.loads(cargo_toml.read_text())excepttomllib.TOMLDecodeErroraserr:raiseerrors.PartsError(f"Cannot parse Cargo.toml for {self._part_info.part_name!r}")fromerrelse:package_dict=parsed_toml.get("package")ifnotpackage_dict:raiseerrors.PartsError("Package section is missing in Cargo.toml file")package_name=package_dict.get("name",self._part_info.part_name)# according to the docs this field is optional since 1.7.5 and defaults to 0.0.0# it is required for publishing crates, so it should be available for most packages# https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-fieldpackage_version=package_dict.get("version","0.0.0")returnf"{package_name}-{package_version}"