| 1 |
|
| 2 |
|
| 3 |
use super::format::{short_id, signature_line, when}; |
| 4 |
use super::open; |
| 5 |
use anyhow::Result; |
| 6 |
use oxy_core::hash::ChangeHash; |
| 7 |
use oxy_core::repo::{self, IdentityScope}; |
| 8 |
|
| 9 |
pub fn create(name: Option<String>, email: Option<String>, local: bool) -> Result<i32> { |
| 10 |
let mut repo = open()?; |
| 11 |
let name = name.unwrap_or_else(|| repo.config.author_name.clone()); |
| 12 |
let email = email.unwrap_or_else(|| repo.config.author_email.clone()); |
| 13 |
let scope = if local { IdentityScope::Repo } else { IdentityScope::User }; |
| 14 |
let (key, _) = repo.create_identity(&name, &email, scope)?; |
| 15 |
println!("Created identity {name} <{email}>"); |
| 16 |
println!("KeyId: {key}"); |
| 17 |
println!("Secret key stored under {}", repo::default_keys_dir().display()); |
| 18 |
match scope { |
| 19 |
IdentityScope::User => println!("Recorded as your default author in {}", repo.user_config_path().display()), |
| 20 |
IdentityScope::Repo => println!("Recorded in this repository's .oxy/config only"), |
| 21 |
} |
| 22 |
if !repo.config.sign_changes { |
| 23 |
println!("Changes will carry this author; run `oxy config --user core.sign change` to sign each commit."); |
| 24 |
} |
| 25 |
Ok(0) |
| 26 |
} |
| 27 |
|
| 28 |
pub fn show() -> Result<i32> { |
| 29 |
let repo = open()?; |
| 30 |
let Some(key) = repo.config.author_key else { |
| 31 |
println!("No identity configured; run `oxy identity create`."); |
| 32 |
return Ok(0); |
| 33 |
}; |
| 34 |
let id = repo.identity(&key)?; |
| 35 |
println!("{} <{}>", id.name, id.email); |
| 36 |
println!("KeyId: {key}"); |
| 37 |
println!("Created: {}", when(id.created)); |
| 38 |
println!("Secret: {}", if repo.secret_key()?.is_some() { "available" } else { "NOT FOUND in key directory" }); |
| 39 |
println!("Signing: {}", if repo.config.sign_changes { "every change (core.sign = change)" } else { "at push via seals (core.sign = seal)" }); |
| 40 |
Ok(0) |
| 41 |
} |
| 42 |
|
| 43 |
pub fn verify(change: Option<&str>) -> Result<i32> { |
| 44 |
let repo = open()?; |
| 45 |
let hashes: Vec<ChangeHash> = match change { |
| 46 |
Some(c) => vec![repo.resolve_change(c)?], |
| 47 |
None => repo.log()?.into_iter().filter(|e| !e.is_working_copy).map(|e| e.hash).collect(), |
| 48 |
}; |
| 49 |
let mut bad = 0; |
| 50 |
for h in hashes { |
| 51 |
let c = repo.store().get_change(&h)?; |
| 52 |
let line = signature_line(&repo, &h)?; |
| 53 |
if line.starts_with("INVALID") { |
| 54 |
bad += 1; |
| 55 |
} |
| 56 |
println!("{} #{} {line}", short_id(&c), h.short(12)); |
| 57 |
} |
| 58 |
Ok(if bad > 0 { 1 } else { 0 }) |
| 59 |
} |
| 60 |
|
| 61 |
pub fn config(key: &str, value: &str, user: bool) -> Result<i32> { |
| 62 |
if user { |
| 63 |
let path = repo::default_user_config(); |
| 64 |
repo::Config::set_user(&path, key, value)?; |
| 65 |
println!("{key} = {value} (in {})", path.display()); |
| 66 |
} else { |
| 67 |
let mut repo = open()?; |
| 68 |
repo.config.set(key, value)?; |
| 69 |
repo.save_config()?; |
| 70 |
println!("{key} = {value} (in this repository)"); |
| 71 |
} |
| 72 |
Ok(0) |
| 73 |
} |