Skip to content

Commit

Permalink
Revert "add commit hashes to git sources"
Browse files Browse the repository at this point in the history
Shnatsel authored Feb 18, 2024
1 parent da85607 commit 4e24aa6
Showing 8 changed files with 111 additions and 501 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

181 changes: 0 additions & 181 deletions auditable-serde/src/compact_enum_variant.rs

This file was deleted.

175 changes: 16 additions & 159 deletions auditable-serde/src/lib.rs
Original file line number Diff line number Diff line change
@@ -45,23 +45,22 @@
//! }
//! ```
mod compact_enum_variant;
mod validation;

use compact_enum_variant::{EnumVariant, IsEnumVariant, VariantRepr};
use validation::RawVersionInfo;

use serde::{Deserialize, Serialize};

#[cfg(feature = "toml")]
use cargo_lock;
#[cfg(any(feature = "from_metadata", feature = "toml"))]
use std::convert::TryFrom;
#[cfg(feature = "toml")]
use std::convert::TryInto;
use std::str::FromStr;
#[cfg(feature = "from_metadata")]
#[cfg(feature = "from_metadata")]
use std::{
cmp::min, cmp::Ordering::*, collections::HashMap, error::Error, fmt::Display, str::FromStr,
};
use std::{cmp::min, cmp::Ordering::*, collections::HashMap, error::Error, fmt::Display};

/// Dependency tree embedded in the binary.
///
@@ -113,7 +112,7 @@ pub struct Package {
/// The package's version in the [semantic version](https://semver.org) format.
#[cfg_attr(feature = "schema", schemars(with = "String"))]
pub version: semver::Version,
/// The description of package's source.
/// Currently "git", "local", "crates.io" or "registry". Designed to be extensible with other revision control systems, etc.
pub source: Source,
/// "build" or "runtime". May be omitted if set to "runtime".
/// If it's both a build and a runtime dependency, "runtime" is recorded.
@@ -134,44 +133,25 @@ pub struct Package {
pub root: bool,
}

/// Serializes to "git", "local", "crates.io", "registry" or a more complex
/// struct with any of those values in the `kind` field. Designed to be
/// extensible with other revision control systems, etc.
//
// The abundance of schemars attributes was introduced to fix an unexpected
// way of representing untagged enums that is inconsistent with serde. Without
// extra `with` attributes the generated schema assigns null types to instances
// of the enum's variants which are unit types instead of using string type.
/// Serializes to "git", "local", "crates.io" or "registry". Designed to be extensible with other revision control systems, etc.
#[non_exhaustive]
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
#[serde(rename_all = "snake_case", untagged)]
#[serde(from = "&str")]
#[serde(into = "String")]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum Source {
/// "crates.io"
#[serde(rename = "crates.io")]
#[cfg_attr(feature = "schema", schemars(with = "String"))]
CratesIo,
/// "local"
#[cfg_attr(feature = "schema", schemars(with = "String"))]
Git,
Local,
/// "registry"
#[cfg_attr(feature = "schema", schemars(with = "String"))]
Registry,
#[serde(with = "compact_enum_variant")]
#[cfg_attr(
feature = "schema",
schemars(schema_with = "compact_enum_variant::schema::<Source, GitSource>",)
)]
Git(GitSource),
/// Any other source
Other(String),
}

impl From<&str> for Source {
fn from(s: &str) -> Self {
match s {
"crates.io" => Self::CratesIo,
"git" => Self::Git(GitSource::default()),
"git" => Self::Git,
"local" => Self::Local,
"registry" => Self::Registry,
other_str => Self::Other(other_str.to_string()),
@@ -180,111 +160,28 @@ impl From<&str> for Source {
}

impl From<Source> for String {
/// Provides a lossy conversion for variants with values different than the default
fn from(s: Source) -> String {
match s {
Source::CratesIo => "crates.io".to_owned(),
Source::Git(_) => "git".to_owned(),
Source::Git => "git".to_owned(),
Source::Local => "local".to_owned(),
Source::Registry => "registry".to_owned(),
Source::Other(string) => string,
}
}
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Default)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct GitSource {
/// Commit hash pointing to specific revision
#[serde(skip_serializing_if = "is_default", default)]
pub rev: Option<String>,
}

impl IsEnumVariant<&str, Source> for GitSource {
fn variant() -> EnumVariant<&'static str, Source> {
EnumVariant::new("git")
}
}

impl From<GitSource> for VariantRepr<&'static str, Source, GitSource> {
fn from(value: GitSource) -> Self {
if is_default(&value) {
VariantRepr::Kind(GitSource::variant())
} else {
VariantRepr::Struct {
kind: GitSource::variant(),
strct: value,
}
}
}
}

impl TryFrom<VariantRepr<&str, Source, GitSource>> for GitSource {
type Error = &'static str;

fn try_from(value: VariantRepr<&str, Source, GitSource>) -> Result<Self, Self::Error> {
use compact_enum_variant::*;

match value {
VariantRepr::Kind(kind) => {
if kind != Self::variant() {
Err("cannot construct expected variant from provided value")
} else {
Ok(Self::default())
}
}
VariantRepr::Struct { kind, strct } => {
if kind != Self::variant() {
Err("cannot construct expected variant from provided value")
} else {
Ok(strct)
}
}
}
}
}

#[cfg(feature = "from_metadata")]
impl From<&cargo_metadata::Source> for Source {
fn from(meta_source: &cargo_metadata::Source) -> Self {
match meta_source.repr.as_str() {
"registry+https://github.com/rust-lang/crates.io-index" => Source::CratesIo,
source => {
let mut source_components = source.split('+');
let starts_with = source_components
source => Source::from(
source
.split('+')
.next()
.expect("Encoding of source strings in `cargo metadata` has changed!");

match starts_with {
"git" => {
let url = source_components.next().expect(
"Encoding of git source strings in `cargo metadata` has changed!",
);

if let Some(url_params) = url.split('?').nth(1) {
let mut git = GitSource::default();

url_params.split('&').for_each(|kv| {
if let Some((key, value)) = kv.split_once('=') {
if key == "rev" {
let mut value = value.to_owned();
if let Some(idx) = value.find('#') {
value.truncate(idx);
}

git.rev = Some(value.to_owned());
}
}
});

Source::Git(git)
} else {
Source::Git(GitSource::default())
}
}
_ => Source::from(starts_with),
}
}
.expect("Encoding of source strings in `cargo metadata` has changed!"),
),
}
}
}
@@ -595,46 +492,6 @@ mod tests {
use std::fs;
use std::{convert::TryInto, path::PathBuf};

#[test]
fn deserialize_source_with_detailed_git_source() {
let package_source_str = r#"{ "kind": "git", "rev": "abc" }"#;
let package_source: Source =
serde_json::from_str(package_source_str).expect("deserialization failure");
match package_source {
Source::Git(git) => {
assert!(git.rev.unwrap() == "abc")
}
_ => panic!("expected git variant"),
}
}

#[test]
#[should_panic]
fn fail_deserializing_invalid_git_source_variant() {
let package_source_str = r#"{ "kind": "abc", "rev": "abc" }"#;
serde_json::from_str(package_source_str).expect("deserialization failure")
}

#[test]
fn deserialize_source_with_simple_git_source() {
let package_source_str = r#""git""#;
let package_source: Source = serde_json::from_str(package_source_str).unwrap();
assert!(package_source == Source::Git(GitSource::default()));
}

#[test]
fn allow_any_other_unkown_sources_as_source_variant() {
let package_source_str = r#""unknown""#;
let package_source: Source =
serde_json::from_str(package_source_str).expect("deserialization failure");
match package_source {
Source::Other(unknown) => {
assert!(unknown == "unknown")
}
_ => panic!("expected Other(unknown) variant"),
}
}

#[cfg(feature = "toml")]
#[cfg(feature = "from_metadata")]
fn load_own_metadata() -> cargo_metadata::Metadata {
200 changes: 89 additions & 111 deletions cargo-auditable.schema.json
Original file line number Diff line number Diff line change
@@ -1,123 +1,101 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://rustsec.org/schemas/cargo-auditable.json",
"title": "cargo-auditable schema",
"description": "Describes the `VersionInfo` JSON data structure that cargo-auditable embeds into Rust binaries.",
"type": "object",
"required": [
"packages"
],
"properties": {
"packages": {
"type": "array",
"items": {
"$ref": "#/definitions/Package"
}
}
},
"definitions": {
"DependencyKind": {
"type": "string",
"enum": [
"build",
"runtime"
]
},
"Package": {
"description": "A single package in the dependency tree",
"type": "object",
"required": [
"name",
"source",
"version"
],
"properties": {
"dependencies": {
"description": "Packages are stored in an ordered array both in the `VersionInfo` struct and in JSON. Here we refer to each package by its index in the array. May be omitted if the list is empty.",
"type": "array",
"items": {
"type": "integer",
"format": "uint",
"minimum": 0.0
}
},
"kind": {
"description": "\"build\" or \"runtime\". May be omitted if set to \"runtime\". If it's both a build and a runtime dependency, \"runtime\" is recorded.",
"allOf": [
{
"$ref": "#/definitions/DependencyKind"
}
]
},
"name": {
"description": "Crate name specified in the `name` field in Cargo.toml file. Examples: \"libc\", \"rand\"",
"type": "string"
},
"root": {
"description": "Whether this is the root package in the dependency tree. There should only be one root package. May be omitted if set to `false`.",
"type": "boolean"
},
"source": {
"description": "The description of package's source.",
"allOf": [
{
"$ref": "#/definitions/Source"
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://rustsec.org/schemas/cargo-auditable.json",
"title": "cargo-auditable schema",
"description": "Describes the `VersionInfo` JSON data structure that cargo-auditable embeds into Rust binaries.",
"type": "object",
"required": [
"packages"
],
"properties": {
"packages": {
"type": "array",
"items": {
"$ref": "#/definitions/Package"
}
]
},
"version": {
"description": "The package's version in the [semantic version](https://semver.org) format.",
"type": "string"
}
}
},
"Source": {
"description": "Serializes to \"git\", \"local\", \"crates.io\", \"registry\" or a more complex struct with any of those values in the `kind` field. Designed to be extensible with other revision control systems, etc.",
"anyOf": [
{
"description": "\"crates.io\"",
"type": "string"
"definitions": {
"DependencyKind": {
"type": "string",
"enum": [
"build",
"runtime"
]
},
{
"description": "\"local\"",
"type": "string"
},
{
"description": "\"registry\"",
"type": "string"
},
{
"anyOf": [
{
"type": "string",
"const": "git"
},
{
"type": "object",
"required": [
"kind"
],
"properties": {
"Package": {
"description": "A single package in the dependency tree",
"type": "object",
"required": [
"name",
"source",
"version"
],
"properties": {
"dependencies": {
"description": "Packages are stored in an ordered array both in the `VersionInfo` struct and in JSON. Here we refer to each package by its index in the array. May be omitted if the list is empty.",
"type": "array",
"items": {
"type": "integer",
"format": "uint",
"minimum": 0.0
}
},
"kind": {
"type": "string",
"const": "git"
"description": "\"build\" or \"runtime\". May be omitted if set to \"runtime\". If it's both a build and a runtime dependency, \"runtime\" is recorded.",
"allOf": [
{
"$ref": "#/definitions/DependencyKind"
}
]
},
"name": {
"description": "Crate name specified in the `name` field in Cargo.toml file. Examples: \"libc\", \"rand\"",
"type": "string"
},
"rev": {
"description": "Commit hash pointing to specific revision",
"type": [
"string",
"null"
]
"root": {
"description": "Whether this is the root package in the dependency tree. There should only be one root package. May be omitted if set to `false`.",
"type": "boolean"
},
"source": {
"description": "Currently \"git\", \"local\", \"crates.io\" or \"registry\". Designed to be extensible with other revision control systems, etc.",
"allOf": [
{
"$ref": "#/definitions/Source"
}
]
},
"version": {
"description": "The package's version in the [semantic version](https://semver.org) format.",
"type": "string"
}
}
}
]
},
{
"description": "Any other source",
"type": "string"
"Source": {
"description": "Serializes to \"git\", \"local\", \"crates.io\" or \"registry\". Designed to be extensible with other revision control systems, etc.",
"oneOf": [
{
"type": "string",
"enum": [
"CratesIo",
"Git",
"Local",
"Registry"
]
},
{
"type": "object",
"required": [
"Other"
],
"properties": {
"Other": {
"type": "string"
}
},
"additionalProperties": false
}
]
}
]
}
}
}
}
2 changes: 1 addition & 1 deletion cargo-auditable/src/collect_audit_data.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ use std::{convert::TryFrom, str::from_utf8};

use crate::{cargo_arguments::CargoArgs, rustc_arguments::RustcArgs};

/// Calls `cargo metadata` to obtain the dependency tree, serializes it to JSON and compresses it.
/// Calls `cargo metadata` to obtain the dependency tree, serializes it to JSON and compresses it
pub fn compressed_dependency_list(rustc_args: &RustcArgs, target_triple: &str) -> Vec<u8> {
let metadata = get_metadata(rustc_args, target_triple);
let version_info = VersionInfo::try_from(&metadata).unwrap();
11 changes: 0 additions & 11 deletions cargo-auditable/tests/fixtures/git_source_of_dep/Cargo.toml

This file was deleted.

3 changes: 0 additions & 3 deletions cargo-auditable/tests/fixtures/git_source_of_dep/src/main.rs

This file was deleted.

32 changes: 1 addition & 31 deletions cargo-auditable/tests/it.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ use std::{
process::{Command, Output, Stdio},
};

use auditable_serde::{DependencyKind, Source, VersionInfo};
use auditable_serde::{DependencyKind, VersionInfo};
use cargo_metadata::{
camino::{Utf8Path, Utf8PathBuf},
Artifact,
@@ -403,33 +403,3 @@ fn test_workspace_member_version_info() {
let status = command.status().unwrap();
assert!(status.success());
}

#[test]
fn test_git_source_of_dep() {
// Path to workspace fixture Cargo.toml. See that file for overview of workspace members and their dependencies.
let workspace_cargo_toml = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/git_source_of_dep/Cargo.toml");
// Run in workspace root with default features
let bins = run_cargo_auditable(workspace_cargo_toml, &["--release"], &[]);
eprintln!("Test fixture binary map: {bins:?}");

// lto_binary_crate should only depend on itself
let git_source_of_dep = &bins.get("git_source_of_dep").unwrap()[0];
let dep_info = get_dependency_info(git_source_of_dep);
eprintln!("{git_source_of_dep} dependency info: {dep_info:?}");
assert!(dep_info
.packages
.iter()
.any(|p| p.name == "git_source_of_dep"));
assert!(dep_info.packages.iter().any(|p| p.name == "serde"
&& match &p.source {
Source::Git(git) => {
if git.rev == Some(String::from("2ba406726f9f84bc3b65ce4e824ae636dfa7dc85")) {
true
} else {
false
}
}
_ => false,
}));
}

0 comments on commit 4e24aa6

Please sign in to comment.