Use sequoia-directories.

- Use `sequoia-directories` to compute the home directory, and the
    various component directories.

  - This also allows the use of `SEQUOIA_HOME` to set the home
    directory.
This commit is contained in:
Neal H. Walfield 2024-05-21 16:09:30 +02:00
parent 1d162d214b
commit e75ad72c65
No known key found for this signature in database
GPG Key ID: 6863C9AD5B4D22D3
4 changed files with 79 additions and 22 deletions

1
Cargo.lock generated
View File

@ -3413,6 +3413,7 @@ dependencies = [
"rpassword", "rpassword",
"sequoia-autocrypt", "sequoia-autocrypt",
"sequoia-cert-store", "sequoia-cert-store",
"sequoia-directories",
"sequoia-keystore", "sequoia-keystore",
"sequoia-net", "sequoia-net",
"sequoia-openpgp", "sequoia-openpgp",

View File

@ -32,6 +32,7 @@ maintenance = { status = "actively-developed" }
buffered-reader = { version = "1.3.1", default-features = false, features = ["compression"] } buffered-reader = { version = "1.3.1", default-features = false, features = ["compression"] }
dirs = "5" dirs = "5"
dot-writer = { version = "0.1.3", optional = true } dot-writer = { version = "0.1.3", optional = true }
sequoia-directories = "0.1"
sequoia-openpgp = { version = "1.18", default-features = false, features = ["compression"] } sequoia-openpgp = { version = "1.18", default-features = false, features = ["compression"] }
sequoia-autocrypt = { version = "0.25", default-features = false } sequoia-autocrypt = { version = "0.25", default-features = false }
sequoia-net = { version = "0.28", default-features = false } sequoia-net = { version = "0.28", default-features = false }
@ -62,8 +63,10 @@ buffered-reader = { version = "1.0.0", default-features = false, features = ["co
clap = { version = "4", features = ["derive", "env", "string", "wrap_help"] } clap = { version = "4", features = ["derive", "env", "string", "wrap_help"] }
clap_complete = "4" clap_complete = "4"
chrono = "0.4.10" chrono = "0.4.10"
dirs = "5"
roff = "0.2.1" roff = "0.2.1"
serde = { version = "1.0.137", features = ["derive"] } serde = { version = "1.0.137", features = ["derive"] }
sequoia-directories = "0.1"
sequoia-openpgp = { version = "1.17", default-features = false } sequoia-openpgp = { version = "1.17", default-features = false }
sequoia-net = { version = "0.28", default-features = false } sequoia-net = { version = "0.28", default-features = false }
subplot-build = { version = ">=0.7, <0.10", optional = true } subplot-build = { version = ">=0.7, <0.10", optional = true }

View File

@ -209,6 +209,35 @@ pub struct SqCommand {
help = "Overwrite existing files", help = "Overwrite existing files",
)] )]
pub force: bool, pub force: bool,
#[clap(
long,
env = "SEQUOIA_HOME",
global = true,
help_heading = GLOBAL_OPTIONS_HEADER,
help = "Set the home directory.",
long_help = format!("\
Set the home directory.
Sequoia's default home directory is `{}`. When using the default \
location, files are placed according to the local standard, \
e.g., the XDG Base Directory Specification. When an alternate \
location is specified, the user data, configuration files, and \
cache data are placed under a single, unified directory. This is \
a lightweight way to partially isolate `sq`.",
sequoia_directories::Home::default_location()
.map(|p| {
let p = p.display().to_string();
if let Some(home) = dirs::home_dir() {
let home = home.display().to_string();
if let Some(rest) = p.strip_prefix(&home) {
return format!("$HOME{}", rest);
}
}
p
})
.unwrap_or("<unknown>".to_string())),
)]
pub home: Option<PathBuf>,
#[clap( #[clap(
long, long,
global = true, global = true,
@ -229,15 +258,28 @@ key store."
global = true, global = true,
help_heading = GLOBAL_OPTIONS_HEADER, help_heading = GLOBAL_OPTIONS_HEADER,
help = "Override the key store server and its data", help = "Override the key store server and its data",
long_help = "\ long_help = format!("\
A key store server manages and protects secret key material. By A key store server manages and protects secret key material. By \
default, `sq` connects to the key store server listening on default, `sq` connects to the key store server for Sequoia's default \
`$XDG_DATA_HOME/sequoia/keystore`. If no key store server is running, home directory (see `--home`), {}. If no key store server is running, \
one is started. one is started.
This option causes `sq` to use an alternate key store server. If This option causes `sq` to use an alternate key store server. If \
necessary, a key store server is started, and configured to look for necessary, a key store server is started, and configured to look for \
its data in the specified location." its data in the specified location.",
sequoia_directories::Home::default()
.map(|home| {
let p = home.data_dir(sequoia_directories::Component::Keystore);
let p = p.display().to_string();
if let Some(home) = dirs::home_dir() {
let home = home.display().to_string();
if let Some(rest) = p.strip_prefix(&home) {
return format!("$HOME{}", rest);
}
}
p
})
.unwrap_or("<unknown>".to_string())),
)] )]
pub key_store: Option<PathBuf>, pub key_store: Option<PathBuf>,
#[clap( #[clap(
@ -258,10 +300,25 @@ standard cert-d, which is located in `$HOME/.local/share/pgp.cert.d`."
global = true, global = true,
help_heading = GLOBAL_OPTIONS_HEADER, help_heading = GLOBAL_OPTIONS_HEADER,
help = "Specify the location of the certificate store", help = "Specify the location of the certificate store",
long_help = "\ long_help = format!("\
Specify the location of the certificate store. By default, sq uses \ Specify the location of the certificate store. By default, `sq` uses \
the OpenPGP certificate directory at `$HOME/.local/share/pgp.cert.d`, \ the OpenPGP certificate directory in Sequoia's home directory (see `--home`), \
and creates it if it does not exist." {}. This can be overridden by setting the `PGP_CERT_D` environment \
variable. That in turn can be overridden by setting the `SQ_CERT_STORE` \
environment variable.",
sequoia_directories::Home::default()
.map(|home| {
let p = home.data_dir(sequoia_directories::Component::CertD);
let p = p.display().to_string();
if let Some(home) = dirs::home_dir() {
let home = home.display().to_string();
if let Some(rest) = p.strip_prefix(&home) {
return format!("$HOME{}", rest);
}
}
p
})
.unwrap_or("<unknown>".to_string())),
)] )]
pub cert_store: Option<PathBuf>, pub cert_store: Option<PathBuf>,
#[clap( #[clap(

View File

@ -416,6 +416,7 @@ pub struct Config<'store, 'rstore>
output_version: Option<OutputVersion>, output_version: Option<OutputVersion>,
policy: &'rstore P<'rstore>, policy: &'rstore P<'rstore>,
time: SystemTime, time: SystemTime,
home: sequoia_directories::Home,
// --no-cert-store // --no-cert-store
no_rw_cert_store: bool, no_rw_cert_store: bool,
cert_store_path: Option<PathBuf>, cert_store_path: Option<PathBuf>,
@ -468,14 +469,10 @@ impl<'store: 'rstore, 'rstore> Config<'store, 'rstore> {
None None
} else if let Some(path) = self.cert_store_path.as_ref() { } else if let Some(path) = self.cert_store_path.as_ref() {
Some(path.clone()) Some(path.clone())
} else if let Ok(path) = std::env::var("PGP_CERT_D") {
Some(PathBuf::from(path))
} else { } else {
// XXX: openpgp-cert-d doesn't yet export this: Some(self.home.data_dir(sequoia_directories::Component::CertD))
// https://gitlab.com/sequoia-pgp/pgp-cert-d/-/issues/34
// Remove this when it does.
let pathbuf = dirs::data_dir()
.expect("Unsupported platform")
.join("pgp.cert.d");
Some(pathbuf)
} }
} }
@ -694,11 +691,9 @@ impl<'store: 'rstore, 'rstore> Config<'store, 'rstore> {
Ok(None) Ok(None)
} else if let Some(dir) = self.key_store_path.as_ref() { } else if let Some(dir) = self.key_store_path.as_ref() {
Ok(Some(dir.clone())) Ok(Some(dir.clone()))
} else if let Some(dir) = dirs::data_dir() {
Ok(Some(dir.join("sequoia/keystore")))
} else { } else {
Err(anyhow::anyhow!( let home = sequoia_directories::Home::new(None)?;
"No key store, the XDG data directory is not defined")) Ok(Some(home.data_dir(sequoia_directories::Component::Keystore)))
} }
} }
@ -1330,6 +1325,7 @@ fn main() -> Result<()> {
output_version, output_version,
policy: &policy, policy: &policy,
time, time,
home: sequoia_directories::Home::new(c.home.clone())?,
no_rw_cert_store: c.no_cert_store, no_rw_cert_store: c.no_cert_store,
cert_store_path: c.cert_store.clone(), cert_store_path: c.cert_store.clone(),
pep_cert_store_path: c.pep_cert_store.clone(), pep_cert_store_path: c.pep_cert_store.clone(),