Skip to content

Commit c8d590a

Browse files
committed
first dev release
1 parent 09b681a commit c8d590a

5 files changed

Lines changed: 113 additions & 3 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
[build-system]
32
requires = ["setuptools>=61.0", "versioningit"]
43
build-backend = "setuptools.build_meta"
@@ -15,8 +14,7 @@ namespaces = true
1514

1615

1716
# ----------------------------------------- Project Metadata -------------------------------------
18-
#
1917
[project]
20-
version = "0.0.0.dev0"
18+
version = "0.0.0.dev1"
2119
name = "FileEx"
2220
requires-python = ">=3.10"

src/fileex/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
"""FileEx"""
22

3+
from fileex import exception, directory, search

src/fileex/directory.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from pathlib import Path as _Path
2+
import shutil as _shutil
3+
4+
from fileex import exception as _exception
5+
6+
7+
def delete_contents(
8+
path: str | _Path, exclude: list[str] | None = None, raise_existence: bool = True
9+
) -> list[str] | None:
10+
"""
11+
Delete all files and directories within a given directory,
12+
excluding those specified by `exclude`.
13+
14+
Parameters
15+
----------
16+
path : str | pathlib.Path
17+
Path to the directory whose content should be deleted.
18+
exclude : list[str] | None, default: None
19+
List of file and directory names to exclude from deletion.
20+
raise_existence : bool, default: True
21+
Raise an error when the directory does not exist.
22+
23+
Returns
24+
-------
25+
deleted_names : list[str] | None
26+
Names of the files and directories that were deleted,
27+
or None if the directory does not exist and `raise_existence` is set to False.
28+
29+
Raises
30+
------
31+
fileex.exception.FileExPathNotFoundError
32+
If the directory does not exist and `raise_existence` is set to True.
33+
"""
34+
path = _Path(path)
35+
if not path.is_dir():
36+
if raise_existence:
37+
raise _exception.FileExPathNotFoundError(path, is_dir=True)
38+
return
39+
if not exclude:
40+
exclude = []
41+
deleted_names = []
42+
for item in path.iterdir():
43+
if item.name not in exclude:
44+
deleted_names.append(item.name)
45+
item.unlink() if item.is_file() else _shutil.rmtree(item)
46+
return deleted_names

src/fileex/exception.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from pathlib import Path as _Path
2+
3+
4+
class FileExError(Exception):
5+
"""Base class for all FileEx errors."""
6+
def __init__(self, message: str):
7+
super().__init__(message)
8+
self.message = message
9+
return
10+
11+
12+
class FileExInputError(FileExError):
13+
"""Error in the input arguments provided to FileEx methods."""
14+
def __init__(self, message: str):
15+
super().__init__(message)
16+
return
17+
18+
19+
class FileExPathNotFoundError(FileExError):
20+
"""The given path does not exist."""
21+
def __init__(self, path: _Path, is_dir: bool):
22+
self.path = path
23+
message = f"No {'directory' if is_dir else 'file'} found at '{path}'."
24+
super().__init__(message)
25+
return

src/fileex/search.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from pathlib import Path as _Path
2+
3+
from fileex import exception as _exception
4+
5+
6+
def path_in_hierarchy(
7+
path: str | _Path,
8+
leaf_dir: str | _Path = ".",
9+
root_dir: str | _Path = "/",
10+
) -> _Path | None:
11+
"""Find a path in the directory hierarchy.
12+
13+
Parameters
14+
----------
15+
path : str | pathlib.Path
16+
Relative path to the file or directory to find.
17+
leaf_dir : str | pathlib.Path, default: "."
18+
Directory to start the search from.
19+
root_dir : str | pathlib.Path, default: "/"
20+
Directory to stop the search at.
21+
This must be an ancestor of `leaf_dir`.
22+
23+
Returns
24+
-------
25+
path : pathlib.Path | None
26+
Absolute path to the file or directory if found, else None.
27+
"""
28+
path = _Path(path)
29+
leaf_dir = _Path(leaf_dir).resolve()
30+
root_dir = _Path(root_dir).resolve()
31+
try:
32+
leaf_dir.relative_to(root_dir)
33+
except ValueError:
34+
raise _exception.FileExInputError("Input argument 'leaf_dir' must be a descendant of 'root_dir'.")
35+
while leaf_dir != root_dir:
36+
possible_path = leaf_dir / path
37+
if possible_path.exists():
38+
return possible_path
39+
leaf_dir = leaf_dir.parent
40+
return

0 commit comments

Comments
 (0)