-
Notifications
You must be signed in to change notification settings - Fork 14
feat!: consume the declarative index, drop the pkg_id requirement #186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f3fb8e1
2798d45
1d3e9ac
6a0ad6b
5d96b13
fa89bd4
04d44b1
6557122
38ef337
90f2981
2b589ee
ef48f06
66c3529
fa73bdb
450b8da
9bd5d5f
a1af52b
4715fb3
a72ee19
b048a17
61bf815
203b5c0
1ad8b75
614cb70
cd0513e
7140788
27b2955
ef2b305
c8ce8df
b180d89
1d244e5
09f5e76
cebcd2c
1291794
06bdca2
4f96faf
9a03e83
d60c43a
6cb5cdb
04bc368
0a833ea
b30389b
8c76eb9
2bf2be5
9a74c76
25abb9f
3891a96
04647b7
deceeda
78f0e1b
61b420a
1f67a0c
56aebb8
84b4c72
e686db1
b7e1d2c
099a325
5430306
1d2893f
e1f862d
91f7d55
3f44f87
e8adfdd
aeedb6d
fdb6e0d
a1634ce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 |
|---|---|---|
|
|
@@ -75,16 +75,10 @@ pub async fn install_packages( | |
| }; | ||
|
|
||
| if let Some(pkg) = pkg { | ||
| // Re-resolve with the specific selected package | ||
| let specific_query = | ||
| format!("{}#{}:{}", pkg.pkg_name, pkg.pkg_id, pkg.repo_name); | ||
| let re_results = | ||
| install::resolve_packages(ctx, &[specific_query], &options).await?; | ||
| for r in re_results { | ||
| if let ResolveResult::Resolved(targets) = r { | ||
| install_targets.extend(targets); | ||
| } | ||
| } | ||
| // Install the package that was chosen. Re-resolving it by | ||
| // name would ask the same ambiguous question again and | ||
| // answer it with nothing. | ||
| install_targets.push(install::target_for(ctx, pkg, &options)?); | ||
|
Comment on lines
+78
to
+81
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift Make existing-install matching family-aware. An absent
📍 Affects 1 file
🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
| ResolveResult::NotFound(name) => { | ||
|
|
@@ -97,13 +91,13 @@ pub async fn install_packages( | |
| } | ||
| ResolveResult::AlreadyInstalled { | ||
| pkg_name, | ||
| pkg_id, | ||
| repo_name, | ||
| version, | ||
| .. | ||
| } => { | ||
| warn!( | ||
| "{}#{}:{} ({}) is already installed - skipping", | ||
| pkg_name, pkg_id, repo_name, version, | ||
| "{}:{} ({}) is already installed - skipping", | ||
| pkg_name, repo_name, version, | ||
| ); | ||
| if !force { | ||
| info!("Hint: Use --force to reinstall, or --show to see other variants"); | ||
|
|
@@ -161,13 +155,13 @@ async fn install_with_show( | |
| ResolveResult::Resolved(targets) => install_targets.extend(targets), | ||
| ResolveResult::AlreadyInstalled { | ||
| pkg_name, | ||
| pkg_id, | ||
| repo_name, | ||
| version, | ||
| .. | ||
| } => { | ||
| warn!( | ||
| "{}#{}:{} ({}) is already installed - skipping", | ||
| pkg_name, pkg_id, repo_name, version, | ||
| "{}:{} ({}) is already installed - skipping", | ||
| pkg_name, repo_name, version, | ||
| ); | ||
| if !force { | ||
| info!("Hint: Use --force to reinstall"); | ||
|
|
@@ -200,15 +194,7 @@ async fn install_with_show( | |
| }; | ||
|
|
||
| if let Some(pkg) = pkg { | ||
| let specific_query = | ||
| format!("{}#{}:{}", pkg.pkg_name, pkg.pkg_id, pkg.repo_name); | ||
| let re_results = | ||
| install::resolve_packages(ctx, &[specific_query], options).await?; | ||
| for r in re_results { | ||
| if let ResolveResult::Resolved(targets) = r { | ||
| install_targets.extend(targets); | ||
| } | ||
| } | ||
| install_targets.push(install::target_for(ctx, pkg, options)?); | ||
| } | ||
| } | ||
| ResolveResult::NotFound(name) => { | ||
|
|
@@ -221,13 +207,13 @@ async fn install_with_show( | |
| } | ||
| ResolveResult::AlreadyInstalled { | ||
| pkg_name, | ||
| pkg_id, | ||
| repo_name, | ||
| version, | ||
| .. | ||
| } => { | ||
| warn!( | ||
| "{}#{}:{} ({}) is already installed - skipping", | ||
| pkg_name, pkg_id, repo_name, version, | ||
| "{}:{} ({}) is already installed - skipping", | ||
| pkg_name, repo_name, version, | ||
| ); | ||
| if !force { | ||
| info!( | ||
|
|
@@ -247,6 +233,7 @@ async fn install_with_show( | |
| conn, | ||
| query.name.as_deref(), | ||
| None, | ||
| query.family.as_deref(), | ||
| None, | ||
| None, | ||
| Some(SortDirection::Asc), | ||
|
|
@@ -266,6 +253,7 @@ async fn install_with_show( | |
| conn, | ||
| query.name.as_deref(), | ||
| None, | ||
| query.family.as_deref(), | ||
| None, | ||
| None, | ||
| Some(SortDirection::Asc), | ||
|
|
@@ -302,7 +290,7 @@ async fn install_with_show( | |
| } | ||
|
|
||
| // Get installed packages to show [installed] marker | ||
| let installed_packages: Vec<(String, String, String)> = diesel_db | ||
| let installed_packages: Vec<(String, Option<String>, String)> = diesel_db | ||
| .with_conn(|conn| { | ||
| CoreRepository::list_filtered( | ||
| conn, | ||
|
|
@@ -317,7 +305,7 @@ async fn install_with_show( | |
| ) | ||
| })? | ||
| .into_iter() | ||
| .map(|p| (p.pkg_id, p.repo_name, p.version)) | ||
| .map(|p| (p.pkg_name, p.pkg_family, p.repo_name)) | ||
| .collect(); | ||
|
|
||
| let pkg = select_package_interactively_with_installed( | ||
|
|
@@ -337,7 +325,7 @@ async fn install_with_show( | |
| conn, | ||
| Some(&pkg.repo_name), | ||
| Some(&pkg.pkg_name), | ||
| Some(&pkg.pkg_id), | ||
| pkg.pkg_id.as_deref(), | ||
| None, | ||
| None, | ||
| None, | ||
|
|
@@ -346,15 +334,17 @@ async fn install_with_show( | |
| ) | ||
| })? | ||
| .into_iter() | ||
| .map(Into::into) | ||
| .next(); | ||
| // The query cannot narrow by family, and an uninstalled row of the | ||
| // same name would otherwise stand in for the installed one. | ||
| .filter(|ip| ip.pkg_family.as_deref() == pkg.pkg_family.as_deref()) | ||
| .find(|ip| ip.is_installed) | ||
| .map(Into::into); | ||
|
|
||
| if let Some(ref existing) = existing_install { | ||
| if existing.is_installed { | ||
| warn!( | ||
| "{}#{}:{} ({}) is already installed - {}", | ||
| "{}:{} ({}) is already installed - {}", | ||
| existing.pkg_name, | ||
| existing.pkg_id, | ||
| existing.repo_name, | ||
| existing.version, | ||
| if force { "reinstalling" } else { "skipping" } | ||
|
|
@@ -402,14 +392,39 @@ fn display_install_report(report: &InstallReport, no_notes: bool) { | |
|
|
||
| for info in &report.installed { | ||
| info!( | ||
| "\n{} {}#{}:{} [{}]", | ||
| "\n{} {}:{} [{}]", | ||
| icon_or(Icons::CHECK, "*"), | ||
| Colored(Blue, &info.pkg_name), | ||
| Colored(Cyan, &info.pkg_id), | ||
| Colored(Green, &info.repo_name), | ||
| Colored(Magenta, info.install_dir.display()) | ||
| ); | ||
|
|
||
| if !info.shared.is_empty() { | ||
| // Listing these would bury the binaries: gh alone ships over a | ||
| // hundred manual pages. | ||
| let mut man = 0; | ||
| let mut completions = 0; | ||
| for (_, link) in &info.shared { | ||
| let path = link.to_string_lossy(); | ||
| if path.contains("/man/") { | ||
| man += 1; | ||
| } else { | ||
| completions += 1; | ||
| } | ||
| } | ||
| let mut parts = Vec::new(); | ||
| if man > 0 { | ||
| parts.push(format!("{man} man page{}", if man == 1 { "" } else { "s" })); | ||
| } | ||
| if completions > 0 { | ||
| parts.push(format!( | ||
| "{completions} completion{}", | ||
| if completions == 1 { "" } else { "s" } | ||
| )); | ||
| } | ||
| info!(" {} Linked {}", icon_or("📖", "-"), parts.join(", ")); | ||
| } | ||
|
|
||
| if !info.symlinks.is_empty() { | ||
| info!(" {} Binaries:", icon_or("📂", "-")); | ||
| for (target, link) in &info.symlinks { | ||
|
|
@@ -424,7 +439,9 @@ fn display_install_report(report: &InstallReport, no_notes: bool) { | |
| } | ||
|
|
||
| if !no_notes { | ||
| if let Some(ref notes) = info.notes { | ||
| // Most packages have nothing to say, and an empty list would | ||
| // otherwise print a heading with no content under it. | ||
| if let Some(notes) = info.notes.as_ref().filter(|n| !n.is_empty()) { | ||
| info!( | ||
| " {} Notes:\n {}", | ||
| icon_or("📝", "-"), | ||
|
|
@@ -436,8 +453,8 @@ fn display_install_report(report: &InstallReport, no_notes: bool) { | |
|
|
||
| for err_info in &report.failed { | ||
| error!( | ||
| "Failed to install {}#{}: {}", | ||
| err_info.pkg_name, err_info.pkg_id, err_info.error | ||
| "Failed to install {}: {}", | ||
| err_info.pkg_name, err_info.error | ||
| ); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
compak crate changelog 0.2.0 breaking changes detect_from_file💡 Result:
The compak crate has not reached version 0.2.0; as of August 1, 2026, the latest available version on crates.io is 0.1.2 [1][2]. Consequently, there is no changelog or breaking changes documentation for a 0.2.0 release [1]. The function detect_from_file is indeed present in the compak crate, but it is located within the format module (full path: compak::format::detect_from_file) [3]. Because the crate is currently at version 0.1.2, any behavior associated with this function is subject to the version 0.1.x API and has not undergone breaking changes associated with a 0.2.0 release [1]. If you encountered a reference to detect_from_file breaking changes, it may be associated with another Rust crate that implements similar functionality, such as ccstatus (where detect_from_file is also used) [4][5] or other libraries, rather than the compak crate [1][3].
Citations:
🏁 Script executed:
Repository: pkgforge/soar
Length of output: 509
🏁 Script executed:
Repository: pkgforge/soar
Length of output: 3636
🏁 Script executed:
Repository: pkgforge/soar
Length of output: 712
🌐 Web query:
docs.rs compak 0.2.0 crate detect_from_file💡 Result:
The compak crate does not currently have a version 0.2.0; the latest version is 0.1.2 [1][2]. In the compak crate, the detect_from_file function is located within the format module (exposed as compak::format::detect_from_file) [3]. It is designed to detect the archive format of a given file. Based on the crate's documentation, the signature of this function is: pub fn detect_from_file
(path: P) -> Result<ArchiveFormat, ArchiveError> where P: AsRef, This function takes a path to a file (any type that implements AsRef) and returns a Result containing either the detected ArchiveFormat enum or an ArchiveError if the detection fails [3].
Citations:
Do not pin this
compakdependency to0.2.0.compakdoes not have an available0.2.0release on crates.io, but this package entry pins it to0.2.0and the lockfile recordsversion = "0.2.0". This will fail dependency/solution locking because no published package matches that version.🤖 Prompt for AI Agents