feat(notgraph): heatmap coloring, symbol counts, per-crate module graphs, cycle callouts

This commit is contained in:
Joseph O'Brien
2026-04-02 20:53:07 -04:00
parent 5c14230935
commit b5a27108d0
28 changed files with 490 additions and 167 deletions

View File

@@ -10,7 +10,9 @@ pub struct BitwardenSource {
impl BitwardenSource {
pub fn new(item_name: impl Into<String>) -> Self {
Self { item_name: item_name.into() }
Self {
item_name: item_name.into(),
}
}
fn retrieve_key(&self) -> Result<String, AgeError> {
@@ -28,10 +30,12 @@ impl BitwardenSource {
let session = std::env::var("BW_SESSION").unwrap_or_default();
let session = if session.is_empty() {
let password = rpassword::prompt_password("Bitwarden master password: ")
.map_err(|e| AgeError::SourceError {
name: self.name().to_string(),
source: anyhow::anyhow!("could not read password: {e}"),
let password =
rpassword::prompt_password("Bitwarden master password: ").map_err(|e| {
AgeError::SourceError {
name: self.name().to_string(),
source: anyhow::anyhow!("could not read password: {e}"),
}
})?;
let output = Command::new("bw")
.args(["unlock", "--raw", &password])
@@ -101,10 +105,11 @@ impl IdentitySource for BitwardenSource {
fn load(&self) -> Result<Box<dyn Identity>, AgeError> {
let key = self.retrieve_key()?;
let identity = X25519Identity::from_bech32(key.trim()).map_err(|e| AgeError::SourceError {
name: self.name().to_string(),
source: anyhow::anyhow!("key is not a valid AGE-SECRET-KEY-1: {e}"),
})?;
let identity =
X25519Identity::from_bech32(key.trim()).map_err(|e| AgeError::SourceError {
name: self.name().to_string(),
source: anyhow::anyhow!("key is not a valid AGE-SECRET-KEY-1: {e}"),
})?;
Ok(Box::new(identity))
}
}

View File

@@ -1,7 +1,7 @@
use crate::error::AgeError;
use crate::identities::Identity;
use crate::identities::encrypted::EncryptedIdentity;
use crate::identities::x25519::X25519Identity;
use crate::identities::Identity;
use crate::sources::IdentitySource;
use std::path::PathBuf;
@@ -33,19 +33,19 @@ impl IdentitySource for FileSource {
source: anyhow::anyhow!("key file UTF-8: {e}"),
})?
.trim();
let identity = X25519Identity::from_bech32(key_str).map_err(|e| AgeError::SourceError {
name: self.name().to_string(),
source: anyhow::anyhow!("invalid AGE-SECRET-KEY-1: {e}"),
})?;
let identity =
X25519Identity::from_bech32(key_str).map_err(|e| AgeError::SourceError {
name: self.name().to_string(),
source: anyhow::anyhow!("invalid AGE-SECRET-KEY-1: {e}"),
})?;
Ok(Box::new(identity))
} else if content.starts_with(b"age-encryption.org/v1") {
let passphrase = rpassword::prompt_password(
"Enter passphrase for encrypted identity file: ",
)
.map_err(|e| AgeError::SourceError {
name: self.name().to_string(),
source: anyhow::anyhow!("could not read passphrase: {e}"),
})?;
let passphrase =
rpassword::prompt_password("Enter passphrase for encrypted identity file: ")
.map_err(|e| AgeError::SourceError {
name: self.name().to_string(),
source: anyhow::anyhow!("could not read passphrase: {e}"),
})?;
Ok(Box::new(EncryptedIdentity::new(content, passphrase)))
} else {
Err(AgeError::UnsupportedKeyType(format!(

View File

@@ -1,6 +1,6 @@
use crate::error::AgeError;
use crate::identities::scrypt::ScryptIdentity;
use crate::identities::Identity;
use crate::identities::scrypt::ScryptIdentity;
use crate::sources::IdentitySource;
pub struct PromptSource;