summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-04-22 18:01:09 +0300
committerLars Wirzenius <liw@liw.fi>2021-04-25 19:24:46 +0300
commit0d8094967d7b07c832f798756e2b6d5609e7babc (patch)
tree05165cca7a58f980e5da3fe41b1890808f37072a
parentfef7f220e2385ccfb423201958021a33c26b69c9 (diff)
downloadobnam2-0d8094967d7b07c832f798756e2b6d5609e7babc.tar.gz
feat: expand tilde notation in configuration file
Backup roots and log file can now say ~/foo/bar to refer to files relative to the user's home directory.
-rw-r--r--obnam.md23
-rw-r--r--src/config.rs37
-rw-r--r--subplot/client.py9
-rw-r--r--subplot/client.yaml3
4 files changed, 64 insertions, 8 deletions
diff --git a/obnam.md b/obnam.md
index e788d96..3050463 100644
--- a/obnam.md
+++ b/obnam.md
@@ -1122,6 +1122,29 @@ encrypt: false
~~~
+## Client expands tildes in its configuration file
+
+This scenario verifies that the client expands tildes in pathnames in
+its configuration file.
+
+
+~~~scenario
+given an installed obnam
+and file tilde.yaml
+when I run obnam --config tilde.yaml config
+then stdout contains home directory followed by /important
+then stdout contains home directory followed by /obnam.log
+~~~
+
+~~~{#tilde.yaml .file .yaml .numberLines}
+roots: [~/important]
+log: ~/obnam.log
+server_url: https://backup.example.com
+verify_tls_cert: true
+encrypt: false
+~~~
+
+
## Client requires https
This scenario verifies that the client rejects a configuration with a
diff --git a/src/config.rs b/src/config.rs
index 6881959..b30cfa3 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -91,21 +91,26 @@ impl ClientConfigWithoutPasswords {
trace!("read_config: filename={:?}", filename);
let config = std::fs::read_to_string(filename)?;
let tentative: TentativeClientConfig = serde_yaml::from_str(&config)?;
-
+ let roots = tentative
+ .roots
+ .iter()
+ .map(|path| expand_tilde(path))
+ .collect();
+ let log = tentative
+ .log
+ .map(|path| expand_tilde(&path))
+ .unwrap_or_else(|| PathBuf::from(DEVNULL));
let encrypt = tentative.encrypt.or(Some(false)).unwrap();
let exclude_cache_tag_directories = tentative.exclude_cache_tag_directories.unwrap_or(true);
let config = Self {
+ chunk_size: tentative.chunk_size.or(Some(DEFAULT_CHUNK_SIZE)).unwrap(),
+ encrypt,
filename: filename.to_path_buf(),
+ roots,
server_url: tentative.server_url,
- roots: tentative.roots,
verify_tls_cert: tentative.verify_tls_cert.or(Some(false)).unwrap(),
- chunk_size: tentative.chunk_size.or(Some(DEFAULT_CHUNK_SIZE)).unwrap(),
- log: tentative
- .log
- .or_else(|| Some(PathBuf::from(DEVNULL)))
- .unwrap(),
- encrypt,
+ log,
exclude_cache_tag_directories,
};
@@ -126,3 +131,19 @@ impl ClientConfigWithoutPasswords {
Ok(())
}
}
+
+fn expand_tilde(path: &Path) -> PathBuf {
+ if path.starts_with("~/") {
+ if let Some(home) = std::env::var_os("HOME") {
+ let mut expanded = PathBuf::from(home);
+ for comp in path.components().skip(1) {
+ expanded.push(comp);
+ }
+ expanded
+ } else {
+ path.to_path_buf()
+ }
+ } else {
+ path.to_path_buf()
+ }
+}
diff --git a/subplot/client.py b/subplot/client.py
index 1ddc772..be0a6d6 100644
--- a/subplot/client.py
+++ b/subplot/client.py
@@ -102,3 +102,12 @@ def stdout_matches_file(ctx, filename=None):
stdout = runcmd_get_stdout(ctx)
data = open(filename).read()
assert_eq(stdout, data)
+
+
+def stdout_contains_home_dir_path(ctx, path=None):
+ runcmd_get_stdout = globals()["runcmd_get_stdout"]
+ stdout = runcmd_get_stdout(ctx)
+ wanted = os.path.abspath(os.path.normpath("./" + path))
+ logging.debug(f"stdout_contains_home_dir_path: stdout={stdout!r}")
+ logging.debug(f"stdout_contains_home_dir_path: wanted={wanted!r}")
+ assert wanted in stdout
diff --git a/subplot/client.yaml b/subplot/client.yaml
index 8c76e9f..6de04c9 100644
--- a/subplot/client.yaml
+++ b/subplot/client.yaml
@@ -28,3 +28,6 @@
- then: "stdout matches file {filename}"
function: stdout_matches_file
+
+- then: "stdout contains home directory followed by {path}"
+ function: stdout_contains_home_dir_path