Split cargo_out into three modules.

The `cargo` module has the output types, `cargo_out` has the code
specific to parsing cargo.out files, while `metadata` has the types to
parse cargo.metadata files.

Bug: 293289578
Test: atest cargo_embargo.test
Change-Id: I5a2e2871a48bf30a64f3ffbc84a160b0daa91b53
This commit is contained in:
Andrew Walbran
2023-08-09 18:28:06 +01:00
parent 6cf047b9ed
commit 085fa6c6b1
4 changed files with 121 additions and 81 deletions

View File

@@ -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<String>,
pub types: Vec<CrateType>,
pub target: Option<String>, // --target
pub features: Vec<String>, // --cfg feature=
pub cfgs: Vec<String>, // non-feature --cfg
pub externs: Vec<(String, Option<String>)>, // name => rlib file
pub codegens: Vec<String>, // -C
pub cap_lints: String,
pub static_libs: Vec<String>,
pub shared_libs: Vec<String>,
pub edition: String,
pub package_dir: PathBuf, // canonicalized
pub main_src: PathBuf, // relative to package_dir
}

View File

@@ -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<String>,
pub types: Vec<CrateType>,
pub target: Option<String>, // --target
pub features: Vec<String>, // --cfg feature=
pub cfgs: Vec<String>, // non-feature --cfg
pub externs: Vec<(String, Option<String>)>, // name => rlib file
pub codegens: Vec<String>, // -C
pub cap_lints: String,
pub static_libs: Vec<String>,
pub shared_libs: Vec<String>,
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<PackageMetadata>,
}
#[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<Crate> {
let mut out = Crate::default();

View File

@@ -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<PackageMetadata>,
}
#[derive(Debug, Deserialize)]
pub struct PackageMetadata {
pub name: String,
pub version: String,
pub edition: String,
pub manifest_path: String,
}

View File

@@ -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;