use std::path::PathBuf;
use std::process;
use clap::Subcommand;
use super::{
open_codebase, registry_client, registry_url, resolve_tri_files, short_hash, try_load_and_parse,
};
#[derive(Subcommand)]
pub enum RegistryAction {
/// Publish local store definitions to a registry
Publish {
/// Registry URL (default: $TRIDENT_REGISTRY_URL or http://127.0.0.1:8090)
#[arg(long)]
registry: Option<String>,
/// Tags to attach to published definitions
#[arg(long)]
tag: Vec<String>,
/// Input .tri file or directory (adds to store first, then publishes)
#[arg(short, long)]
input: Option<PathBuf>,
},
/// Pull a definition from a registry into local store
Pull {
/// Name or content hash to pull
name: String,
/// Registry URL
#[arg(long)]
registry: Option<String>,
},
/// Search a registry for definitions
Search {
/// Search query (name, module, or type signature)
query: String,
/// Registry URL
#[arg(long)]
registry: Option<String>,
/// Search by type signature instead of name
#[arg(long)]
r#type: bool,
/// Search by tag
#[arg(long)]
tag: bool,
},
}
pub fn cmd_registry(action: RegistryAction) {
match action {
RegistryAction::Publish {
registry,
tag,
input,
} => cmd_registry_publish(registry, tag, input),
RegistryAction::Pull { name, registry } => cmd_registry_pull(name, registry),
RegistryAction::Search {
query,
registry,
r#type,
tag,
} => cmd_registry_search(query, registry, r#type, tag),
}
}
fn cmd_registry_publish(registry: Option<String>, tags: Vec<String>, input: Option<PathBuf>) {
let client = registry_client(registry);
let mut cb = open_codebase();
if let Some(ref input_path) = input {
let files = resolve_tri_files(input_path);
for file_path in &files {
if let Some((_, file)) = try_load_and_parse(file_path) {
cb.add_file(&file);
}
}
if let Err(e) = cb.save() {
eprintln!("error: cannot save codebase: {}", e);
}
}
eprintln!("Publishing...");
match trident::registry::publish_codebase(&cb, &client, &tags) {
Ok(results) => {
let created = results.iter().filter(|r| r.created).count();
let existing = results.len() - created;
let named = results.iter().filter(|r| r.name_bound).count();
eprintln!(
"Published: {} new, {} existing, {} names bound",
created, existing, named
);
}
Err(e) => {
eprintln!("error: publish failed: {}", e);
process::exit(1);
}
}
}
fn cmd_registry_pull(name: String, registry: Option<String>) {
let url = registry_url(registry);
let client = trident::registry::RegistryClient::new(&url);
let mut cb = open_codebase();
eprintln!("Pulling '{}' from {}...", name, url);
match trident::registry::pull_into_codebase(&mut cb, &client, &name) {
Ok(result) => {
eprintln!("Pulled: {} ({})", name, short_hash(&result.hash));
eprintln!(" Module: {}", result.module);
if !result.params.is_empty() {
let params: Vec<String> = result
.params
.iter()
.map(|(n, t)| format!("{}: {}", n, t))
.collect();
eprintln!(" Params: {}", params.join(", "));
}
if let Some(ref ret) = result.return_ty {
eprintln!(" Returns: {}", ret);
}
if !result.dependencies.is_empty() {
eprintln!(" Dependencies: {}", result.dependencies.len());
}
}
Err(e) => {
eprintln!("error: {}", e);
process::exit(1);
}
}
}
fn cmd_registry_search(query: String, registry: Option<String>, by_type: bool, by_tag: bool) {
let url = registry_url(registry);
let client = trident::registry::RegistryClient::new(&url);
let results = if by_type {
client.search_by_type(&query)
} else if by_tag {
client.search_by_tag(&query)
} else {
client.search(&query)
};
match results {
Ok(results) => {
if results.is_empty() {
eprintln!("No results for '{}'", query);
return;
}
for r in &results {
let verified = if r.verified { " [verified]" } else { "" };
let tags = if r.tags.is_empty() {
String::new()
} else {
format!(" [{}]", r.tags.join(", "))
};
println!(
" {} {} {}{}{}",
short_hash(&r.hash),
r.name,
r.signature,
verified,
tags
);
}
eprintln!("\n{} results", results.len());
}
Err(e) => {
eprintln!("error: {}", e);
process::exit(1);
}
}
}
trident/src/cli/registry.rs
ฯ 0.0%
use PathBuf;
use process;
use Subcommand;
use ;