Pass the status along to the delete_action so that we can act correctly on non-empty dirs.
This commit is contained in:
parent
daae141949
commit
687c533478
2 changed files with 32 additions and 21 deletions
|
|
@ -85,7 +85,7 @@ pub fn activate(store_path: &StorePath, ephemeral: bool) -> Result<()> {
|
||||||
status?;
|
status?;
|
||||||
|
|
||||||
let new_state = create_etc_links(config.entries.values(), &etc_dir, state, &old_state)
|
let new_state = create_etc_links(config.entries.values(), &etc_dir, state, &old_state)
|
||||||
.update_state(old_state, &|path| {
|
.update_state(old_state, &|path, status| {
|
||||||
log::debug!("Deactivating: {}", path.display());
|
log::debug!("Deactivating: {}", path.display());
|
||||||
false
|
false
|
||||||
});
|
});
|
||||||
|
|
@ -100,8 +100,9 @@ pub fn deactivate() -> Result<()> {
|
||||||
let state = read_created_files()?;
|
let state = read_created_files()?;
|
||||||
log::debug!("{:?}", state);
|
log::debug!("{:?}", state);
|
||||||
|
|
||||||
serialise_state(state.deactivate(&|path| {
|
serialise_state(state.deactivate(&|path, status| {
|
||||||
try_delete_path(path)
|
log::debug!("Deactivating: {}", path.display());
|
||||||
|
try_delete_path(path, status)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
log::error!("Error deleting path: {}", path.display());
|
log::error!("Error deleting path: {}", path.display());
|
||||||
log::error!("{e}");
|
log::error!("{e}");
|
||||||
|
|
@ -114,7 +115,7 @@ pub fn deactivate() -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_delete_path(path: &Path) -> Result<()> {
|
fn try_delete_path(path: &Path, status: &EtcFileStatus) -> Result<()> {
|
||||||
// exists() returns false for broken symlinks
|
// exists() returns false for broken symlinks
|
||||||
if path.exists() || path.is_symlink() {
|
if path.exists() || path.is_symlink() {
|
||||||
if path.is_symlink() {
|
if path.is_symlink() {
|
||||||
|
|
@ -122,7 +123,14 @@ fn try_delete_path(path: &Path) -> Result<()> {
|
||||||
} else if path.is_file() {
|
} else if path.is_file() {
|
||||||
remove_file(path)
|
remove_file(path)
|
||||||
} else if path.is_dir() {
|
} else if path.is_dir() {
|
||||||
|
if path.read_dir()?.next().is_none() {
|
||||||
remove_dir(path)
|
remove_dir(path)
|
||||||
|
} else {
|
||||||
|
if let EtcFileStatus::Managed = status {
|
||||||
|
log::warn!("Managed directory not empty, ignoring: {}", path.display());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!("Unsupported file type! {}", path.display()))
|
Err(anyhow!("Unsupported file type! {}", path.display()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ impl EtcTree {
|
||||||
|
|
||||||
pub fn deactivate<F>(self, delete_action: &F) -> Option<EtcTree>
|
pub fn deactivate<F>(self, delete_action: &F) -> Option<EtcTree>
|
||||||
where
|
where
|
||||||
F: Fn(&Path) -> bool,
|
F: Fn(&Path, &EtcFileStatus) -> bool,
|
||||||
{
|
{
|
||||||
let new_tree = self.nested.keys().fold(self.clone(), |mut new_tree, name| {
|
let new_tree = self.nested.keys().fold(self.clone(), |mut new_tree, name| {
|
||||||
new_tree.nested = new_tree.nested.alter(
|
new_tree.nested = new_tree.nested.alter(
|
||||||
|
|
@ -165,7 +165,7 @@ impl EtcTree {
|
||||||
// closure on their paths).
|
// closure on their paths).
|
||||||
if new_tree.nested.is_empty() {
|
if new_tree.nested.is_empty() {
|
||||||
if let EtcFileStatus::Managed = new_tree.status {
|
if let EtcFileStatus::Managed = new_tree.status {
|
||||||
if delete_action(&new_tree.path) {
|
if delete_action(&new_tree.path, &new_tree.status) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(new_tree)
|
Some(new_tree)
|
||||||
|
|
@ -180,7 +180,7 @@ impl EtcTree {
|
||||||
|
|
||||||
pub fn update_state<F>(self, other: Self, delete_action: &F) -> Option<Self>
|
pub fn update_state<F>(self, other: Self, delete_action: &F) -> Option<Self>
|
||||||
where
|
where
|
||||||
F: Fn(&Path) -> bool,
|
F: Fn(&Path, &EtcFileStatus) -> bool,
|
||||||
{
|
{
|
||||||
let to_deactivate = other
|
let to_deactivate = other
|
||||||
.nested
|
.nested
|
||||||
|
|
@ -235,7 +235,7 @@ mod tests {
|
||||||
impl EtcTree {
|
impl EtcTree {
|
||||||
pub fn deactivate_managed_entry<F>(self, path: &Path, delete_action: &F) -> Self
|
pub fn deactivate_managed_entry<F>(self, path: &Path, delete_action: &F) -> Self
|
||||||
where
|
where
|
||||||
F: Fn(&Path) -> bool,
|
F: Fn(&Path, &EtcFileStatus) -> bool,
|
||||||
{
|
{
|
||||||
fn go<'a, C, F>(
|
fn go<'a, C, F>(
|
||||||
mut tree: EtcTree,
|
mut tree: EtcTree,
|
||||||
|
|
@ -245,7 +245,7 @@ mod tests {
|
||||||
) -> EtcTree
|
) -> EtcTree
|
||||||
where
|
where
|
||||||
C: Iterator<Item = path::Component<'a>>,
|
C: Iterator<Item = path::Component<'a>>,
|
||||||
F: Fn(&Path) -> bool,
|
F: Fn(&Path, &EtcFileStatus) -> bool,
|
||||||
{
|
{
|
||||||
log::debug!("Deactivating {}", path.display());
|
log::debug!("Deactivating {}", path.display());
|
||||||
|
|
||||||
|
|
@ -368,22 +368,25 @@ mod tests {
|
||||||
.register_managed_entry(&PathBuf::from("/").join("foo5").join("baz").join("bar"));
|
.register_managed_entry(&PathBuf::from("/").join("foo5").join("baz").join("bar"));
|
||||||
let tree2 = tree1
|
let tree2 = tree1
|
||||||
.clone()
|
.clone()
|
||||||
.deactivate_managed_entry(&PathBuf::from("/").join("foo4"), &|p| {
|
.deactivate_managed_entry(&PathBuf::from("/").join("foo4"), &|path, _status| {
|
||||||
println!("Deactivating: {}", p.display());
|
println!("Deactivating: {}", path.display());
|
||||||
false
|
false
|
||||||
})
|
})
|
||||||
.deactivate_managed_entry(&PathBuf::from("/").join("foo2"), &|p| {
|
.deactivate_managed_entry(&PathBuf::from("/").join("foo2"), &|path, _status| {
|
||||||
println!("Deactivating: {}", p.display());
|
println!("Deactivating: {}", path.display());
|
||||||
true
|
true
|
||||||
})
|
})
|
||||||
.deactivate_managed_entry(&PathBuf::from("/").join("foo3"), &|p| {
|
.deactivate_managed_entry(&PathBuf::from("/").join("foo3"), &|path, _status| {
|
||||||
println!("Deactivating: {}", p.display());
|
println!("Deactivating: {}", path.display());
|
||||||
true
|
true
|
||||||
})
|
})
|
||||||
.deactivate_managed_entry(&PathBuf::from("/").join("foo5").join("baz"), &|p| {
|
.deactivate_managed_entry(
|
||||||
println!("Deactivating: {}", p.display());
|
&PathBuf::from("/").join("foo5").join("baz"),
|
||||||
|
&|path, _status| {
|
||||||
|
println!("Deactivating: {}", path.display());
|
||||||
true
|
true
|
||||||
});
|
},
|
||||||
|
);
|
||||||
dbg!(&tree1);
|
dbg!(&tree1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree2.nested.keys().sorted().collect::<Vec<_>>(),
|
tree2.nested.keys().sorted().collect::<Vec<_>>(),
|
||||||
|
|
@ -424,7 +427,7 @@ mod tests {
|
||||||
.register_managed_entry(&PathBuf::from("/").join("foo4").join("bar"))
|
.register_managed_entry(&PathBuf::from("/").join("foo4").join("bar"))
|
||||||
.register_managed_entry(&PathBuf::from("/").join("foo5"))
|
.register_managed_entry(&PathBuf::from("/").join("foo5"))
|
||||||
.register_managed_entry(&PathBuf::from("/").join("foo5").join("bar"));
|
.register_managed_entry(&PathBuf::from("/").join("foo5").join("bar"));
|
||||||
let new_tree = tree1.update_state(tree2, &|path| {
|
let new_tree = tree1.update_state(tree2, &|path, _status| {
|
||||||
println!("Deactivating path: {}", path.display());
|
println!("Deactivating path: {}", path.display());
|
||||||
path != PathBuf::from("/").join("foo5").join("bar").as_path()
|
path != PathBuf::from("/").join("foo5").join("bar").as_path()
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue