Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 34 additions & 8 deletions crates/cargo-util-schemas/lockfile.schema.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "TomlLockfile",
"description": "The `Cargo.lock` structure.",
"description": "Serialization of `Cargo.lock`",
"type": "object",
"properties": {
"version": {
"description": "The lockfile format version (`version =` field).\n\nThis field is optional for backward compatibility. Older lockfiles, i.e. V1 and V2, does\nnot have the version field serialized.",
"type": [
"integer",
"null"
Expand All @@ -13,6 +14,7 @@
"minimum": 0
},
"package": {
"description": "The list of `[[package]]` entries describing each resolved dependency.",
"type": [
"array",
"null"
Expand All @@ -22,7 +24,7 @@
}
},
"root": {
"description": "`root` is optional to allow backward compatibility.",
"description": "The `[root]` table describing the root package.\n\nThis field is optional for backward compatibility. Older lockfiles have the root package\nseparated, whereas newer lockfiles have the root package as part of `[[package]]`.",
"anyOf": [
{
"$ref": "#/$defs/TomlLockfileDependency"
Expand All @@ -33,6 +35,7 @@
]
},
"metadata": {
"description": "The `[metadata]` table\n\n\nIn older lockfile versions, dependency checksums were stored here instead of alongside each\npackage entry.",
"type": [
"object",
"null"
Expand All @@ -42,32 +45,43 @@
}
},
"patch": {
"description": "The `[patch]` table describing unused patches.\n\nThe lockfile stores them as a list of `[[patch.unused]]` entries.",
"$ref": "#/$defs/TomlLockfilePatch"
}
},
"$defs": {
"TomlLockfileDependency": {
"description": "Serialization of lockfiles dependencies",
"type": "object",
"properties": {
"name": {
"description": "The name of the dependency.",
"type": "string"
},
"version": {
"description": "The version of the dependency.",
"type": "string"
},
"source": {
"type": [
"string",
"null"
"description": "The source of the dependency.\n\nCargo does not serialize path dependencies.",
"anyOf": [
{
"$ref": "#/$defs/TomlLockfileSourceId"
},
{
"type": "null"
}
]
},
"checksum": {
"description": "The checksum of the dependency.\n\nIn older lockfiles, checksums were not stored here and instead on a separate `[metadata]`\ntable (see [`TomlLockfileMetadata`]).",
"type": [
"string",
"null"
]
},
"dependencies": {
"description": "The transitive dependencies used by this dependency.",
"type": [
"array",
"null"
Expand All @@ -77,6 +91,7 @@
}
},
"replace": {
"description": "The replace of the dependency.",
"anyOf": [
{
"$ref": "#/$defs/TomlLockfilePackageId"
Expand All @@ -92,7 +107,12 @@
"version"
]
},
"TomlLockfileSourceId": {
"description": "Serialization of dependency's source",
"type": "string"
},
"TomlLockfilePackageId": {
"description": "Serialization of package IDs.\n\nThe version and source are only included when necessary to disambiguate between packages:\n- If multiple packages share the same name, the version is included.\n- If multiple packages share the same name and version, the source is included.",
"type": "object",
"properties": {
"name": {
Expand All @@ -105,9 +125,13 @@
]
},
"source": {
"type": [
"string",
"null"
"anyOf": [
{
"$ref": "#/$defs/TomlLockfileSourceId"
},
{
"type": "null"
}
]
}
},
Expand All @@ -116,9 +140,11 @@
]
},
"TomlLockfilePatch": {
"description": "Serialization of unused patches\n\nCargo stores patches that were declared but not used during resolution.",
"type": "object",
"properties": {
"unused": {
"description": "The list of unused dependency patches.",
"type": "array",
"items": {
"$ref": "#/$defs/TomlLockfileDependency"
Expand Down
61 changes: 54 additions & 7 deletions crates/cargo-util-schemas/src/lockfile.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! `Cargo.lock` / Lockfile schema definition

use std::collections::BTreeMap;
use std::fmt;
use std::{cmp::Ordering, str::FromStr};
Expand All @@ -7,56 +9,96 @@ use url::Url;

use crate::core::{GitReference, SourceKind};

/// The `Cargo.lock` structure.
/// Serialization of `Cargo.lock`
#[derive(Serialize, Deserialize, Debug)]
#[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))]
pub struct TomlLockfile {
/// The lockfile format version (`version =` field).
///
/// This field is optional for backward compatibility. Older lockfiles, i.e. V1 and V2, does
/// not have the version field serialized.
pub version: Option<u32>,
/// The list of `[[package]]` entries describing each resolved dependency.
pub package: Option<Vec<TomlLockfileDependency>>,
/// `root` is optional to allow backward compatibility.
/// The `[root]` table describing the root package.
///
/// This field is optional for backward compatibility. Older lockfiles have the root package
/// separated, whereas newer lockfiles have the root package as part of `[[package]]`.
pub root: Option<TomlLockfileDependency>,
/// The `[metadata]` table
///
///
/// In older lockfile versions, dependency checksums were stored here instead of alongside each
/// package entry.
pub metadata: Option<TomlLockfileMetadata>,
/// The `[patch]` table describing unused patches.
///
/// The lockfile stores them as a list of `[[patch.unused]]` entries.
#[serde(default, skip_serializing_if = "TomlLockfilePatch::is_empty")]
pub patch: TomlLockfilePatch,
}

/// Serialization of lockfiles metadata
///
/// Older versions of lockfiles have their dependencies' checksums on this `[metadata]` table.
pub type TomlLockfileMetadata = BTreeMap<String, String>;

/// Serialization of unused patches
///
/// Cargo stores patches that were declared but not used during resolution.
#[derive(Serialize, Deserialize, Debug, Default)]
#[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))]
pub struct TomlLockfilePatch {
/// The list of unused dependency patches.
pub unused: Vec<TomlLockfileDependency>,
}

pub type TomlLockfileMetadata = BTreeMap<String, String>;

impl TomlLockfilePatch {
fn is_empty(&self) -> bool {
self.unused.is_empty()
}
}

/// Serialization of lockfiles dependencies
#[derive(Serialize, Deserialize, Debug, PartialOrd, Ord, PartialEq, Eq)]
#[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))]
pub struct TomlLockfileDependency {
/// The name of the dependency.
pub name: String,
/// The version of the dependency.
pub version: String,
/// The source of the dependency.
///
/// Cargo does not serialize path dependencies.
pub source: Option<TomlLockfileSourceId>,
/// The checksum of the dependency.
///
/// In older lockfiles, checksums were not stored here and instead on a separate `[metadata]`
/// table (see [`TomlLockfileMetadata`]).
pub checksum: Option<String>,
/// The transitive dependencies used by this dependency.
pub dependencies: Option<Vec<TomlLockfilePackageId>>,
/// The replace of the dependency.
pub replace: Option<TomlLockfilePackageId>,
}

/// Serialization of dependency's source
#[derive(Debug, Clone)]
#[cfg_attr(
feature = "unstable-schema",
derive(schemars::JsonSchema),
schemars(with = "String")
)]
pub struct TomlLockfileSourceId {
/// Full string of the source
/// The string representation of the source as it appears in the lockfile.
source_str: String,
/// Used for sources ordering
/// The parsed source type, e.g. `git`, `registry`.
///
/// Used for sources ordering.
kind: SourceKind,
/// Used for sources ordering
/// The parsed URL of the source.
///
/// Used for sources ordering.
url: Url,
}

Expand Down Expand Up @@ -157,6 +199,11 @@ impl Ord for TomlLockfileSourceId {
}
}

/// Serialization of package IDs.
///
/// The version and source are only included when necessary to disambiguate between packages:
/// - If multiple packages share the same name, the version is included.
/// - If multiple packages share the same name and version, the source is included.
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Hash, Clone)]
#[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))]
pub struct TomlLockfilePackageId {
Expand Down
Loading