Skip to content
This repository has been archived by the owner on Aug 15, 2024. It is now read-only.

Commit

Permalink
Merge pull request #53 from hi-rustin/rustin-patch-spec
Browse files Browse the repository at this point in the history
 feat: allow version selection
  • Loading branch information
epage authored Dec 2, 2023
2 parents 86a6e3b + 091ab5d commit dfb357d
Show file tree
Hide file tree
Showing 36 changed files with 339 additions and 23 deletions.
18 changes: 14 additions & 4 deletions src/bin/cargo-info/command/info.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cargo::util::command_prelude::*;
use cargo::{core::PackageIdSpec, util::command_prelude::*};
use cargo_information::ops;

pub fn cli() -> Command {
Expand All @@ -11,7 +11,13 @@ pub fn cli() -> Command {
fn info_subcommand() -> Command {
Command::new("info")
.about("Display info about a package in the registry")
.arg(Arg::new("pkgid").required(true).value_name("SPEC"))
.arg(
Arg::new("package")
.required(true)
.value_name("SPEC")
.help_heading(heading::PACKAGE_SELECTION)
.help("Package to inspect"),
)
.arg_index("Registry index URL to search packages in")
.arg_registry("Registry to search packages in")
.arg(
Expand Down Expand Up @@ -91,9 +97,13 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
&config_args,
)?;

let pkgid = args.get_one::<String>("pkgid").map(String::as_str).unwrap();
let package = args
.get_one::<String>("package")
.map(String::as_str)
.unwrap();
let spec = PackageIdSpec::parse(package)?;
let reg_or_index = args.registry_or_index(config)?;
ops::info(pkgid, config, reg_or_index)?;
ops::info(&spec, config, reg_or_index)?;
Ok(())
}

Expand Down
41 changes: 25 additions & 16 deletions src/ops/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::task::Poll;

use anyhow::{bail, Context as _};
use cargo::core::registry::PackageRegistry;
use cargo::core::{Dependency, PackageId, Registry, SourceId, Summary, Workspace};
use cargo::core::{Dependency, PackageId, PackageIdSpec, Registry, SourceId, Summary, Workspace};
use cargo::ops::RegistryOrIndex;
use cargo::sources::source::{QueryKind, Source};
use cargo::sources::{RegistrySource, SourceConfigMap};
Expand All @@ -18,22 +18,28 @@ use crates_io::User;

use super::view::{pretty_view, suggest_cargo_tree};

pub fn info(spec: &str, config: &Config, reg_or_index: Option<RegistryOrIndex>) -> CargoResult<()> {
pub fn info(
spec: &PackageIdSpec,
config: &Config,
reg_or_index: Option<RegistryOrIndex>,
) -> CargoResult<()> {
let mut registry = PackageRegistry::new(config)?;
// Make sure we get the lock before we download anything.
let _lock = config.acquire_package_cache_lock(CacheLockMode::DownloadExclusive)?;
registry.lock_patches();

let mut package_id = None;
// If we can find it in workspace, use it as a specific version.
if let Ok(root) = root_manifest(None, config) {
let ws = Workspace::new(&root, config)?;
if let Some(resolve) = ops::load_pkg_lockfile(&ws)? {
if let Ok(p) = resolve.query(spec) {
package_id = Some(p)
}
}
}
let mut package_id = root_manifest(None, config)
.ok()
.and_then(|root| Workspace::new(&root, config).ok())
.and_then(|ws| ops::load_pkg_lockfile(&ws).ok())
.and_then(|resolve| {
// If the locked versions are matched, use the highest version.
resolve
.as_ref()
.map(|r| r.iter())
.and_then(|it| it.filter(|&p| spec.matches(p)).max_by_key(|&p| p.version()))
});

let (use_package_source_id, source_ids) = get_source_id(config, reg_or_index, package_id)?;
// If we don't use the package's source, we need to query the package ID from the specified registry.
Expand All @@ -47,7 +53,7 @@ pub fn info(spec: &str, config: &Config, reg_or_index: Option<RegistryOrIndex>)
// Query the package registry and pretty print the result.
// If package_id is None, find the latest version.
fn query_and_pretty_view(
spec: &str,
spec: &PackageIdSpec,
package_id: Option<PackageId>,
config: &Config,
mut registry: PackageRegistry,
Expand All @@ -65,7 +71,7 @@ fn query_and_pretty_view(
}
}
// Query without version requirement to get all index summaries.
let dep = Dependency::parse(spec, None, source_ids.original)?;
let dep = Dependency::parse(spec.name(), None, source_ids.original)?;
let summaries = loop {
// Exact to avoid returning all for path/git
match registry.query_vec(&dep, QueryKind::Exact) {
Expand All @@ -79,9 +85,12 @@ fn query_and_pretty_view(
let package_id = match package_id {
Some(id) => id,
None => {
// Find the latest version.
let summary = summaries.iter().max_by_key(|s| s.package_id().version());

// If no matching summary is found, it defaults to the summary with the highest version number.
let summary = summaries
.iter()
.filter(|s| spec.matches(s.package_id()))
.max_by_key(|s| s.package_id().version())
.or(summaries.iter().max_by_key(|s| s.package_id().version()));
// If can not find the latest version, return an error.
match summary {
Some(summary) => summary.package_id(),
Expand Down
6 changes: 3 additions & 3 deletions tests/testsuite/cargo_information/help/stdout.log
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ Display info about a package in the registry

Usage: cargo info [OPTIONS] <SPEC>

Arguments:
<SPEC>

Options:
--index <INDEX> Registry index URL to search packages in
--registry <REGISTRY> Registry to search packages in
Expand All @@ -15,6 +12,9 @@ Options:
-Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details
-h, --help Print help

Package Selection:
<SPEC> Package to inspect

Manifest Options:
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
Expand Down
4 changes: 4 additions & 0 deletions tests/testsuite/cargo_information/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ mod basic;
mod features;
mod help;
mod not_found;
mod specify_version_outside_workspace;
mod specify_version_with_ws_and_match_multiple_versions;
mod specify_version_within_ws_and_conflict_with_lockfile;
mod specify_version_within_ws_and_match_with_lockfile;
mod with_frozen_outside_workspace;
mod with_frozen_within_workspace;
mod with_locked_outside_workspace;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use cargo_test_macro::cargo_test;
use cargo_test_support::curr_dir;

use super::{cargo_info, init_registry_without_token};

#[cargo_test]
fn case() {
init_registry_without_token();
for ver in ["0.1.1+my-package", "0.2.0+my-package", "0.2.3+my-package"] {
cargo_test_support::registry::Package::new("my-package", ver).publish();
}
cargo_info()
.arg("my-package@0.2")
.arg("--registry=dummy-registry")
.assert()
.success()
.stdout_matches_path(curr_dir!().join("stdout.log"))
.stderr_matches_path(curr_dir!().join("stderr.log"));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Updating `dummy-registry` index
Downloading crates ...
Downloaded my-package v0.2.3+my-package (registry `dummy-registry`)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
my-package
version: 0.2.3+my-package
license: unknown
rust-version: unknown

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[workspace]
members = ["crate*"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "crate1"
version = "0.0.0"

[dependencies]
my-package = "=0.2.0+my-package"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "crate2"
version = "0.0.0"

[dependencies]
my-package = "=0.2.3+my-package"
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use cargo_test_macro::cargo_test;
use cargo_test_support::{compare::assert_ui, curr_dir, Project};

use super::{cargo_info, init_registry_without_token};

#[cargo_test]
fn case() {
init_registry_without_token();
for ver in [
"0.1.1+my-package",
"0.2.0+my-package",
"0.2.3+my-package",
"0.4.1+my-package",
] {
cargo_test_support::registry::Package::new("my-package", ver).publish();
}

let project = Project::from_template(curr_dir!().join("in"));
let project_root = project.root();
let cwd = &project_root;

cargo_info()
.arg("my-package@0.2")
.arg("--registry=dummy-registry")
.current_dir(cwd)
.assert()
.success()
.stdout_matches_path(curr_dir!().join("stdout.log"))
.stderr_matches_path(curr_dir!().join("stderr.log"));

assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
}

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[workspace]
members = ["crate*"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "crate1"
version = "0.0.0"

[dependencies]
my-package = "=0.2.0+my-package"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "crate2"
version = "0.0.0"

[dependencies]
my-package = "=0.2.3+my-package"
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Updating `dummy-registry` index
Downloading crates ...
Downloaded my-package v0.2.3+my-package (registry `dummy-registry`)
Updating crates.io index
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
my-package
version: 0.2.3+my-package (latest 0.4.1+my-package)
license: unknown
rust-version: unknown
documentation: https://docs.rs/my-package/0.2.3+my-package
note: to see how you depend on my-package, run `cargo tree --package my-package@0.2.3+my-package --invert`
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use cargo_test_macro::cargo_test;
use cargo_test_support::{compare::assert_ui, curr_dir, Project};

use super::{cargo_info, init_registry_without_token};

#[cargo_test]
fn case() {
init_registry_without_token();
for ver in [
"0.1.1+my-package",
"0.2.0+my-package",
"0.2.3+my-package",
"0.4.1+my-package",
"20.0.0+my-package",
"99999.0.0+my-package",
"99999.0.0-alpha.1+my-package",
] {
cargo_test_support::registry::Package::new("my-package", ver).publish();
}

let project = Project::from_template(curr_dir!().join("in"));
let project_root = project.root();
let cwd = &project_root;

cargo_info()
.arg("my-package@0.4")
.arg("--registry=dummy-registry")
.current_dir(cwd)
.assert()
.success()
.stdout_matches_path(curr_dir!().join("stdout.log"))
.stderr_matches_path(curr_dir!().join("stderr.log"));

assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
}

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[workspace]

[package]
name = "cargo-list-test-fixture"
version = "0.0.0"

[dependencies]
my-package = "0.1"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Updating `dummy-registry` index
Downloading crates ...
Downloaded my-package v0.4.1+my-package (registry `dummy-registry`)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
my-package
version: 0.4.1+my-package (latest 99999.0.0+my-package)
license: unknown
rust-version: unknown
Loading

0 comments on commit dfb357d

Please sign in to comment.