harn_cli/package/registry/
commands.rs1use crate::package::*;
5
6pub fn list_package_cache() {
7 let result = (|| -> Result<(PathBuf, Vec<PackageCacheEntry>), PackageError> {
8 Ok((cache_root()?, discover_package_cache_entries()?))
9 })();
10
11 match result {
12 Ok((root, entries)) => {
13 println!("Cache root: {}", root.display());
14 if entries.is_empty() {
15 println!("No cached packages.");
16 return;
17 }
18 println!("kind\tkey\tcontent_hash\tsource\tpath");
19 for entry in entries {
20 let (source, content_hash) = entry
21 .metadata
22 .as_ref()
23 .map(|metadata| (metadata.source.as_str(), metadata.content_hash.as_str()))
24 .unwrap_or(("(unknown)", "(unknown)"));
25 println!(
26 "{}\t{}\t{}\t{}\t{}",
27 entry.kind,
28 entry.commit,
29 content_hash,
30 source,
31 entry.path.display()
32 );
33 }
34 }
35 Err(error) => {
36 eprintln!("error: {error}");
37 process::exit(1);
38 }
39 }
40}
41
42pub fn clean_package_cache(all: bool) {
43 match clean_package_cache_impl(all) {
44 Ok(removed) => println!("Removed {removed} cached package entries."),
45 Err(error) => {
46 eprintln!("error: {error}");
47 process::exit(1);
48 }
49 }
50}
51
52pub fn verify_package_cache(materialized: bool) {
53 match verify_package_cache_impl(materialized) {
54 Ok(verified) => println!("Verified {verified} package cache entries."),
55 Err(error) => {
56 eprintln!("error: {error}");
57 process::exit(1);
58 }
59 }
60}
61
62pub fn search_package_registry(query: Option<&str>, registry: Option<&str>, json: bool) {
63 match search_package_registry_impl(query, registry) {
64 Ok(packages) if json => {
65 println!(
66 "{}",
67 serde_json::to_string_pretty(&packages)
68 .unwrap_or_else(|error| format!(r#"{{"error":"{error}"}}"#))
69 );
70 }
71 Ok(packages) => {
72 if packages.is_empty() {
73 println!("No packages found.");
74 return;
75 }
76 println!("name\tlatest\tharn\tcontract\tdescription");
77 for package in packages {
78 let latest = latest_registry_version(&package)
79 .map(|version| version.version.as_str())
80 .unwrap_or("-");
81 println!(
82 "{}\t{}\t{}\t{}\t{}",
83 package.name,
84 latest,
85 package.harn.as_deref().unwrap_or("-"),
86 package.connector_contract.as_deref().unwrap_or("-"),
87 package.description.as_deref().unwrap_or("")
88 );
89 }
90 }
91 Err(error) => {
92 eprintln!("error: {error}");
93 process::exit(1);
94 }
95 }
96}
97
98pub fn search_rule_package_registry(query: Option<&str>, registry: Option<&str>, json: bool) {
99 match search_rule_package_registry_impl(query, registry) {
100 Ok(packages) if json => {
101 println!(
102 "{}",
103 serde_json::to_string_pretty(&packages)
104 .unwrap_or_else(|error| format!(r#"{{"error":"{error}"}}"#))
105 );
106 }
107 Ok(packages) => {
108 if packages.is_empty() {
109 println!("No rule packs found.");
110 return;
111 }
112 println!("name\tlatest\tlanguages\trules\tsafety\tdescription");
113 for package in packages {
114 let latest = latest_registry_version(&package)
115 .map(|version| version.version.as_str())
116 .unwrap_or("-")
117 .to_string();
118 let rule_pack = package.rule_pack.unwrap_or_default();
119 let languages = if rule_pack.languages.is_empty() {
120 "-".to_string()
121 } else {
122 rule_pack.languages.join(",")
123 };
124 let safety = if rule_pack.safety_summary.is_empty() {
125 "-".to_string()
126 } else {
127 rule_pack.safety_summary.join(",")
128 };
129 println!(
130 "{}\t{}\t{}\t{}\t{}\t{}",
131 package.name,
132 latest,
133 languages,
134 rule_pack.rule_count,
135 safety,
136 package.description.as_deref().unwrap_or("")
137 );
138 }
139 }
140 Err(error) => {
141 eprintln!("error: {error}");
142 process::exit(1);
143 }
144 }
145}
146
147pub fn show_package_registry_info(spec: &str, registry: Option<&str>, json: bool) {
148 match package_registry_info_impl(spec, registry) {
149 Ok(info) if json => {
150 println!(
151 "{}",
152 serde_json::to_string_pretty(&info)
153 .unwrap_or_else(|error| format!(r#"{{"error":"{error}"}}"#))
154 );
155 }
156 Ok(info) => {
157 let package = info.package;
158 println!("{}", package.name);
159 if let Some(description) = package.description.as_deref() {
160 println!("description: {description}");
161 }
162 println!("repository: {}", package.repository);
163 if let Some(license) = package.license.as_deref() {
164 println!("license: {license}");
165 }
166 if let Some(harn) = package.harn.as_deref() {
167 println!("harn: {harn}");
168 }
169 if let Some(contract) = package.connector_contract.as_deref() {
170 println!("connector_contract: {contract}");
171 }
172 if let Some(docs) = package.docs_url.as_deref() {
173 println!("docs: {docs}");
174 }
175 if let Some(checksum) = package.checksum.as_deref() {
176 println!("checksum: {checksum}");
177 }
178 if let Some(provenance) = package.provenance.as_deref() {
179 println!("provenance: {provenance}");
180 }
181 if !package.exports.is_empty() {
182 println!("exports: {}", package.exports.join(", "));
183 }
184 if let Some(rule_pack) = package.rule_pack.as_ref() {
185 println!("rule_pack: yes");
186 println!("rules: {}", rule_pack.rule_count);
187 if !rule_pack.languages.is_empty() {
188 println!("languages: {}", rule_pack.languages.join(", "));
189 }
190 if !rule_pack.safety_summary.is_empty() {
191 println!("safety: {}", rule_pack.safety_summary.join(", "));
192 }
193 }
194 if let Some(version) = info.selected_version {
195 println!("selected: {}", version.version);
196 if let Some(git) = version.git.as_deref() {
197 println!("git: {git}");
198 }
199 if let Some(archive) = version.archive.as_deref() {
200 println!("archive: {archive}");
201 }
202 if let Some(rev) = version.rev.as_deref() {
203 println!("rev: {rev}");
204 }
205 if let Some(branch) = version.branch.as_deref() {
206 println!("branch: {branch}");
207 }
208 if let Some(package_name) = version.package.as_deref() {
209 println!("package: {package_name}");
210 }
211 }
212 if !package.versions.is_empty() {
213 let versions = package
214 .versions
215 .iter()
216 .map(|version| {
217 if version.yanked {
218 format!("{} (yanked)", version.version)
219 } else {
220 version.version.clone()
221 }
222 })
223 .collect::<Vec<_>>()
224 .join(", ");
225 println!("versions: {versions}");
226 }
227 }
228 Err(error) => {
229 eprintln!("error: {error}");
230 process::exit(1);
231 }
232 }
233}