biscuitcutter 1.0.0__tar.gz

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,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Erdogan Taskesen
4
+ biscuitcutter - Python package
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ include biscuitcutter/template.zip
@@ -0,0 +1,130 @@
1
+ Metadata-Version: 2.4
2
+ Name: biscuitcutter
3
+ Version: 1.0.0
4
+ Summary: biscuitcutter – scaffold a new Python repo from a template in seconds.
5
+ Author-email: Erdogan Taskesen <erdogant@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://erdogant.github.io/biscuitcutter
8
+ Project-URL: Download, https://github.com/erdogant/biscuitcutter/archive/{version}.tar.gz
9
+ Keywords: Python,biscuitcutter,templates,scaffolding,cookiecutter
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Education
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Operating System :: Unix
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Operating System :: OS Independent
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Dynamic: license-file
22
+
23
+ [![Python](https://img.shields.io/pypi/pyversions/biscuitcutter)](https://img.shields.io/pypi/pyversions/biscuitcutter)
24
+ [![Pypi](https://img.shields.io/pypi/v/biscuitcutter)](https://pypi.org/project/biscuitcutter/)
25
+ [![Docs](https://img.shields.io/badge/Sphinx-Docs-Green)](https://erdogant.github.io/biscuitcutter/)
26
+ [![LOC](https://sloc.xyz/github/erdogant/biscuitcutter/?category=code)](https://github.com/erdogant/biscuitcutter/)
27
+ [![Downloads](https://static.pepy.tech/personalized-badge/biscuitcutter?period=month&units=international_system&left_color=grey&right_color=brightgreen&left_text=PyPI%20downloads/month)](https://pepy.tech/project/biscuitcutter)
28
+ [![Downloads](https://static.pepy.tech/personalized-badge/biscuitcutter?period=total&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/biscuitcutter)
29
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/erdogant/biscuitcutter/blob/master/LICENSE)
30
+ [![Forks](https://img.shields.io/github/forks/erdogant/biscuitcutter.svg)](https://github.com/erdogant/biscuitcutter/network)
31
+ [![Issues](https://img.shields.io/github/issues/erdogant/biscuitcutter.svg)](https://github.com/erdogant/biscuitcutter/issues)
32
+ [![Project Status](http://www.repostatus.org/badges/latest/active.svg)](http://www.repostatus.org/#active)
33
+
34
+ <div>
35
+ <a href="https://erdogant.github.io/biscuitcutter/">
36
+ <img src="https://raw.githubusercontent.com/erdogant/biscuitcutter/master/docs/figs/logo.png"
37
+ width="250"
38
+ align="left" />
39
+ </a>
40
+ <strong>biscuitcutter</strong> is a new repository scaffolder for Python projects.
41
+
42
+ Create a new Python package or repository with a single command! ⭐️Star it if you like it⭐️
43
+ </div>
44
+
45
+ ---
46
+
47
+ ### Key Features
48
+
49
+ | Feature | Description |
50
+ |--------|-------------|
51
+ | [**Interactive CLI**](https://erdogant.github.io/biscuitcutter/pages/html/Installation.html) | Scaffold a new Python repository with prompts for repo name, author info, and more. |
52
+ | [**Template-Based**](https://erdogant.github.io/biscuitcutter/) | Uses a pre-configured template to create a ready-to-use project structure. |
53
+ | [**Placeholder Replacement**](https://erdogant.github.io/biscuitcutter/) | Automatically replaces placeholders (repo name, author, email, GitHub username) in all files. |
54
+
55
+ ---
56
+
57
+ ### Resources and Links
58
+ - **Documentation:** [Website](https://erdogant.github.io/biscuitcutter)
59
+ - **Bug Reports and Feature Requests:** [GitHub Issues](https://github.com/erdogant/biscuitcutter/issues)
60
+
61
+ ---
62
+
63
+ ### Installation
64
+
65
+ ##### Install biscuitcutter from PyPI
66
+ ```bash
67
+ pip install biscuitcutter
68
+ ```
69
+ ---
70
+
71
+ ### Usage
72
+
73
+ After installation, run the interactive CLI:
74
+
75
+ ```bash
76
+ biscuitcutter
77
+ ```
78
+
79
+ This will prompt you for:
80
+
81
+ - **Repository / package name** (required)
82
+ - **Author full name** (required)
83
+ - **Author e-mail** (optional)
84
+ - **GitHub username** (optional, defaults to lowercase author name without spaces)
85
+ - **Parent directory** (optional, defaults to current directory)
86
+
87
+ Alternatively, you can import and call the main function directly:
88
+
89
+ ```python
90
+ from biscuitcutter import main
91
+ main()
92
+ ```
93
+
94
+ ---
95
+
96
+ ### Example Session
97
+
98
+ ```console
99
+ 🍪 biscuitcutter – new repo scaffolder
100
+
101
+ ───────────────────────────────────────────
102
+ Repository / package name: my_project
103
+ Author full name: Erdogan Taskesen
104
+ Author e-mail: erdogant@gmail.com
105
+ GitHub username: erdogant
106
+ Parent directory (leave blank for current dir):
107
+
108
+ ✔ Created directory: /path/to/my_project
109
+ ✔ Template extracted to: /path/to/my_project
110
+ ✔ Placeholders replaced.
111
+
112
+ 🎉 Done! Your new repo is ready at:
113
+ /path/to/my_project
114
+ ```
115
+
116
+ ---
117
+
118
+ ### Contributors
119
+
120
+ Setting up and maintaining biscuitcutter has been possible thanks to users and contributors. Thanks to:
121
+
122
+ <p align="left">
123
+ <a href="https://github.com/erdogant/biscuitcutter/graphs/contributors">
124
+ <img src="https://contrib.rocks/image?repo=erdogant/biscuitcutter" />
125
+ </a>
126
+ </p>
127
+
128
+ ### Maintainer
129
+ * Erdogan Taskesen, github: [erdogant](https://github.com/erdogant)
130
+ * Contributions are welcome.
@@ -0,0 +1,108 @@
1
+ [![Python](https://img.shields.io/pypi/pyversions/biscuitcutter)](https://img.shields.io/pypi/pyversions/biscuitcutter)
2
+ [![Pypi](https://img.shields.io/pypi/v/biscuitcutter)](https://pypi.org/project/biscuitcutter/)
3
+ [![Docs](https://img.shields.io/badge/Sphinx-Docs-Green)](https://erdogant.github.io/biscuitcutter/)
4
+ [![LOC](https://sloc.xyz/github/erdogant/biscuitcutter/?category=code)](https://github.com/erdogant/biscuitcutter/)
5
+ [![Downloads](https://static.pepy.tech/personalized-badge/biscuitcutter?period=month&units=international_system&left_color=grey&right_color=brightgreen&left_text=PyPI%20downloads/month)](https://pepy.tech/project/biscuitcutter)
6
+ [![Downloads](https://static.pepy.tech/personalized-badge/biscuitcutter?period=total&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/biscuitcutter)
7
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/erdogant/biscuitcutter/blob/master/LICENSE)
8
+ [![Forks](https://img.shields.io/github/forks/erdogant/biscuitcutter.svg)](https://github.com/erdogant/biscuitcutter/network)
9
+ [![Issues](https://img.shields.io/github/issues/erdogant/biscuitcutter.svg)](https://github.com/erdogant/biscuitcutter/issues)
10
+ [![Project Status](http://www.repostatus.org/badges/latest/active.svg)](http://www.repostatus.org/#active)
11
+
12
+ <div>
13
+ <a href="https://erdogant.github.io/biscuitcutter/">
14
+ <img src="https://raw.githubusercontent.com/erdogant/biscuitcutter/master/docs/figs/logo.png"
15
+ width="250"
16
+ align="left" />
17
+ </a>
18
+ <strong>biscuitcutter</strong> is a new repository scaffolder for Python projects.
19
+
20
+ Create a new Python package or repository with a single command! ⭐️Star it if you like it⭐️
21
+ </div>
22
+
23
+ ---
24
+
25
+ ### Key Features
26
+
27
+ | Feature | Description |
28
+ |--------|-------------|
29
+ | [**Interactive CLI**](https://erdogant.github.io/biscuitcutter/pages/html/Installation.html) | Scaffold a new Python repository with prompts for repo name, author info, and more. |
30
+ | [**Template-Based**](https://erdogant.github.io/biscuitcutter/) | Uses a pre-configured template to create a ready-to-use project structure. |
31
+ | [**Placeholder Replacement**](https://erdogant.github.io/biscuitcutter/) | Automatically replaces placeholders (repo name, author, email, GitHub username) in all files. |
32
+
33
+ ---
34
+
35
+ ### Resources and Links
36
+ - **Documentation:** [Website](https://erdogant.github.io/biscuitcutter)
37
+ - **Bug Reports and Feature Requests:** [GitHub Issues](https://github.com/erdogant/biscuitcutter/issues)
38
+
39
+ ---
40
+
41
+ ### Installation
42
+
43
+ ##### Install biscuitcutter from PyPI
44
+ ```bash
45
+ pip install biscuitcutter
46
+ ```
47
+ ---
48
+
49
+ ### Usage
50
+
51
+ After installation, run the interactive CLI:
52
+
53
+ ```bash
54
+ biscuitcutter
55
+ ```
56
+
57
+ This will prompt you for:
58
+
59
+ - **Repository / package name** (required)
60
+ - **Author full name** (required)
61
+ - **Author e-mail** (optional)
62
+ - **GitHub username** (optional, defaults to lowercase author name without spaces)
63
+ - **Parent directory** (optional, defaults to current directory)
64
+
65
+ Alternatively, you can import and call the main function directly:
66
+
67
+ ```python
68
+ from biscuitcutter import main
69
+ main()
70
+ ```
71
+
72
+ ---
73
+
74
+ ### Example Session
75
+
76
+ ```console
77
+ 🍪 biscuitcutter – new repo scaffolder
78
+
79
+ ───────────────────────────────────────────
80
+ Repository / package name: my_project
81
+ Author full name: Erdogan Taskesen
82
+ Author e-mail: erdogant@gmail.com
83
+ GitHub username: erdogant
84
+ Parent directory (leave blank for current dir):
85
+
86
+ ✔ Created directory: /path/to/my_project
87
+ ✔ Template extracted to: /path/to/my_project
88
+ ✔ Placeholders replaced.
89
+
90
+ 🎉 Done! Your new repo is ready at:
91
+ /path/to/my_project
92
+ ```
93
+
94
+ ---
95
+
96
+ ### Contributors
97
+
98
+ Setting up and maintaining biscuitcutter has been possible thanks to users and contributors. Thanks to:
99
+
100
+ <p align="left">
101
+ <a href="https://github.com/erdogant/biscuitcutter/graphs/contributors">
102
+ <img src="https://contrib.rocks/image?repo=erdogant/biscuitcutter" />
103
+ </a>
104
+ </p>
105
+
106
+ ### Maintainer
107
+ * Erdogan Taskesen, github: [erdogant](https://github.com/erdogant)
108
+ * Contributions are welcome.
@@ -0,0 +1,42 @@
1
+ import logging
2
+
3
+ # We import 'main' instead of 'biscuitcutter' since that is the actual entry point in your script.
4
+ from biscuitcutter.biscuitcutter import main
5
+
6
+ __author__ = 'Erdogan Taskesen'
7
+ __email__ = 'erdogant@gmail.com'
8
+ __version__ = '1.0.0'
9
+
10
+ # Setup package-level logger
11
+ _logger = logging.getLogger('biscuitcutter')
12
+ _log_handler = logging.StreamHandler()
13
+ _formatter = logging.Formatter(fmt='[{asctime}] [{name:<12.12}] [{levelname:<8}] {message}', style='{', datefmt='%d-%m-%Y %H:%M:%S')
14
+ _log_handler.setFormatter(_formatter)
15
+ _log_handler.setLevel(logging.DEBUG)
16
+ if not _logger.hasHandlers(): # avoid duplicate handlers if re-imported
17
+ _logger.addHandler(_log_handler)
18
+ _logger.setLevel(logging.DEBUG)
19
+ _logger.propagate = True # allow submodules to inherit this handler
20
+
21
+
22
+ # module level doc-string
23
+ __doc__ = """
24
+ biscuitcutter
25
+ =====================================================================
26
+
27
+ biscuitcutter is a new repo scaffolder using command line interface.
28
+
29
+ Example
30
+ -------
31
+ >>> # Install
32
+ >>> pip install biscuitcutter
33
+ >>> # From the terminal run:
34
+ >>> biscuitcutter
35
+ >>>
36
+
37
+
38
+ References
39
+ ----------
40
+ https://github.com/erdogant/biscuitcutter
41
+
42
+ """
@@ -0,0 +1,194 @@
1
+ """biscuitcutter.
2
+
3
+ Name : biscuitcutter.py
4
+ Author : Erdogan Taskesen
5
+ Contact : erdogant@gmail.com
6
+ github : https://github.com/erdogant/biscuitcutter
7
+ Licence : MIT
8
+
9
+ """
10
+
11
+ import os
12
+ import sys
13
+ import zipfile
14
+ import shutil
15
+ import logging
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ TEMPLATE_PLACEHOLDER_GITHUB = "GITHUBNAME"
20
+ TEMPLATE_PLACEHOLDER_REPO = "REPONAME"
21
+ TEMPLATE_PLACEHOLDER_AUTHOR = "AUTHORNAME"
22
+ TEMPLATE_PLACEHOLDER_EMAIL = "CONTACTADRESS"
23
+
24
+
25
+ # ---------------------------------------------------------------------------
26
+ # CLI entry-point
27
+ # ---------------------------------------------------------------------------
28
+
29
+ def main():
30
+ """Interactive CLI: scaffold a new Python repo from the biscuitcutter template.
31
+
32
+ Example
33
+ -------
34
+ >>> # Install
35
+ >>> pip install biscuitcutter
36
+ >>> # From the terminal run:
37
+ >>> biscuitcutter
38
+
39
+ """
40
+ print("\n🍪 biscuitcutter – new repo scaffolder\n" + "─" * 42)
41
+
42
+ # ── 1. Collect user input ───────────────────────────────────────────────
43
+ repo_name = _prompt("Repository / package name", required=True)
44
+ author_name = _prompt("Author full name", required=True)
45
+ author_email= _prompt("Author e-mail", required=False, default="")
46
+ github_user = _prompt("GitHub username", required=False, default=author_name.lower().replace(" ", ""))
47
+
48
+ output_dir = _prompt(
49
+ "Parent directory (leave blank for current dir)",
50
+ required=False,
51
+ default=os.getcwd(),
52
+ )
53
+
54
+ repo_dir = os.path.join(output_dir, repo_name)
55
+
56
+ # ── 2. Create repo directory ────────────────────────────────────────────
57
+ if os.path.exists(repo_dir):
58
+ overwrite = input(f"\n⚠️ '{repo_dir}' already exists. Overwrite? [y/N]: ").strip().lower()
59
+ if overwrite != "y":
60
+ print("Aborted.")
61
+ sys.exit(0)
62
+ shutil.rmtree(repo_dir)
63
+
64
+ os.makedirs(repo_dir)
65
+ print(f"\n✔ Created directory: {repo_dir}")
66
+
67
+ # ── 3. Download & extract template.zip ─────────────────────────────────
68
+ target_directory = os.path.dirname(os.path.abspath(__file__))
69
+ zip_path = os.path.join(target_directory, 'template.zip')
70
+ print(f"directory: {target_directory}")
71
+ print(f"Template: {zip_path}")
72
+
73
+ _extract_zip(zip_path, repo_dir)
74
+ # os.remove(zip_path)
75
+ print(f"✔ Template extracted to: {repo_dir}")
76
+
77
+ # ── 4. Rename variables / placeholders inside all text files ───────────
78
+ replacements = {
79
+ TEMPLATE_PLACEHOLDER_REPO: repo_name,
80
+ TEMPLATE_PLACEHOLDER_AUTHOR: author_name,
81
+ TEMPLATE_PLACEHOLDER_EMAIL: author_email,
82
+ TEMPLATE_PLACEHOLDER_GITHUB: github_user,
83
+ }
84
+ _rename_in_tree(repo_dir, replacements)
85
+ _rename_paths(repo_dir, TEMPLATE_PLACEHOLDER_REPO, repo_name)
86
+
87
+ print(f"✔ Placeholders replaced.")
88
+ print(f"\n🎉 Done! Your new repo is ready at:\n {repo_dir}\n")
89
+
90
+
91
+ # ---------------------------------------------------------------------------
92
+ # Helpers
93
+ # ---------------------------------------------------------------------------
94
+
95
+ def _prompt(label, required=True, default=None):
96
+ suffix = f" [{default}]" if default else ""
97
+ while True:
98
+ value = input(f" {label}{suffix}: ").strip()
99
+ if not value and default is not None:
100
+ return default
101
+ if not value and required:
102
+ print(f" ✗ '{label}' is required.")
103
+ continue
104
+ return value or ""
105
+
106
+
107
+ def _create_stub_zip(dest_path, placeholder):
108
+ """Create a minimal stub zip when the real template is unavailable."""
109
+ import io, zipfile as zf
110
+
111
+ buf = io.BytesIO()
112
+ with zf.ZipFile(buf, "w") as z:
113
+ z.writestr(f"{placeholder}/__init__.py", f"# {placeholder}\n__version__ = '0.1.0'\n")
114
+ z.writestr(f"{placeholder}/{placeholder}.py",
115
+ f'"""{placeholder}."""\n\nclass {placeholder}:\n pass\n')
116
+ z.writestr("README.md", f"# {placeholder}\n\nA new Python library.\n")
117
+ z.writestr("pyproject.toml",
118
+ f'[project]\nname = "{placeholder}"\n'
119
+ f'authors = [{{name = "Erdogan Taskesen", email = "erdogant@gmail.com"}}]\n')
120
+ with open(dest_path, "wb") as fh:
121
+ fh.write(buf.getvalue())
122
+
123
+
124
+ def _extract_zip(zip_path, dest_dir):
125
+ """Extract zip; if the archive has a single top-level folder, strip it."""
126
+ with zipfile.ZipFile(zip_path, "r") as z:
127
+ members = z.namelist()
128
+ # Detect common prefix (GitHub zips add a top-level folder)
129
+ top_dirs = {m.split("/")[0] for m in members if "/" in m}
130
+ strip = ""
131
+ if len(top_dirs) == 1:
132
+ candidate = top_dirs.pop() + "/"
133
+ if all(m.startswith(candidate) or m == candidate.rstrip("/") for m in members):
134
+ strip = candidate
135
+
136
+ for member in members:
137
+ rel = member[len(strip):] if strip and member.startswith(strip) else member
138
+ if not rel:
139
+ continue
140
+ target = os.path.join(dest_dir, rel)
141
+ if member.endswith("/"):
142
+ os.makedirs(target, exist_ok=True)
143
+ else:
144
+ os.makedirs(os.path.dirname(target), exist_ok=True)
145
+ with z.open(member) as src, open(target, "wb") as dst:
146
+ shutil.copyfileobj(src, dst)
147
+
148
+
149
+ def _rename_in_tree(root, replacements):
150
+ """Walk *root* and replace placeholder strings in every text file."""
151
+ TEXT_EXTENSIONS = {
152
+ ".py", ".md", ".rst", ".txt", ".toml", ".cfg", ".ini",
153
+ ".yml", ".yaml", ".json", ".html", ".js", ".css", ".sh",
154
+ ".bat", ".ps1", "",
155
+ }
156
+ for dirpath, _dirs, files in os.walk(root):
157
+ for fname in files:
158
+ _, ext = os.path.splitext(fname)
159
+ if ext.lower() not in TEXT_EXTENSIONS:
160
+ continue
161
+ fpath = os.path.join(dirpath, fname)
162
+ try:
163
+ with open(fpath, "r", encoding="utf-8", errors="replace") as fh:
164
+ content = fh.read()
165
+ new_content = content
166
+ for old, new in replacements.items():
167
+ new_content = new_content.replace(old, new)
168
+ if new_content != content:
169
+ with open(fpath, "w", encoding="utf-8") as fh:
170
+ fh.write(new_content)
171
+ except Exception as exc:
172
+ logger.debug(f"Skipping {fpath}: {exc}")
173
+
174
+
175
+ def _rename_paths(root, old_name, new_name):
176
+ """Rename files and directories that contain *old_name* in their names."""
177
+ # Walk bottom-up so we rename children before parents.
178
+ for dirpath, dirs, files in os.walk(root, topdown=False):
179
+ for fname in files:
180
+ if old_name in fname:
181
+ src = os.path.join(dirpath, fname)
182
+ dst = os.path.join(dirpath, fname.replace(old_name, new_name))
183
+ os.rename(src, dst)
184
+ for dname in dirs:
185
+ if old_name in dname:
186
+ src = os.path.join(dirpath, dname)
187
+ dst = os.path.join(dirpath, dname.replace(old_name, new_name))
188
+ os.rename(src, dst)
189
+
190
+
191
+ # ---------------------------------------------------------------------------
192
+
193
+ if __name__ == "__main__":
194
+ main()
@@ -0,0 +1,6 @@
1
+ # %%
2
+ import biscuitcutter
3
+ print(dir(biscuitcutter))
4
+ print(biscuitcutter.__version__)
5
+
6
+ # %%
@@ -0,0 +1,130 @@
1
+ Metadata-Version: 2.4
2
+ Name: biscuitcutter
3
+ Version: 1.0.0
4
+ Summary: biscuitcutter – scaffold a new Python repo from a template in seconds.
5
+ Author-email: Erdogan Taskesen <erdogant@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://erdogant.github.io/biscuitcutter
8
+ Project-URL: Download, https://github.com/erdogant/biscuitcutter/archive/{version}.tar.gz
9
+ Keywords: Python,biscuitcutter,templates,scaffolding,cookiecutter
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Education
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Operating System :: Unix
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Operating System :: OS Independent
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Dynamic: license-file
22
+
23
+ [![Python](https://img.shields.io/pypi/pyversions/biscuitcutter)](https://img.shields.io/pypi/pyversions/biscuitcutter)
24
+ [![Pypi](https://img.shields.io/pypi/v/biscuitcutter)](https://pypi.org/project/biscuitcutter/)
25
+ [![Docs](https://img.shields.io/badge/Sphinx-Docs-Green)](https://erdogant.github.io/biscuitcutter/)
26
+ [![LOC](https://sloc.xyz/github/erdogant/biscuitcutter/?category=code)](https://github.com/erdogant/biscuitcutter/)
27
+ [![Downloads](https://static.pepy.tech/personalized-badge/biscuitcutter?period=month&units=international_system&left_color=grey&right_color=brightgreen&left_text=PyPI%20downloads/month)](https://pepy.tech/project/biscuitcutter)
28
+ [![Downloads](https://static.pepy.tech/personalized-badge/biscuitcutter?period=total&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/biscuitcutter)
29
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/erdogant/biscuitcutter/blob/master/LICENSE)
30
+ [![Forks](https://img.shields.io/github/forks/erdogant/biscuitcutter.svg)](https://github.com/erdogant/biscuitcutter/network)
31
+ [![Issues](https://img.shields.io/github/issues/erdogant/biscuitcutter.svg)](https://github.com/erdogant/biscuitcutter/issues)
32
+ [![Project Status](http://www.repostatus.org/badges/latest/active.svg)](http://www.repostatus.org/#active)
33
+
34
+ <div>
35
+ <a href="https://erdogant.github.io/biscuitcutter/">
36
+ <img src="https://raw.githubusercontent.com/erdogant/biscuitcutter/master/docs/figs/logo.png"
37
+ width="250"
38
+ align="left" />
39
+ </a>
40
+ <strong>biscuitcutter</strong> is a new repository scaffolder for Python projects.
41
+
42
+ Create a new Python package or repository with a single command! ⭐️Star it if you like it⭐️
43
+ </div>
44
+
45
+ ---
46
+
47
+ ### Key Features
48
+
49
+ | Feature | Description |
50
+ |--------|-------------|
51
+ | [**Interactive CLI**](https://erdogant.github.io/biscuitcutter/pages/html/Installation.html) | Scaffold a new Python repository with prompts for repo name, author info, and more. |
52
+ | [**Template-Based**](https://erdogant.github.io/biscuitcutter/) | Uses a pre-configured template to create a ready-to-use project structure. |
53
+ | [**Placeholder Replacement**](https://erdogant.github.io/biscuitcutter/) | Automatically replaces placeholders (repo name, author, email, GitHub username) in all files. |
54
+
55
+ ---
56
+
57
+ ### Resources and Links
58
+ - **Documentation:** [Website](https://erdogant.github.io/biscuitcutter)
59
+ - **Bug Reports and Feature Requests:** [GitHub Issues](https://github.com/erdogant/biscuitcutter/issues)
60
+
61
+ ---
62
+
63
+ ### Installation
64
+
65
+ ##### Install biscuitcutter from PyPI
66
+ ```bash
67
+ pip install biscuitcutter
68
+ ```
69
+ ---
70
+
71
+ ### Usage
72
+
73
+ After installation, run the interactive CLI:
74
+
75
+ ```bash
76
+ biscuitcutter
77
+ ```
78
+
79
+ This will prompt you for:
80
+
81
+ - **Repository / package name** (required)
82
+ - **Author full name** (required)
83
+ - **Author e-mail** (optional)
84
+ - **GitHub username** (optional, defaults to lowercase author name without spaces)
85
+ - **Parent directory** (optional, defaults to current directory)
86
+
87
+ Alternatively, you can import and call the main function directly:
88
+
89
+ ```python
90
+ from biscuitcutter import main
91
+ main()
92
+ ```
93
+
94
+ ---
95
+
96
+ ### Example Session
97
+
98
+ ```console
99
+ 🍪 biscuitcutter – new repo scaffolder
100
+
101
+ ───────────────────────────────────────────
102
+ Repository / package name: my_project
103
+ Author full name: Erdogan Taskesen
104
+ Author e-mail: erdogant@gmail.com
105
+ GitHub username: erdogant
106
+ Parent directory (leave blank for current dir):
107
+
108
+ ✔ Created directory: /path/to/my_project
109
+ ✔ Template extracted to: /path/to/my_project
110
+ ✔ Placeholders replaced.
111
+
112
+ 🎉 Done! Your new repo is ready at:
113
+ /path/to/my_project
114
+ ```
115
+
116
+ ---
117
+
118
+ ### Contributors
119
+
120
+ Setting up and maintaining biscuitcutter has been possible thanks to users and contributors. Thanks to:
121
+
122
+ <p align="left">
123
+ <a href="https://github.com/erdogant/biscuitcutter/graphs/contributors">
124
+ <img src="https://contrib.rocks/image?repo=erdogant/biscuitcutter" />
125
+ </a>
126
+ </p>
127
+
128
+ ### Maintainer
129
+ * Erdogan Taskesen, github: [erdogant](https://github.com/erdogant)
130
+ * Contributions are welcome.
@@ -0,0 +1,13 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ pyproject.toml
5
+ biscuitcutter/__init__.py
6
+ biscuitcutter/biscuitcutter.py
7
+ biscuitcutter/examples.py
8
+ biscuitcutter/template.zip
9
+ biscuitcutter.egg-info/PKG-INFO
10
+ biscuitcutter.egg-info/SOURCES.txt
11
+ biscuitcutter.egg-info/dependency_links.txt
12
+ biscuitcutter.egg-info/entry_points.txt
13
+ biscuitcutter.egg-info/top_level.txt
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ bakebiscuit = biscuitcutter.biscuitcutter:main
3
+ bakebiscuits = biscuitcutter.biscuitcutter:main
4
+ biscuitcutter = biscuitcutter.biscuitcutter:main
@@ -0,0 +1 @@
1
+ biscuitcutter
@@ -0,0 +1,46 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "biscuitcutter"
7
+ dynamic = ["version"]
8
+ authors = [{ name = "Erdogan Taskesen", email = "erdogant@gmail.com" }]
9
+ description = "biscuitcutter – scaffold a new Python repo from a template in seconds."
10
+ readme = "README.md"
11
+ requires-python = ">=3.8"
12
+ license = "MIT"
13
+ keywords = ["Python", "biscuitcutter", "templates", "scaffolding", "cookiecutter"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Intended Audience :: Developers",
17
+ "Intended Audience :: Education",
18
+ "Intended Audience :: Science/Research",
19
+ "Operating System :: Unix",
20
+ "Operating System :: Microsoft :: Windows",
21
+ "Operating System :: MacOS",
22
+ "Operating System :: OS Independent",
23
+ ]
24
+ dependencies = []
25
+
26
+ [project.urls]
27
+ Homepage = "https://erdogant.github.io/biscuitcutter"
28
+ Download = "https://github.com/erdogant/biscuitcutter/archive/{version}.tar.gz"
29
+
30
+ # ── CLI entry-points ───────────────────────────────────────────────────────
31
+ # After `pip install biscuitcutter` the user can type any of these commands
32
+ # in a terminal to launch the interactive scaffolder.
33
+ [project.scripts]
34
+ biscuitcutter = "biscuitcutter.biscuitcutter:main"
35
+ bakebiscuit = "biscuitcutter.biscuitcutter:main"
36
+ bakebiscuits = "biscuitcutter.biscuitcutter:main"
37
+
38
+ [tool.setuptools]
39
+ packages = ["biscuitcutter"]
40
+ include-package-data = true
41
+
42
+ [tool.setuptools.package-data]
43
+ biscuitcutter = ["template.zip"]
44
+
45
+ [tool.setuptools.dynamic]
46
+ version = { attr = "biscuitcutter.__version__" }
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+