makefiles-cli 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,113 @@
1
+ import pathlib
2
+ import shutil
3
+
4
+ import makefiles.exceptions as exceptions
5
+ import makefiles.types as custom_types
6
+ import makefiles.utils as utils
7
+ import makefiles.utils.cli_io as cli_io
8
+
9
+
10
+ def _remove_path(path: pathlib.Path) -> None:
11
+ """
12
+ Remove/Unlink `path` recursively.
13
+ """
14
+ try:
15
+ if utils.isfile(path) or utils.islink(path) or utils.isbrokenlink(path):
16
+ path.unlink(missing_ok=True)
17
+ elif utils.isdir(path):
18
+ shutil.rmtree(path)
19
+ except FileNotFoundError:
20
+ pass
21
+
22
+
23
+ def copy(
24
+ src: pathlib.Path,
25
+ *dests: pathlib.Path,
26
+ overwrite: bool = False,
27
+ parents: bool = False,
28
+ ) -> custom_types.ExitCode:
29
+ """
30
+ Copies a source file or symbolic link to one or more destination paths.
31
+
32
+ Args:
33
+ src (pathlib.Path): Path to the source file. Must be a regular file or a symlink to a file.
34
+ *dests (pathlib.Path): One or more destination paths to copy the source to.
35
+ overwrite (bool, optional): If True, existing destination files will be overwritten.
36
+ If False (default), print an error message and be skip.
37
+ parents (bool, optional): If True, create parent(s) if not already exists.
38
+ If False (default), print an error message and skip.
39
+
40
+ Returns:
41
+ custom_types.ExitCode: Exit code 0 if all copies succeed.
42
+ Returns 1 if any destination exists and overwrite is False.
43
+
44
+ Raises:
45
+ makefiles.exceptions.SourceNotFoundError: If the source path does not exist.
46
+ makefiles.exceptions.InvalidSourceError: If the source is not a file or a symbolic link to a file.
47
+ """
48
+ exitcode: custom_types.ExitCode = custom_types.ExitCode(0)
49
+
50
+ if not utils.exists(src):
51
+ raise exceptions.SourceNotFoundError(f"source {str(src)} does not exists")
52
+ elif not (utils.isfile(src) or utils.islinkf(src)):
53
+ raise exceptions.InvalidSourceError(f"source {str(src)} is not a file or a link to file")
54
+
55
+ for dest in dests:
56
+ if utils.exists(dest) and not overwrite:
57
+ cli_io.eprint(f"destination {str(dest)} already exists\n")
58
+ exitcode = custom_types.ExitCode(1) or exitcode
59
+ continue
60
+
61
+ dest_parent: pathlib.Path = dest.parent
62
+ if not (utils.isdir(dest_parent) or utils.islinkd(dest_parent)) and not parents:
63
+ cli_io.eprint(f"parent dir {str(dest_parent)} does not exists\n")
64
+ exitcode = custom_types.ExitCode(1) or exitcode
65
+ continue
66
+
67
+ _remove_path(dest)
68
+ dest_parent.mkdir(parents=True, exist_ok=True)
69
+
70
+ shutil.copyfile(src, dest, follow_symlinks=True)
71
+
72
+ return exitcode
73
+
74
+
75
+ def create_empty_files(
76
+ *paths: pathlib.Path,
77
+ overwrite: bool = False,
78
+ parents: bool = False,
79
+ ) -> custom_types.ExitCode:
80
+ """
81
+ Creates empty files at the specified paths, optionally overwriting existing files or directories.
82
+
83
+ Args:
84
+ *paths (pathlib.Path): One or more paths where empty files should be created.
85
+ overwrite (bool, optional): If True, existing destination files will be overwritten.
86
+ If False (default), print an error message and be skip.
87
+ parents (bool, optional): If True, create parent(s) if not already exists.
88
+ If False (default), print an error message and skip.
89
+
90
+ Returns:
91
+ makefiles.types.ExitCode: Exit code 0 on full success.
92
+ Exit code 1 if any file already exists and overwrite is False.
93
+ """
94
+ exitcode: custom_types.ExitCode = custom_types.ExitCode(0)
95
+
96
+ for path in paths:
97
+ if utils.exists(path) and not overwrite:
98
+ cli_io.eprint(f"destination {path} already exists\n")
99
+ exitcode = custom_types.ExitCode(1) or exitcode
100
+ continue
101
+
102
+ path_parent: pathlib.Path = path.parent
103
+ if not (utils.isdir(path_parent) or utils.islinkd(path_parent)) and not parents:
104
+ cli_io.eprint(f"parent dir {str(path_parent)} does not exists\n")
105
+ exitcode = custom_types.ExitCode(1) or exitcode
106
+ continue
107
+
108
+ _remove_path(path)
109
+ path_parent.mkdir(parents=True, exist_ok=True)
110
+
111
+ path.touch(exist_ok=False)
112
+
113
+ return exitcode
@@ -0,0 +1,7 @@
1
+ from makefiles.utils.picker.fzf import prompt as fzf
2
+ from makefiles.utils.picker.manual import prompt as manual
3
+
4
+ __all__: list[str] = [
5
+ "fzf",
6
+ "manual",
7
+ ]
@@ -0,0 +1,48 @@
1
+ import shutil
2
+ import subprocess
3
+
4
+ import makefiles.exceptions as exceptions
5
+ import makefiles.types as custom_types
6
+
7
+ FZF_DEFAULT_FLAGS: list[str] = [
8
+ "--style=minimal",
9
+ "--info=hidden",
10
+ "--keep-right",
11
+ ]
12
+
13
+
14
+ def prompt(options: list[str], *, height: custom_types.NaturalNumber = custom_types.NaturalNumber(10)) -> str:
15
+ """
16
+ Displays an interactive fuzzy-selection prompt using `fzf` and returns the user's selection.
17
+
18
+ Args:
19
+ options (list[str]): A list of string options to display in the selection interface.
20
+ height (custom_types.NaturalNumber, optional): Approximate terminal height percentage for the `fzf` UI.
21
+ Defaults to 10. The value is interpreted as `--height=~<value>` by `fzf`.
22
+
23
+ Returns:
24
+ str: The selected option as returned by `fzf`, with trailing newline removed.
25
+
26
+ Raises:
27
+ exceptions.FZFNotFoundError: If the `fzf` binary is not found in the system PATH.
28
+ KeyboardInterrupt: If the user interrupts the prompt using Ctrl+C (fzf returns exit code 130).
29
+ exceptions.FZFError: If `fzf` exits with a non-zero return code other than 130.
30
+ """
31
+ if not shutil.which("fzf"):
32
+ raise exceptions.FZFNotFoundError("`fzf` is not found in path")
33
+
34
+ options_str: str = "\n".join(options)
35
+
36
+ process: subprocess.CompletedProcess = subprocess.run(
37
+ ["fzf", *FZF_DEFAULT_FLAGS, f"--height=~{int(height)}"],
38
+ input=options_str,
39
+ text=True,
40
+ capture_output=True,
41
+ )
42
+
43
+ if process.returncode != 0:
44
+ if process.returncode == 130:
45
+ raise KeyboardInterrupt
46
+ raise exceptions.FZFError("`fzf` command returned non zero exit code")
47
+
48
+ return process.stdout.strip("\n")
@@ -0,0 +1,29 @@
1
+ import makefiles.types as custom_types
2
+ import makefiles.utils.cli_io as cli_io
3
+
4
+
5
+ def prompt(options: list[str]) -> str:
6
+ """
7
+ Displays a numbered list of options and prompts the user to select one via keyboard input.
8
+
9
+ Args:
10
+ options (list[str]): A list of string options to present to the user for selection.
11
+
12
+ Returns:
13
+ str: The selected option from the list, based on user input.
14
+ """
15
+ options = sorted(options) # do not modify the parameter
16
+
17
+ for index, option in enumerate(options, start=1):
18
+ cli_io.print(f"[{index}]: {option}\n")
19
+
20
+ while True:
21
+ try:
22
+ cli_io.print("Choose a template: ")
23
+ choice: custom_types.NaturalNumber = custom_types.NaturalNumber(cli_io.input())
24
+ assert choice <= len(options)
25
+ break
26
+ except (ValueError, TypeError, AssertionError):
27
+ cli_io.eprint("Please insert a valid input\n")
28
+
29
+ return options[choice - 1]
@@ -0,0 +1,8 @@
1
+ #!python
2
+
3
+ import sys
4
+
5
+ from makefiles.mkfile import main
6
+
7
+ if __name__ == "__main__":
8
+ sys.exit(main())
@@ -0,0 +1,69 @@
1
+ Metadata-Version: 2.4
2
+ Name: makefiles-cli
3
+ Version: 1.0.0
4
+ Summary: A lightweight Python utility for file creation and template generation from XDG_TEMPLATES_DIR
5
+ License-Expression: GPL-3.0-only
6
+ Project-URL: Homepage, https://github.com/Rid1FZ/makefiles-cli
7
+ Keywords: makefiles,mkfiles,mkfile,makefiles-cli,mkfile-cli
8
+ Classifier: Programming Language :: Python :: 3.10
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Operating System :: POSIX :: Linux
13
+ Classifier: Environment :: Console
14
+ Classifier: Typing :: Typed
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Dynamic: license-file
19
+
20
+ # makefiles-cli - Command line interface for XDG_TEMPLATES_DIR
21
+
22
+ `makefiles-cli` is a simple commandline tool to create files and templates. It can create one or more empty files or any template defined in `XDG_TEMPLATES_DIR`. It also has support for [fzf](https://github.com/junegunn/fzf) to make it easier to find template.
23
+
24
+ ## Usage
25
+
26
+ Create empty files:
27
+
28
+ ```bash
29
+ mkfile example1 example2
30
+ ```
31
+
32
+ List all available templates:
33
+
34
+ ```bash
35
+ mkfile --list
36
+ ```
37
+
38
+ Create template from any template defined in `XDG_TEMPLATES_DIR`:
39
+
40
+ ```bash
41
+ mkfile script.py --template="pyscript.py"
42
+ ```
43
+
44
+ Create template using `fzf` as picker to pick template interactively:
45
+
46
+ ```bash
47
+ mkfile script.py --template --picker="fzf"
48
+ ```
49
+
50
+ Run `mkfile --help` for all the available options.
51
+
52
+ ## Installation
53
+
54
+ _Requirements_:
55
+
56
+ - python3 (python3.10 or greater)
57
+ - pip
58
+
59
+ You can install `makefiles-cli` directly from **PyPI** using `pip`:
60
+
61
+ ```bash
62
+ pip install makefiles-cli
63
+ ```
64
+
65
+ Or if you love to stay on bleeding edge, install directly from github:
66
+
67
+ ```bash
68
+ pip install git+https://github.com/Rid1FZ/makefiles-cli
69
+ ```
@@ -0,0 +1,19 @@
1
+ makefiles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ makefiles/_version.py,sha256=fo5PXsZuloQZu3LdpIFTUAXvJmY2L9N5sNGe2tvdU98,511
3
+ makefiles/cli_parser.py,sha256=cCpL3sR7pQkbh8J2YyNYFXYs5EYDuciLBQID7ghQbPk,2041
4
+ makefiles/exceptions.py,sha256=oQXWabm6iFFmSpsSZRp1Q6Fmlgl-NmKVInPQlFmrBkg,2034
5
+ makefiles/mkfile.py,sha256=YlOFs7mpd0deDHP-auSnmBet8AYQPk84-Eu9--d1aHY,4041
6
+ makefiles/types.py,sha256=f52KuUyNpKLdn2V8EWdL2zaz60zK9PDsUuVyGkdnX-w,2479
7
+ makefiles/utils/__init__.py,sha256=UPjxn9bLa6qtWGZGrLseGiCQPRGPPh4p8rX40KoK-nk,3870
8
+ makefiles/utils/cli_io.py,sha256=hWWsiE5pdyJtl4_MKK15hRckdG6YHwAbIppUWOhTHo4,2561
9
+ makefiles/utils/dirwalker.py,sha256=nRJaAzbXT5VOAjZMl97B7jlFo5U962YGeDd2OU476_s,1225
10
+ makefiles/utils/fileutils.py,sha256=9yfbbofwWSxqQhTqSstkme-hZICyCGv_DFSHNTmsIbU,4301
11
+ makefiles/utils/picker/__init__.py,sha256=PLvX88I1vEer2-fnM7vOPk0RnSsmg4flc-ak5qSvpq0,163
12
+ makefiles/utils/picker/fzf.py,sha256=pjXRyQP7s7z-Ev8zM_h6mNsRCWECKrXDUI1kdCCO1p4,1714
13
+ makefiles/utils/picker/manual.py,sha256=IejYYqLDUwaRVAYTKA3VHR5zDaWJFbbQzKLlmN5SPJY,957
14
+ makefiles_cli-1.0.0.data/scripts/mkfile,sha256=tBmA2Skc-0YD8uq_DxdLmxPLUQpGspPR1xHzQRUL968,105
15
+ makefiles_cli-1.0.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
16
+ makefiles_cli-1.0.0.dist-info/METADATA,sha256=9gtQHcMrMH866G2q21DpHhYltoOpfz1EoH1AE2RMwIo,1816
17
+ makefiles_cli-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
18
+ makefiles_cli-1.0.0.dist-info/top_level.txt,sha256=_LWvFR-XPibPQepQ4yMZlEJyTQZgOtjVo1m0V9GFcxw,10
19
+ makefiles_cli-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+