diff --git a/tools/cargo_embargo/src/cargo.rs b/tools/cargo_embargo/src/cargo.rs new file mode 100644 index 000000000..23e644765 --- /dev/null +++ b/tools/cargo_embargo/src/cargo.rs @@ -0,0 +1,86 @@ +// Copyright (C) 2023 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Types and functions for parsing the output of cargo. + +pub mod cargo_out; +pub mod metadata; + +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; + +/// Combined representation of --crate-type and --test flags. +#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde[rename_all = "lowercase"]] +pub enum CrateType { + // --crate-type types + Bin, + Lib, + RLib, + DyLib, + CDyLib, + StaticLib, + #[serde(rename = "proc-macro")] + ProcMacro, + // --test + Test, + // "--cfg test" without --test. (Assume it is a test with the harness disabled. + TestNoHarness, +} + +impl CrateType { + fn from_str(s: &str) -> CrateType { + match s { + "bin" => CrateType::Bin, + "lib" => CrateType::Lib, + "rlib" => CrateType::RLib, + "dylib" => CrateType::DyLib, + "cdylib" => CrateType::CDyLib, + "staticlib" => CrateType::StaticLib, + "proc-macro" => CrateType::ProcMacro, + _ => panic!("unexpected --crate-type: {}", s), + } + } +} + +impl CrateType { + /// Returns whether the crate type is a kind of library. + pub fn is_library(self) -> bool { + matches!(self, Self::Lib | Self::RLib | Self::DyLib | Self::CDyLib | Self::StaticLib) + } +} + +/// Info extracted from `CargoOut` for a crate. +/// +/// Note that there is a 1-to-many relationship between a Cargo.toml file and these `Crate` +/// objects. For example, a Cargo.toml file might have a bin, a lib, and various tests. Each of +/// those will be a separate `Crate`. All of them will have the same `package_name`. +#[derive(Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +pub struct Crate { + pub name: String, + pub package_name: String, + pub version: Option, + pub types: Vec, + pub target: Option, // --target + pub features: Vec, // --cfg feature= + pub cfgs: Vec, // non-feature --cfg + pub externs: Vec<(String, Option)>, // name => rlib file + pub codegens: Vec, // -C + pub cap_lints: String, + pub static_libs: Vec, + pub shared_libs: Vec, + pub edition: String, + pub package_dir: PathBuf, // canonicalized + pub main_src: PathBuf, // relative to package_dir +} diff --git a/tools/cargo_embargo/src/cargo_out.rs b/tools/cargo_embargo/src/cargo/cargo_out.rs similarity index 86% rename from tools/cargo_embargo/src/cargo_out.rs rename to tools/cargo_embargo/src/cargo/cargo_out.rs index 29b750c6b..74acf5c04 100644 --- a/tools/cargo_embargo/src/cargo_out.rs +++ b/tools/cargo_embargo/src/cargo/cargo_out.rs @@ -12,68 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. +use super::metadata::WorkspaceMetadata; +use super::{Crate, CrateType}; use anyhow::anyhow; use anyhow::bail; use anyhow::Context; use anyhow::Result; use once_cell::sync::Lazy; use regex::Regex; -use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::env; use std::fs::{read_to_string, File}; use std::path::Path; use std::path::PathBuf; -/// Combined representation of --crate-type and --test flags. -#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] -#[serde[rename_all = "lowercase"]] -pub enum CrateType { - // --crate-type types - Bin, - Lib, - RLib, - DyLib, - CDyLib, - StaticLib, - ProcMacro, - // --test - Test, - // "--cfg test" without --test. (Assume it is a test with the harness disabled. - TestNoHarness, -} - -impl CrateType { - /// Returns whether the crate type is a kind of library. - pub fn is_library(self) -> bool { - matches!(self, Self::Lib | Self::RLib | Self::DyLib | Self::CDyLib | Self::StaticLib) - } -} - -/// Info extracted from `CargoOut` for a crate. -/// -/// Note that there is a 1-to-many relationship between a Cargo.toml file and these `Crate` -/// objects. For example, a Cargo.toml file might have a bin, a lib, and various tests. Each of -/// those will be a separate `Crate`. All of them will have the same `package_name`. -#[derive(Debug, Default, Deserialize, Eq, PartialEq, Serialize)] -pub struct Crate { - pub name: String, - pub package_name: String, - pub version: Option, - pub types: Vec, - pub target: Option, // --target - pub features: Vec, // --cfg feature= - pub cfgs: Vec, // non-feature --cfg - pub externs: Vec<(String, Option)>, // name => rlib file - pub codegens: Vec, // -C - pub cap_lints: String, - pub static_libs: Vec, - pub shared_libs: Vec, - pub edition: String, - pub package_dir: PathBuf, // canonicalized - pub main_src: PathBuf, // relative to package_dir -} - /// Reads the given `cargo.out` and `cargo.metadata` files, and generates a list of crates based on /// the rustc invocations. /// @@ -121,20 +73,6 @@ fn parse_cargo_out_str( Ok(crates) } -/// `cargo metadata` output. -#[derive(Debug, Deserialize)] -struct WorkspaceMetadata { - packages: Vec, -} - -#[derive(Debug, Deserialize)] -struct PackageMetadata { - name: String, - version: String, - edition: String, - manifest_path: String, -} - /// Raw-ish data extracted from cargo.out file. #[derive(Debug, Default)] struct CargoOut { @@ -257,21 +195,6 @@ impl CargoOut { } } -impl CrateType { - fn from_str(s: &str) -> CrateType { - match s { - "bin" => CrateType::Bin, - "lib" => CrateType::Lib, - "rlib" => CrateType::RLib, - "dylib" => CrateType::DyLib, - "cdylib" => CrateType::CDyLib, - "staticlib" => CrateType::StaticLib, - "proc-macro" => CrateType::ProcMacro, - _ => panic!("unexpected --crate-type: {}", s), - } - } -} - impl Crate { fn from_rustc_invocation(rustc: &str, metadata: &WorkspaceMetadata) -> Result { let mut out = Crate::default(); diff --git a/tools/cargo_embargo/src/cargo/metadata.rs b/tools/cargo_embargo/src/cargo/metadata.rs new file mode 100644 index 000000000..e5cfc7709 --- /dev/null +++ b/tools/cargo_embargo/src/cargo/metadata.rs @@ -0,0 +1,31 @@ +// Copyright (C) 2023 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Types for parsing cargo.metadata JSON files. + +use serde::Deserialize; + +/// `cargo metadata` output. +#[derive(Debug, Deserialize)] +pub struct WorkspaceMetadata { + pub packages: Vec, +} + +#[derive(Debug, Deserialize)] +pub struct PackageMetadata { + pub name: String, + pub version: String, + pub edition: String, + pub manifest_path: String, +} diff --git a/tools/cargo_embargo/src/main.rs b/tools/cargo_embargo/src/main.rs index 514717b5b..cbcac394d 100644 --- a/tools/cargo_embargo/src/main.rs +++ b/tools/cargo_embargo/src/main.rs @@ -27,7 +27,7 @@ //! available to tweak it via a config file. mod bp; -mod cargo_out; +mod cargo; mod config; use crate::config::Config; @@ -36,7 +36,7 @@ use anyhow::bail; use anyhow::Context; use anyhow::Result; use bp::*; -use cargo_out::{parse_cargo_out, Crate, CrateType}; +use cargo::{cargo_out::parse_cargo_out, Crate, CrateType}; use clap::Parser; use once_cell::sync::Lazy; use regex::Regex;