From c56a200798958c94dfe111d04b6e4765e92bd698 Mon Sep 17 00:00:00 2001 From: Scott K Logan Date: Thu, 19 Dec 2024 15:36:44 -0600 Subject: [PATCH] Collect crate metadata during 'prepare' phase of build * If metadata collection fails for some reason, it would be good if we hadn't already performed any operations on the package. * It would be good to have the metadata earlier in the process so we can use it in other operations. --- colcon_cargo/task/cargo/build.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/colcon_cargo/task/cargo/build.py b/colcon_cargo/task/cargo/build.py index 59c44ce..3b0a950 100644 --- a/colcon_cargo/task/cargo/build.py +++ b/colcon_cargo/task/cargo/build.py @@ -65,13 +65,16 @@ async def build( # noqa: D102 elif build_dir.exists(): shutil.rmtree(build_dir) - # Invoke build step if CARGO_EXECUTABLE is None: raise RuntimeError("Could not find 'cargo' executable") + # Get package metadata + metadata = await self._get_metadata(env) + cargo_args = args.cargo_args if cargo_args is None: cargo_args = [] + # Invoke build step cmd = self._build_cmd(cargo_args) self.progress('build') @@ -85,7 +88,7 @@ async def build( # noqa: D102 # We also need to check if the package has any binaries, because if it # has no binaries then cargo install will return an error. cmd = self._install_cmd(cargo_args) - if cmd is not None and await self._has_binaries(env): + if cmd is not None and self._has_binaries(metadata): self.progress('install') rc = await run( self.context, cmd, cwd=self.context.pkg.path, env=env) @@ -141,8 +144,7 @@ def _install_cmd(self, cargo_args): cmd += ['--profile', 'dev'] return cmd + cargo_args - # Identify if there are any binaries to install for the current package - async def _has_binaries(self, env): + async def _get_metadata(self, env): cmd = [ CARGO_EXECUTABLE, 'metadata', @@ -150,6 +152,9 @@ async def _has_binaries(self, env): '--format-version', '1', ] + # TODO: The reported target_directory is wrong. Does it matter here? + # We could maybe override it with --config + rc = await run( self.context, cmd, @@ -167,7 +172,11 @@ async def _has_binaries(self, env): "Failed to capture stdout from 'cargo metadata'" ) - metadata = json.loads(rc.stdout) + return json.loads(rc.stdout) + + # Identify if there are any binaries to install for the current package + @staticmethod + def _has_binaries(metadata): for package in metadata.get('packages', {}): for target in package.get('targets', {}): for crate_type in target.get('crate_types', {}):