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",
"sequoia-autocrypt",
"sequoia-cert-store",
"sequoia-directories",
"sequoia-keystore",
"sequoia-net",
"sequoia-openpgp",

View File

@ -32,6 +32,7 @@ maintenance = { status = "actively-developed" }
buffered-reader = { version = "1.3.1", default-features = false, features = ["compression"] }
dirs = "5"
dot-writer = { version = "0.1.3", optional = true }
sequoia-directories = "0.1"
sequoia-openpgp = { version = "1.18", default-features = false, features = ["compression"] }
sequoia-autocrypt = { version = "0.25", 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_complete = "4"
chrono = "0.4.10"
dirs = "5"
roff = "0.2.1"
serde = { version = "1.0.137", features = ["derive"] }
sequoia-directories = "0.1"
sequoia-openpgp = { version = "1.17", default-features = false }
sequoia-net = { version = "0.28", default-features = false }
subplot-build = { version = ">=0.7, <0.10", optional = true }

View File

@ -209,6 +209,35 @@ pub struct SqCommand {
help = "Overwrite existing files",
)]
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(
long,
global = true,
@ -229,15 +258,28 @@ key store."
global = true,
help_heading = GLOBAL_OPTIONS_HEADER,
help = "Override the key store server and its data",
long_help = "\
A key store server manages and protects secret key material. By
default, `sq` connects to the key store server listening on
`$XDG_DATA_HOME/sequoia/keystore`. If no key store server is running,
long_help = format!("\
A key store server manages and protects secret key material. By \
default, `sq` connects to the key store server for Sequoia's default \
home directory (see `--home`), {}. If no key store server is running, \
one is started.
This option causes `sq` to use an alternate key store server. If
necessary, a key store server is started, and configured to look for
its data in the specified location."
This option causes `sq` to use an alternate key store server. If \
necessary, a key store server is started, and configured to look for \
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>,
#[clap(
@ -258,10 +300,25 @@ standard cert-d, which is located in `$HOME/.local/share/pgp.cert.d`."
global = true,
help_heading = GLOBAL_OPTIONS_HEADER,
help = "Specify the location of the certificate store",
long_help = "\
Specify the location of the certificate store. By default, sq uses \
the OpenPGP certificate directory at `$HOME/.local/share/pgp.cert.d`, \
and creates it if it does not exist."
long_help = format!("\
Specify the location of the certificate store. By default, `sq` uses \
the OpenPGP certificate directory in Sequoia's home directory (see `--home`), \
{}. 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>,
#[clap(

View File

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