[FEATURE REQUEST] Provide `file.absent` with `removedirs` option
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 15.7k
- Forks
- 5.6k
- Avg merge
- 2d 44m
- Merged PRs (30d)
- 80
Description
Is your feature request related to a problem? Please describe.
file.managed does support makedirs: True for creating the directories need to write a file. When that file is no longer needed, file.absent can remove that file, but all directories are kept.
Describe the solution you'd like
I'd like to have a removedirs: True option on file.absent that works like Python's os.removedirs() function and removes all empty parent directories after removing the file.
/path/to/file.txt:
file.absent:
- removedirs: True
This also looks very symmetrical to file.managed with makedirs: True.
Describe alternatives you've considered
The most common solution mentioned is using file.absent on the parent directory with unless: and some glob check, but that has many edge cases. Just running a /path/to/* glob often will not detect .hidden files, and it only works for a single directory level. A custom state could be added, but needs to be maintained separately:
# vim: ft=python:sw=4
import os
def _each_parent(name):
head, tail = os.path.split(name)
if not tail:
head, tail = os.path.split(head)
while head and tail:
yield head
head, tail = os.path.split(head)
def absent(name, removedirs=True):
"""
Ensures the given file path is removed, and all empty parent directories are
removed too.
"""
ret = __states__["file.absent"](name)
if "removed" in ret["changes"]:
ret["changes"]["removed"] = [ret["changes"]["removed"]]
if not removedirs or ret["result"] == False:
return ret
# Clean up empty parent directories
for path in _each_parent(name):
try:
if not os.path.isdir(path) or len(os.listdir(path)) > 0:
break
if "removed" not in ret["changes"]:
ret["changes"]["removed"] = []
ret["changes"]["removed"].append(path)
if __opts__["test"]:
ret["result"] = None
else:
os.rmdir(path)
except OSError:
break
return ret
(This one does not change the comment, but extends the state diff with deleted parent directories.)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the file.absent and file.managed state entry points and compare the requested behavior with Python's os.removedirs() and the custom absent state shown in the issue. Done means file.absent accepts removedirs: True, removes empty parent directories after the target, and preserves existing behavior when the option is not enabled.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devops, infrastructure
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100