reordered close
This commit is contained in:
+25
-25
@@ -8,32 +8,32 @@ use crate::utils::*;
|
||||
|
||||
#[derive(Parser, Debug, PartialEq)]
|
||||
pub struct CloseOperation {
|
||||
pub drawer_file: PathBuf,
|
||||
pub target_path: Option<PathBuf>,
|
||||
pub target_path: PathBuf,
|
||||
pub drawer_file: Option<PathBuf>,
|
||||
#[arg(short = 'i')]
|
||||
pub key: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl Operation for CloseOperation {
|
||||
fn validate(&self) -> Result<(), DrawerError> {
|
||||
validate_drawer_extension(&self.drawer_file)?;
|
||||
let drawer_file = self.drawer_file.as_ref().cloned()
|
||||
.unwrap_or_else(|| self.target_path.with_extension("drawer"));
|
||||
validate_drawer_extension(&drawer_file)?;
|
||||
validate_ssh_key(&self.key)?;
|
||||
let target = self.target_path.as_ref().cloned()
|
||||
.unwrap_or_else(|| default_target(&self.drawer_file, None));
|
||||
let meta = std::fs::metadata(&target)
|
||||
.map_err(|_| DrawerError::TargetInvalid(target.clone()))?;
|
||||
let meta = std::fs::metadata(&self.target_path)
|
||||
.map_err(|_| DrawerError::TargetInvalid(self.target_path.clone()))?;
|
||||
if !meta.is_dir() && !meta.is_file() {
|
||||
return Err(DrawerError::TargetInvalid(target.clone()));
|
||||
return Err(DrawerError::TargetInvalid(self.target_path.clone()));
|
||||
}
|
||||
if meta.is_dir() && std::fs::read_dir(&target).is_err() {
|
||||
return Err(DrawerError::TargetInvalid(target.clone()));
|
||||
if meta.is_dir() && std::fs::read_dir(&self.target_path).is_err() {
|
||||
return Err(DrawerError::TargetInvalid(self.target_path.clone()));
|
||||
}
|
||||
let canon_target = target.canonicalize()
|
||||
.unwrap_or_else(|_| target.clone());
|
||||
let drawer_parent = parent_or_dot(&self.drawer_file);
|
||||
let canon_target = self.target_path.canonicalize()
|
||||
.unwrap_or_else(|_| self.target_path.clone());
|
||||
let drawer_parent = parent_or_dot(&drawer_file);
|
||||
let canon_drawer = drawer_parent.canonicalize()
|
||||
.unwrap_or_else(|_| drawer_parent.to_path_buf())
|
||||
.join(self.drawer_file.file_name().unwrap_or_default());
|
||||
.join(drawer_file.file_name().unwrap_or_default());
|
||||
if canon_drawer.starts_with(&canon_target) {
|
||||
return Err(DrawerError::DrawerInsideTarget);
|
||||
}
|
||||
@@ -41,22 +41,22 @@ impl Operation for CloseOperation {
|
||||
}
|
||||
|
||||
fn execute(&self) -> Result<(), DrawerError> {
|
||||
let target = self.target_path.as_ref().cloned()
|
||||
.unwrap_or_else(|| default_target(&self.drawer_file, None));
|
||||
if self.target_path.is_none() {
|
||||
println!("(assuming from {})", target.display());
|
||||
let drawer_file = self.drawer_file.as_ref().cloned()
|
||||
.unwrap_or_else(|| self.target_path.with_extension("drawer"));
|
||||
if self.drawer_file.is_none() {
|
||||
println!("(creating {})", drawer_file.display());
|
||||
}
|
||||
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
{
|
||||
let gz = GzEncoder::new(&mut buf, Compression::default());
|
||||
let mut archive = tar::Builder::new(gz);
|
||||
if target.is_dir() {
|
||||
archive.append_dir_all(".", &target)
|
||||
if self.target_path.is_dir() {
|
||||
archive.append_dir_all(".", &self.target_path)
|
||||
.map_err(|_| DrawerError::TarFailed)?;
|
||||
} else {
|
||||
let name = target.file_name().unwrap_or_default();
|
||||
archive.append_path_with_name(&target, name)
|
||||
let name = self.target_path.file_name().unwrap_or_default();
|
||||
archive.append_path_with_name(&self.target_path, name)
|
||||
.map_err(|_| DrawerError::TarFailed)?;
|
||||
}
|
||||
let gz = archive.into_inner()
|
||||
@@ -65,8 +65,8 @@ impl Operation for CloseOperation {
|
||||
.map_err(|_| DrawerError::TarFailed)?;
|
||||
}
|
||||
|
||||
let encrypted = encrypt(&buf, &self.key, &self.drawer_file)?;
|
||||
std::fs::write(&self.drawer_file, &encrypted)
|
||||
.map_err(|_| DrawerError::WriteFailed(self.drawer_file.clone()))
|
||||
let encrypted = encrypt(&buf, &self.key, &drawer_file)?;
|
||||
std::fs::write(&drawer_file, &encrypted)
|
||||
.map_err(|_| DrawerError::WriteFailed(drawer_file.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -32,12 +32,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_basic_close() {
|
||||
let op = parse_args(vec!["drawer", "close", "blah.drawer", "-i", "foo.key", "blah"]);
|
||||
let op = parse_args(vec!["drawer", "close", "blah", "-i", "foo.key", "blah.drawer"]);
|
||||
assert_eq!(op, Ok(
|
||||
Command::Close(CloseOperation{
|
||||
drawer_file: "blah.drawer".into(),
|
||||
drawer_file: Some("blah.drawer".into()),
|
||||
key: Some(PathBuf::from("foo.key")),
|
||||
target_path: Some("blah".into()),
|
||||
target_path: "blah".into(),
|
||||
})
|
||||
))
|
||||
}
|
||||
|
||||
@@ -47,10 +47,10 @@ err "key: refuse missing parent" $DRAWER key "$WORK/nosuchdir/test.key"
|
||||
|
||||
DRAWER_FILE="$WORK/test.drawer"
|
||||
|
||||
ok "close: pack test dir" $DRAWER close -i "$KEY" "$DRAWER_FILE" "$TEST_DIR"
|
||||
err "close: refuse without key" DRAWER_KEY="" $DRAWER close "$DRAWER_FILE" "$TEST_DIR"
|
||||
err "close: refuse bad key" $DRAWER close -i "$WORK/notakey" "$DRAWER_FILE" "$TEST_DIR"
|
||||
err "close: refuse bad extension" $DRAWER close -i "$KEY" "$WORK/test.notadrawer" "$TEST_DIR"
|
||||
ok "close: pack test dir" $DRAWER close -i "$KEY" "$TEST_DIR" "$DRAWER_FILE"
|
||||
err "close: refuse without key" DRAWER_KEY="" $DRAWER close "$TEST_DIR" "$DRAWER_FILE"
|
||||
err "close: refuse bad key" $DRAWER close -i "$WORK/notakey" "$TEST_DIR" "$DRAWER_FILE"
|
||||
err "close: refuse bad extension" $DRAWER close -i "$KEY" "$TEST_DIR" "$WORK/test.notadrawer"
|
||||
|
||||
# ── open ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -76,11 +76,25 @@ err "open: refuse bad key" $DRAWER open -i "$WORK/notakey" "$DRAWER_FI
|
||||
INFER_DRAWER="$WORK/inferred.drawer"
|
||||
INFER_OUT="$WORK/inferred"
|
||||
|
||||
ok "close: inferred source" $DRAWER close -i "$KEY" "$INFER_DRAWER" "$TEST_DIR"
|
||||
ok "close: inferred source" $DRAWER close -i "$KEY" "$TEST_DIR" "$INFER_DRAWER"
|
||||
mkdir -p "$INFER_OUT"
|
||||
ok "open: inferred target" $DRAWER open -i "$KEY" "$INFER_DRAWER" "$INFER_OUT"
|
||||
ok "open: inferred file1.md" test -f "$INFER_OUT/file1.md"
|
||||
|
||||
# ── close: inferred drawer file ──────────────────────────────────────────────
|
||||
|
||||
INFER_CLOSE_SRC="$WORK/myproject"
|
||||
INFER_CLOSE_DRAWER="$WORK/myproject.drawer"
|
||||
cp -r "$TEST_DIR" "$INFER_CLOSE_SRC"
|
||||
|
||||
ok "close: inferred drawer file" $DRAWER close -i "$KEY" "$INFER_CLOSE_SRC"
|
||||
ok "close: drawer file created" test -f "$INFER_CLOSE_DRAWER"
|
||||
|
||||
INFER_CLOSE_OUT="$WORK/myproject_out"
|
||||
mkdir -p "$INFER_CLOSE_OUT"
|
||||
ok "close: inferred round-trip open" $DRAWER open -i "$KEY" "$INFER_CLOSE_DRAWER" "$INFER_CLOSE_OUT"
|
||||
ok "close: inferred round-trip file1" test -f "$INFER_CLOSE_OUT/file1.md"
|
||||
|
||||
# ── info ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
$DRAWER info -i "$KEY" "$DRAWER_FILE" 2>/dev/null | grep -q "folder, 2 files" \
|
||||
@@ -96,7 +110,7 @@ SINGLE_DRAWER="$WORK/file1.drawer"
|
||||
SINGLE_OUT_DIR="$WORK/single_out"
|
||||
mkdir -p "$SINGLE_OUT_DIR"
|
||||
|
||||
ok "close: single file" $DRAWER close -i "$KEY" "$SINGLE_DRAWER" "$SINGLE_SRC"
|
||||
ok "close: single file" $DRAWER close -i "$KEY" "$SINGLE_SRC" "$SINGLE_DRAWER"
|
||||
$DRAWER info -i "$KEY" "$SINGLE_DRAWER" 2>/dev/null | grep -q "file, " \
|
||||
&& pass "info: reports single file" || fail "info: reports single file"
|
||||
ok "open: single file" $DRAWER open -i "$KEY" "$SINGLE_DRAWER" "$SINGLE_OUT_DIR/file1.md"
|
||||
|
||||
Reference in New Issue
Block a user