projectstarter-cli 0.1.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.
- projectstarter/__init__.py +0 -0
- projectstarter/cli.py +173 -0
- projectstarter/doctor.py +31 -0
- projectstarter/generator.py +427 -0
- projectstarter/registry.py +43 -0
- projectstarter/utils.py +12 -0
- projectstarter_cli-0.1.0.dist-info/METADATA +662 -0
- projectstarter_cli-0.1.0.dist-info/RECORD +12 -0
- projectstarter_cli-0.1.0.dist-info/WHEEL +5 -0
- projectstarter_cli-0.1.0.dist-info/entry_points.txt +2 -0
- projectstarter_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
- projectstarter_cli-0.1.0.dist-info/top_level.txt +1 -0
|
File without changes
|
projectstarter/cli.py
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
|
|
3
|
+
from .registry import GENERATORS, PROJECT_INFO
|
|
4
|
+
from .utils import validate_project_name
|
|
5
|
+
from .doctor import run_doctor
|
|
6
|
+
|
|
7
|
+
def main():
|
|
8
|
+
parser = argparse.ArgumentParser(
|
|
9
|
+
description="ProjectStarter - Create projects quickly"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
parser.add_argument(
|
|
13
|
+
"--version",
|
|
14
|
+
action="version",
|
|
15
|
+
version="ProjectStarter 0.1.0"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
subparsers = parser.add_subparsers(
|
|
19
|
+
dest="command"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# create command
|
|
23
|
+
create_parser = subparsers.add_parser(
|
|
24
|
+
"create",
|
|
25
|
+
help="Create a new project"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
create_parser.add_argument(
|
|
29
|
+
"project_type",
|
|
30
|
+
nargs="?",
|
|
31
|
+
choices=GENERATORS.keys(),
|
|
32
|
+
help="Type of project to create"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
create_parser.add_argument(
|
|
36
|
+
"project_name",
|
|
37
|
+
nargs="?",
|
|
38
|
+
help="Name of the project"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# list command
|
|
42
|
+
subparsers.add_parser(
|
|
43
|
+
"list",
|
|
44
|
+
help="List available project types"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# info command
|
|
48
|
+
info_parser = subparsers.add_parser(
|
|
49
|
+
"info",
|
|
50
|
+
help="Show information about a project type"
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# doctor command
|
|
54
|
+
subparsers.add_parser(
|
|
55
|
+
"doctor",
|
|
56
|
+
help="Check ProjectStarter installation"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
info_parser.add_argument(
|
|
60
|
+
"project_type",
|
|
61
|
+
choices=PROJECT_INFO.keys(),
|
|
62
|
+
help="Project type to show information about"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
args = parser.parse_args()
|
|
66
|
+
|
|
67
|
+
# create project
|
|
68
|
+
if args.command == "create":
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
|
|
72
|
+
if args.project_type is None:
|
|
73
|
+
|
|
74
|
+
print("\nChoose a project type:\n")
|
|
75
|
+
|
|
76
|
+
project_types = list(GENERATORS.keys())
|
|
77
|
+
|
|
78
|
+
for index, project_type in enumerate(
|
|
79
|
+
project_types,
|
|
80
|
+
start=1
|
|
81
|
+
):
|
|
82
|
+
print(f"{index}. {project_type}")
|
|
83
|
+
|
|
84
|
+
print()
|
|
85
|
+
|
|
86
|
+
choice = input("Enter your choice: ")
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
choice = int(choice)
|
|
90
|
+
project_type = project_types[choice - 1]
|
|
91
|
+
|
|
92
|
+
except (ValueError, IndexError):
|
|
93
|
+
print("Invalid choice.")
|
|
94
|
+
return
|
|
95
|
+
|
|
96
|
+
project_name = input(
|
|
97
|
+
"Enter project name: "
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
if not validate_project_name(project_name):
|
|
101
|
+
print(
|
|
102
|
+
"Invalid project name."
|
|
103
|
+
"\nUse only letters, numbers, and underscores."
|
|
104
|
+
"\nProject name must not start with a number."
|
|
105
|
+
)
|
|
106
|
+
return
|
|
107
|
+
|
|
108
|
+
generator = GENERATORS[project_type]
|
|
109
|
+
|
|
110
|
+
generator(project_name)
|
|
111
|
+
|
|
112
|
+
else:
|
|
113
|
+
|
|
114
|
+
generator = GENERATORS[args.project_type]
|
|
115
|
+
|
|
116
|
+
if args.project_name is None:
|
|
117
|
+
args.project_name = input(
|
|
118
|
+
"Enter project name: "
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
if not validate_project_name(args.project_name):
|
|
122
|
+
print(
|
|
123
|
+
"Invalid project name."
|
|
124
|
+
"\nUse only letters, numbers, and underscores."
|
|
125
|
+
"\nProject name must not start with a number."
|
|
126
|
+
)
|
|
127
|
+
return
|
|
128
|
+
|
|
129
|
+
generator(args.project_name)
|
|
130
|
+
|
|
131
|
+
except FileExistsError as error:
|
|
132
|
+
|
|
133
|
+
print(f"\nError: {error}")
|
|
134
|
+
|
|
135
|
+
# list projects
|
|
136
|
+
elif args.command == "list":
|
|
137
|
+
|
|
138
|
+
print("\nAvailable project types:\n")
|
|
139
|
+
|
|
140
|
+
for project_type in GENERATORS:
|
|
141
|
+
print(f" {project_type}")
|
|
142
|
+
|
|
143
|
+
print()
|
|
144
|
+
|
|
145
|
+
# info project
|
|
146
|
+
elif args.command == "info":
|
|
147
|
+
|
|
148
|
+
info = PROJECT_INFO[args.project_type]
|
|
149
|
+
|
|
150
|
+
print(f"\n{args.project_type.capitalize()}")
|
|
151
|
+
print("─" * 30)
|
|
152
|
+
|
|
153
|
+
print(f"Description: {info['description']}")
|
|
154
|
+
print(
|
|
155
|
+
f"Virtual environment: "
|
|
156
|
+
f"{info['virtual_environment']}"
|
|
157
|
+
)
|
|
158
|
+
print(
|
|
159
|
+
f"Automatic installation: "
|
|
160
|
+
f"{info['automatic_installation']}"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
print("\nRun:")
|
|
164
|
+
print(f" {info['run']}")
|
|
165
|
+
|
|
166
|
+
print()
|
|
167
|
+
|
|
168
|
+
elif args.command == "doctor":
|
|
169
|
+
run_doctor()
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
if __name__ == "__main__":
|
|
173
|
+
main()
|
projectstarter/doctor.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
from .registry import GENERATORS, PROJECT_INFO
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def run_doctor():
|
|
7
|
+
print("\nProjectStarter Doctor")
|
|
8
|
+
print("─" * 30)
|
|
9
|
+
|
|
10
|
+
# Python
|
|
11
|
+
print("✓ Python")
|
|
12
|
+
print(f" Version: {sys.version.split()[0]}")
|
|
13
|
+
|
|
14
|
+
# Registry
|
|
15
|
+
print("✓ Registry")
|
|
16
|
+
|
|
17
|
+
# Generators
|
|
18
|
+
print(f"✓ Generators ({len(GENERATORS)})")
|
|
19
|
+
|
|
20
|
+
for project_type in GENERATORS:
|
|
21
|
+
print(f" - {project_type}")
|
|
22
|
+
|
|
23
|
+
# Project information
|
|
24
|
+
print("✓ Project Info")
|
|
25
|
+
|
|
26
|
+
if set(GENERATORS.keys()) == set(PROJECT_INFO.keys()):
|
|
27
|
+
print(" All project information is available.")
|
|
28
|
+
else:
|
|
29
|
+
print(" Warning: Project information is incomplete.")
|
|
30
|
+
|
|
31
|
+
print("\nEverything looks good! ✓")
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import subprocess
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def run_command(command, cwd=None):
|
|
7
|
+
"""Run a command."""
|
|
8
|
+
subprocess.run(
|
|
9
|
+
command,
|
|
10
|
+
cwd=cwd,
|
|
11
|
+
check=True
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def create_virtual_environment(project_path):
|
|
16
|
+
"""Create a virtual environment."""
|
|
17
|
+
|
|
18
|
+
venv_path = project_path / ".venv"
|
|
19
|
+
|
|
20
|
+
print("Creating virtual environment...")
|
|
21
|
+
|
|
22
|
+
run_command(
|
|
23
|
+
[sys.executable, "-m", "venv", ".venv"],
|
|
24
|
+
cwd=project_path
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if sys.platform == "win32":
|
|
28
|
+
return venv_path / "Scripts" / "python.exe"
|
|
29
|
+
|
|
30
|
+
return venv_path / "bin" / "python"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def upgrade_pip(python_exe):
|
|
34
|
+
"""Upgrade pip."""
|
|
35
|
+
|
|
36
|
+
print("Upgrading pip...")
|
|
37
|
+
|
|
38
|
+
run_command(
|
|
39
|
+
[
|
|
40
|
+
str(python_exe),
|
|
41
|
+
"-m",
|
|
42
|
+
"pip",
|
|
43
|
+
"install",
|
|
44
|
+
"--upgrade",
|
|
45
|
+
"pip"
|
|
46
|
+
]
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def install_package(python_exe, package):
|
|
51
|
+
"""Install a package."""
|
|
52
|
+
|
|
53
|
+
print(f"Installing {package}...")
|
|
54
|
+
|
|
55
|
+
run_command(
|
|
56
|
+
[
|
|
57
|
+
str(python_exe),
|
|
58
|
+
"-m",
|
|
59
|
+
"pip",
|
|
60
|
+
"install",
|
|
61
|
+
package
|
|
62
|
+
]
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def save_requirements(python_exe, project_path):
|
|
67
|
+
"""Create requirements.txt."""
|
|
68
|
+
|
|
69
|
+
result = subprocess.run(
|
|
70
|
+
[
|
|
71
|
+
str(python_exe),
|
|
72
|
+
"-m",
|
|
73
|
+
"pip",
|
|
74
|
+
"freeze"
|
|
75
|
+
],
|
|
76
|
+
capture_output=True,
|
|
77
|
+
text=True,
|
|
78
|
+
check=True
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
(project_path / "requirements.txt").write_text(
|
|
82
|
+
result.stdout,
|
|
83
|
+
encoding="utf-8"
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def create_gitignore(project_path, django=False):
|
|
88
|
+
"""Create .gitignore."""
|
|
89
|
+
|
|
90
|
+
content = """__pycache__/
|
|
91
|
+
*.py[cod]
|
|
92
|
+
|
|
93
|
+
.venv/
|
|
94
|
+
venv/
|
|
95
|
+
|
|
96
|
+
.env
|
|
97
|
+
|
|
98
|
+
.pytest_cache/
|
|
99
|
+
.vscode/
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
if django:
|
|
103
|
+
content += "\ndb.sqlite3\n"
|
|
104
|
+
|
|
105
|
+
(project_path / ".gitignore").write_text(
|
|
106
|
+
content,
|
|
107
|
+
encoding="utf-8"
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def create_python_project(project_name):
|
|
112
|
+
"""Create a basic Python project."""
|
|
113
|
+
|
|
114
|
+
project_path = Path(project_name)
|
|
115
|
+
|
|
116
|
+
if project_path.exists():
|
|
117
|
+
raise FileExistsError(
|
|
118
|
+
f"Project '{project_name}' already exists."
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
print(f"Creating Python project '{project_name}'...")
|
|
122
|
+
|
|
123
|
+
package_path = project_path / "src" / project_name
|
|
124
|
+
tests_path = project_path / "tests"
|
|
125
|
+
|
|
126
|
+
package_path.mkdir(parents=True)
|
|
127
|
+
tests_path.mkdir(parents=True)
|
|
128
|
+
|
|
129
|
+
(package_path / "__init__.py").write_text(
|
|
130
|
+
"",
|
|
131
|
+
encoding="utf-8"
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
(package_path / "main.py").write_text(
|
|
135
|
+
"""def main():
|
|
136
|
+
print("Hello from your new Python project!")
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
if __name__ == "__main__":
|
|
140
|
+
main()
|
|
141
|
+
""",
|
|
142
|
+
encoding="utf-8"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
(tests_path / "test_main.py").write_text(
|
|
146
|
+
"""def test_example():
|
|
147
|
+
assert True
|
|
148
|
+
""",
|
|
149
|
+
encoding="utf-8"
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
create_gitignore(project_path)
|
|
153
|
+
|
|
154
|
+
(project_path / "requirements.txt").write_text(
|
|
155
|
+
"",
|
|
156
|
+
encoding="utf-8"
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
readme = (
|
|
160
|
+
f"# {project_name}\n\n"
|
|
161
|
+
"A Python project created with ProjectStarter.\n\n"
|
|
162
|
+
"## Run\n\n"
|
|
163
|
+
"Activate the virtual environment on Windows:\n\n"
|
|
164
|
+
".venv\\Scripts\\activate\n\n"
|
|
165
|
+
"Run the application:\n\n"
|
|
166
|
+
"python src/"
|
|
167
|
+
f"{project_name}/main.py\n"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
(project_path / "README.md").write_text(
|
|
171
|
+
readme,
|
|
172
|
+
encoding="utf-8"
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
print(
|
|
176
|
+
f"Project '{project_name}' created successfully!"
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def create_django_project(project_name):
|
|
181
|
+
"""Create a Django project."""
|
|
182
|
+
|
|
183
|
+
project_path = Path(project_name)
|
|
184
|
+
|
|
185
|
+
if project_path.exists():
|
|
186
|
+
raise FileExistsError(
|
|
187
|
+
f"Project '{project_name}' already exists."
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
print(f"Creating Django project '{project_name}'...")
|
|
191
|
+
|
|
192
|
+
project_path.mkdir(parents=True)
|
|
193
|
+
|
|
194
|
+
python_exe = create_virtual_environment(
|
|
195
|
+
project_path
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
upgrade_pip(python_exe)
|
|
199
|
+
|
|
200
|
+
install_package(
|
|
201
|
+
python_exe,
|
|
202
|
+
"django"
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
print("Creating Django project files...")
|
|
206
|
+
|
|
207
|
+
run_command(
|
|
208
|
+
[
|
|
209
|
+
str(python_exe),
|
|
210
|
+
"-m",
|
|
211
|
+
"django",
|
|
212
|
+
"startproject",
|
|
213
|
+
"config",
|
|
214
|
+
"."
|
|
215
|
+
],
|
|
216
|
+
cwd=project_path
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
save_requirements(
|
|
220
|
+
python_exe,
|
|
221
|
+
project_path
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
create_gitignore(
|
|
225
|
+
project_path,
|
|
226
|
+
django=True
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
readme = (
|
|
230
|
+
f"# {project_name}\n\n"
|
|
231
|
+
"A Django project created with ProjectStarter.\n\n"
|
|
232
|
+
"## Activate virtual environment\n\n"
|
|
233
|
+
"Windows:\n\n"
|
|
234
|
+
".venv\\Scripts\\activate\n\n"
|
|
235
|
+
"## Run the project\n\n"
|
|
236
|
+
"python manage.py runserver\n\n"
|
|
237
|
+
"## Project URL\n\n"
|
|
238
|
+
"http://127.0.0.1:8000/\n"
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
(project_path / "README.md").write_text(
|
|
242
|
+
readme,
|
|
243
|
+
encoding="utf-8"
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
print(
|
|
247
|
+
f"Django project '{project_name}' "
|
|
248
|
+
"created successfully!"
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def create_flask_project(project_name):
|
|
253
|
+
"""Create a Flask project."""
|
|
254
|
+
|
|
255
|
+
project_path = Path(project_name)
|
|
256
|
+
|
|
257
|
+
if project_path.exists():
|
|
258
|
+
raise FileExistsError(
|
|
259
|
+
f"Project '{project_name}' already exists."
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
print(f"Creating Flask project '{project_name}'...")
|
|
263
|
+
|
|
264
|
+
project_path.mkdir(parents=True)
|
|
265
|
+
|
|
266
|
+
python_exe = create_virtual_environment(
|
|
267
|
+
project_path
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
upgrade_pip(python_exe)
|
|
271
|
+
|
|
272
|
+
install_package(
|
|
273
|
+
python_exe,
|
|
274
|
+
"flask"
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
app_path = project_path / "app"
|
|
278
|
+
templates_path = app_path / "templates"
|
|
279
|
+
static_path = app_path / "static"
|
|
280
|
+
|
|
281
|
+
templates_path.mkdir(parents=True)
|
|
282
|
+
static_path.mkdir(parents=True)
|
|
283
|
+
|
|
284
|
+
(app_path / "__init__.py").write_text(
|
|
285
|
+
"""from flask import Flask
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def create_app():
|
|
289
|
+
app = Flask(__name__)
|
|
290
|
+
|
|
291
|
+
@app.route("/")
|
|
292
|
+
def home():
|
|
293
|
+
return "Hello from Flask!"
|
|
294
|
+
|
|
295
|
+
return app
|
|
296
|
+
""",
|
|
297
|
+
encoding="utf-8"
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
(project_path / "run.py").write_text(
|
|
301
|
+
"""from app import create_app
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
app = create_app()
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
if __name__ == "__main__":
|
|
308
|
+
app.run(debug=True)
|
|
309
|
+
""",
|
|
310
|
+
encoding="utf-8"
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
save_requirements(
|
|
314
|
+
python_exe,
|
|
315
|
+
project_path
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
create_gitignore(
|
|
319
|
+
project_path
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
readme = (
|
|
323
|
+
f"# {project_name}\n\n"
|
|
324
|
+
"A Flask project created with ProjectStarter.\n\n"
|
|
325
|
+
"## Activate virtual environment\n\n"
|
|
326
|
+
"Windows:\n\n"
|
|
327
|
+
".venv\\Scripts\\activate\n\n"
|
|
328
|
+
"## Run the project\n\n"
|
|
329
|
+
"python run.py\n\n"
|
|
330
|
+
"## Project URL\n\n"
|
|
331
|
+
"http://127.0.0.1:5000/\n"
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
(project_path / "README.md").write_text(
|
|
335
|
+
readme,
|
|
336
|
+
encoding="utf-8"
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
print(
|
|
340
|
+
f"Flask project '{project_name}' "
|
|
341
|
+
"created successfully!"
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
def create_fastapi_project(project_name):
|
|
345
|
+
"""Create a FastAPI project."""
|
|
346
|
+
|
|
347
|
+
project_path = Path(project_name)
|
|
348
|
+
|
|
349
|
+
if project_path.exists():
|
|
350
|
+
raise FileExistsError(
|
|
351
|
+
f"Project '{project_name}' already exists."
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
print(f"Creating FastAPI project '{project_name}'...")
|
|
355
|
+
|
|
356
|
+
project_path.mkdir(parents=True)
|
|
357
|
+
|
|
358
|
+
python_exe = create_virtual_environment(
|
|
359
|
+
project_path
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
upgrade_pip(python_exe)
|
|
363
|
+
|
|
364
|
+
install_package(
|
|
365
|
+
python_exe,
|
|
366
|
+
"fastapi"
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
install_package(
|
|
370
|
+
python_exe,
|
|
371
|
+
"uvicorn"
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
app_path = project_path / "app"
|
|
375
|
+
app_path.mkdir(parents=True)
|
|
376
|
+
|
|
377
|
+
(app_path / "__init__.py").write_text(
|
|
378
|
+
"",
|
|
379
|
+
encoding="utf-8"
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
(app_path / "main.py").write_text(
|
|
383
|
+
"""from fastapi import FastAPI
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
app = FastAPI()
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
@app.get("/")
|
|
390
|
+
def home():
|
|
391
|
+
return {"message": "Hello from FastAPI!"}
|
|
392
|
+
""",
|
|
393
|
+
encoding="utf-8"
|
|
394
|
+
)
|
|
395
|
+
|
|
396
|
+
save_requirements(
|
|
397
|
+
python_exe,
|
|
398
|
+
project_path
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
create_gitignore(
|
|
402
|
+
project_path
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
readme = (
|
|
406
|
+
f"# {project_name}\n\n"
|
|
407
|
+
"A FastAPI project created with ProjectStarter.\n\n"
|
|
408
|
+
"## Activate virtual environment\n\n"
|
|
409
|
+
"Windows:\n\n"
|
|
410
|
+
".venv\\Scripts\\activate\n\n"
|
|
411
|
+
"## Run\n\n"
|
|
412
|
+
"uvicorn app.main:app --reload\n\n"
|
|
413
|
+
"## API\n\n"
|
|
414
|
+
"http://127.0.0.1:8000/\n\n"
|
|
415
|
+
"## Swagger Docs\n\n"
|
|
416
|
+
"http://127.0.0.1:8000/docs\n"
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
(project_path / "README.md").write_text(
|
|
420
|
+
readme,
|
|
421
|
+
encoding="utf-8"
|
|
422
|
+
)
|
|
423
|
+
|
|
424
|
+
print(
|
|
425
|
+
f"FastAPI project '{project_name}' "
|
|
426
|
+
"created successfully!"
|
|
427
|
+
)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from .generator import (
|
|
2
|
+
create_python_project,
|
|
3
|
+
create_django_project,
|
|
4
|
+
create_flask_project,
|
|
5
|
+
create_fastapi_project,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
GENERATORS = {
|
|
9
|
+
"python": create_python_project,
|
|
10
|
+
"django": create_django_project,
|
|
11
|
+
"flask": create_flask_project,
|
|
12
|
+
"fastapi": create_fastapi_project,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
PROJECT_INFO = {
|
|
16
|
+
"python": {
|
|
17
|
+
"description": "A basic Python project",
|
|
18
|
+
"virtual_environment": "Yes",
|
|
19
|
+
"automatic_installation": "No",
|
|
20
|
+
"run": "python src/<project_name>/main.py",
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
"django": {
|
|
24
|
+
"description": "Python web framework",
|
|
25
|
+
"virtual_environment": "Yes",
|
|
26
|
+
"automatic_installation": "Yes",
|
|
27
|
+
"run": "python manage.py runserver",
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
"flask": {
|
|
31
|
+
"description": "Lightweight Python web framework",
|
|
32
|
+
"virtual_environment": "Yes",
|
|
33
|
+
"automatic_installation": "Yes",
|
|
34
|
+
"run": "python run.py",
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
"fastapi": {
|
|
38
|
+
"description": "Modern Python API framework",
|
|
39
|
+
"virtual_environment": "Yes",
|
|
40
|
+
"automatic_installation": "Yes",
|
|
41
|
+
"run": "uvicorn app.main:app --reload",
|
|
42
|
+
},
|
|
43
|
+
}
|
projectstarter/utils.py
ADDED
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: projectstarter-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python CLI tool for quickly generating Python, Django, Flask, and FastAPI projects
|
|
5
|
+
Author-email: Mohamed Ali Ismail Jami <mohamedali32947@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/hamada-cool/projectstarter
|
|
8
|
+
Project-URL: Repository, https://github.com/hamada-cool/projectstarter
|
|
9
|
+
Project-URL: Issues, https://github.com/hamada-cool/projectstarter/issues
|
|
10
|
+
Keywords: cli,project-generator,project-starter,python,django,flask,fastapi
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
|
|
22
|
+
# ProjectStarter 🚀
|
|
23
|
+
|
|
24
|
+
ProjectStarter is a Python CLI tool created by **Mohamed Ali** for quickly creating ready-to-use project structures.
|
|
25
|
+
|
|
26
|
+
It helps developers avoid manually creating folders, files, virtual environments, installing framework dependencies, and preparing basic project documentation.
|
|
27
|
+
|
|
28
|
+
## ✨ Features
|
|
29
|
+
|
|
30
|
+
- 🐍 Create basic Python projects
|
|
31
|
+
- 🌐 Create Django projects
|
|
32
|
+
- ⚡ Create Flask projects
|
|
33
|
+
- 🚀 Create FastAPI projects
|
|
34
|
+
- 📦 Automatically create `.venv` for Django, Flask, and FastAPI projects
|
|
35
|
+
- ⬆️ Automatically upgrade `pip`
|
|
36
|
+
- 🔧 Automatically install required framework packages
|
|
37
|
+
- 📄 Automatically generate `requirements.txt`
|
|
38
|
+
- 🚫 Automatically generate `.gitignore`
|
|
39
|
+
- 📝 Automatically generate a README for generated projects
|
|
40
|
+
- 📋 List supported project types
|
|
41
|
+
- ℹ️ Show information about each project type
|
|
42
|
+
- 🩺 Check the ProjectStarter installation with `doctor`
|
|
43
|
+
- 🧪 Includes automated tests
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 📋 Supported Project Types
|
|
48
|
+
|
|
49
|
+
| Project Type | Virtual Environment | Automatic Dependency Installation | Run Command |
|
|
50
|
+
|---|---|---|---|
|
|
51
|
+
| Python | No | No | `python src/<project_name>/main.py` |
|
|
52
|
+
| Django | Yes | Yes | `python manage.py runserver` |
|
|
53
|
+
| Flask | Yes | Yes | `python run.py` |
|
|
54
|
+
| FastAPI | Yes | Yes | `uvicorn app.main:app --reload` |
|
|
55
|
+
|
|
56
|
+
> The basic Python generator creates the project structure directly. Django, Flask, and FastAPI projects receive their own `.venv` and framework dependencies automatically.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
# 📦 Installation
|
|
61
|
+
|
|
62
|
+
Install ProjectStarter from PyPI:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install projectstarter
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Check that it is installed:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
projectstarter --version
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Show the available commands:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
projectstarter --help
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
# 🚀 Usage
|
|
83
|
+
|
|
84
|
+
## 1. Create a project interactively
|
|
85
|
+
|
|
86
|
+
Run:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
projectstarter create
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
ProjectStarter will show the available project types:
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
Choose a project type:
|
|
96
|
+
|
|
97
|
+
1. python
|
|
98
|
+
2. django
|
|
99
|
+
3. flask
|
|
100
|
+
4. fastapi
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Then enter the number of the project type and the project name.
|
|
104
|
+
|
|
105
|
+
Example:
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
Enter your choice: 2
|
|
109
|
+
Enter project name: myproject
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
ProjectStarter will create the project automatically.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 2. Create a Python project
|
|
117
|
+
|
|
118
|
+
Run:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
projectstarter create python myproject
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The generated structure is:
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
myproject/
|
|
128
|
+
├── src/
|
|
129
|
+
│ └── myproject/
|
|
130
|
+
│ ├── __init__.py
|
|
131
|
+
│ └── main.py
|
|
132
|
+
├── tests/
|
|
133
|
+
│ └── test_main.py
|
|
134
|
+
├── .gitignore
|
|
135
|
+
├── requirements.txt
|
|
136
|
+
└── README.md
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Run the Python project
|
|
140
|
+
|
|
141
|
+
Windows:
|
|
142
|
+
|
|
143
|
+
```powershell
|
|
144
|
+
python src/myproject/main.py
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The generated application contains a simple `main()` function.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
# 🌐 Django
|
|
152
|
+
|
|
153
|
+
Create a Django project:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
projectstarter create django myproject
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
ProjectStarter automatically:
|
|
160
|
+
|
|
161
|
+
1. Creates the project directory.
|
|
162
|
+
2. Creates `.venv`.
|
|
163
|
+
3. Upgrades `pip`.
|
|
164
|
+
4. Installs Django.
|
|
165
|
+
5. Creates the Django project using the `config` package.
|
|
166
|
+
6. Creates `requirements.txt`.
|
|
167
|
+
7. Creates `.gitignore`.
|
|
168
|
+
8. Creates a project README.
|
|
169
|
+
|
|
170
|
+
The main structure is:
|
|
171
|
+
|
|
172
|
+
```text
|
|
173
|
+
myproject/
|
|
174
|
+
├── .venv/
|
|
175
|
+
├── config/
|
|
176
|
+
│ ├── __init__.py
|
|
177
|
+
│ ├── asgi.py
|
|
178
|
+
│ ├── settings.py
|
|
179
|
+
│ ├── urls.py
|
|
180
|
+
│ └── wsgi.py
|
|
181
|
+
├── manage.py
|
|
182
|
+
├── requirements.txt
|
|
183
|
+
├── .gitignore
|
|
184
|
+
└── README.md
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Activate the virtual environment
|
|
188
|
+
|
|
189
|
+
Windows:
|
|
190
|
+
|
|
191
|
+
```powershell
|
|
192
|
+
cd myproject
|
|
193
|
+
.venv\Scripts\activate
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
macOS/Linux:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
cd myproject
|
|
200
|
+
source .venv/bin/activate
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Run Django
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
python manage.py runserver
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Open:
|
|
210
|
+
|
|
211
|
+
```text
|
|
212
|
+
http://127.0.0.1:8000/
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
# ⚡ Flask
|
|
218
|
+
|
|
219
|
+
Create a Flask project:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
projectstarter create flask myproject
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
ProjectStarter automatically:
|
|
226
|
+
|
|
227
|
+
1. Creates the project directory.
|
|
228
|
+
2. Creates `.venv`.
|
|
229
|
+
3. Upgrades `pip`.
|
|
230
|
+
4. Installs Flask.
|
|
231
|
+
5. Creates the `app` package.
|
|
232
|
+
6. Creates `templates` and `static` directories.
|
|
233
|
+
7. Creates `run.py`.
|
|
234
|
+
8. Creates `requirements.txt`.
|
|
235
|
+
9. Creates `.gitignore`.
|
|
236
|
+
10. Creates a project README.
|
|
237
|
+
|
|
238
|
+
The generated structure is:
|
|
239
|
+
|
|
240
|
+
```text
|
|
241
|
+
myproject/
|
|
242
|
+
├── .venv/
|
|
243
|
+
├── app/
|
|
244
|
+
│ ├── __init__.py
|
|
245
|
+
│ ├── templates/
|
|
246
|
+
│ └── static/
|
|
247
|
+
├── run.py
|
|
248
|
+
├── requirements.txt
|
|
249
|
+
├── .gitignore
|
|
250
|
+
└── README.md
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Activate the virtual environment
|
|
254
|
+
|
|
255
|
+
Windows:
|
|
256
|
+
|
|
257
|
+
```powershell
|
|
258
|
+
cd myproject
|
|
259
|
+
.venv\Scripts\activate
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
macOS/Linux:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
cd myproject
|
|
266
|
+
source .venv/bin/activate
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Run Flask
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
python run.py
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Open:
|
|
276
|
+
|
|
277
|
+
```text
|
|
278
|
+
http://127.0.0.1:5000/
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
# 🚀 FastAPI
|
|
284
|
+
|
|
285
|
+
Create a FastAPI project:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
projectstarter create fastapi myproject
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
ProjectStarter automatically:
|
|
292
|
+
|
|
293
|
+
1. Creates the project directory.
|
|
294
|
+
2. Creates `.venv`.
|
|
295
|
+
3. Upgrades `pip`.
|
|
296
|
+
4. Installs FastAPI.
|
|
297
|
+
5. Installs Uvicorn.
|
|
298
|
+
6. Creates the `app` package.
|
|
299
|
+
7. Creates `app/main.py`.
|
|
300
|
+
8. Creates `requirements.txt`.
|
|
301
|
+
9. Creates `.gitignore`.
|
|
302
|
+
10. Creates a project README.
|
|
303
|
+
|
|
304
|
+
The generated structure is:
|
|
305
|
+
|
|
306
|
+
```text
|
|
307
|
+
myproject/
|
|
308
|
+
├── .venv/
|
|
309
|
+
├── app/
|
|
310
|
+
│ ├── __init__.py
|
|
311
|
+
│ └── main.py
|
|
312
|
+
├── requirements.txt
|
|
313
|
+
├── .gitignore
|
|
314
|
+
└── README.md
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Activate the virtual environment
|
|
318
|
+
|
|
319
|
+
Windows:
|
|
320
|
+
|
|
321
|
+
```powershell
|
|
322
|
+
cd myproject
|
|
323
|
+
.venv\Scripts\activate
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
macOS/Linux:
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
cd myproject
|
|
330
|
+
source .venv/bin/activate
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Run FastAPI
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
uvicorn app.main:app --reload
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
API:
|
|
340
|
+
|
|
341
|
+
```text
|
|
342
|
+
http://127.0.0.1:8000/
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Swagger documentation:
|
|
346
|
+
|
|
347
|
+
```text
|
|
348
|
+
http://127.0.0.1:8000/docs
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
# 📋 List Project Types
|
|
354
|
+
|
|
355
|
+
To see all available generators:
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
projectstarter list
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Example:
|
|
362
|
+
|
|
363
|
+
```text
|
|
364
|
+
Available project types:
|
|
365
|
+
|
|
366
|
+
python
|
|
367
|
+
django
|
|
368
|
+
flask
|
|
369
|
+
fastapi
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
# ℹ️ Project Information
|
|
375
|
+
|
|
376
|
+
Use the `info` command to see information about a generator.
|
|
377
|
+
|
|
378
|
+
Example:
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
projectstarter info django
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
Example output:
|
|
385
|
+
|
|
386
|
+
```text
|
|
387
|
+
Django
|
|
388
|
+
──────────────────────────────
|
|
389
|
+
Description: Python web framework
|
|
390
|
+
Virtual environment: Yes
|
|
391
|
+
Automatic installation: Yes
|
|
392
|
+
|
|
393
|
+
Run:
|
|
394
|
+
python manage.py runserver
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
You can also check other project types:
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
projectstarter info python
|
|
401
|
+
projectstarter info flask
|
|
402
|
+
projectstarter info fastapi
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
# 🩺 Doctor
|
|
408
|
+
|
|
409
|
+
ProjectStarter includes a built-in diagnostic command:
|
|
410
|
+
|
|
411
|
+
```bash
|
|
412
|
+
projectstarter doctor
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
It checks:
|
|
416
|
+
|
|
417
|
+
- Python
|
|
418
|
+
- Project registry
|
|
419
|
+
- Available generators
|
|
420
|
+
- Project information
|
|
421
|
+
|
|
422
|
+
Example:
|
|
423
|
+
|
|
424
|
+
```text
|
|
425
|
+
ProjectStarter Doctor
|
|
426
|
+
──────────────────────────────
|
|
427
|
+
✓ Python
|
|
428
|
+
Version: 3.x.x
|
|
429
|
+
✓ Registry
|
|
430
|
+
✓ Generators (4)
|
|
431
|
+
- python
|
|
432
|
+
- django
|
|
433
|
+
- flask
|
|
434
|
+
- fastapi
|
|
435
|
+
✓ Project Info
|
|
436
|
+
All project information is available.
|
|
437
|
+
|
|
438
|
+
Everything looks good! ✓
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
# 🧪 Testing ProjectStarter
|
|
444
|
+
|
|
445
|
+
ProjectStarter uses `pytest` for automated testing.
|
|
446
|
+
|
|
447
|
+
Install pytest for development:
|
|
448
|
+
|
|
449
|
+
```bash
|
|
450
|
+
python -m pip install pytest
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
Run all tests:
|
|
454
|
+
|
|
455
|
+
```bash
|
|
456
|
+
python -m pytest
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
The test suite covers:
|
|
460
|
+
|
|
461
|
+
- Project name validation
|
|
462
|
+
- Generator registry
|
|
463
|
+
- Project information
|
|
464
|
+
- Python project generation
|
|
465
|
+
- Django project generation
|
|
466
|
+
- Flask project generation
|
|
467
|
+
- FastAPI project generation
|
|
468
|
+
- CLI commands
|
|
469
|
+
- Interactive project creation
|
|
470
|
+
- Doctor command
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
# 🏗️ ProjectStarter Development Structure
|
|
475
|
+
|
|
476
|
+
The ProjectStarter source code is organized as follows:
|
|
477
|
+
|
|
478
|
+
```text
|
|
479
|
+
projectstarter/
|
|
480
|
+
├── projectstarter/
|
|
481
|
+
│ ├── __init__.py
|
|
482
|
+
│ ├── cli.py
|
|
483
|
+
│ ├── doctor.py
|
|
484
|
+
│ ├── generator.py
|
|
485
|
+
│ ├── registry.py
|
|
486
|
+
│ └── utils.py
|
|
487
|
+
│
|
|
488
|
+
├── templates/
|
|
489
|
+
│ └── python/
|
|
490
|
+
│ └── main.py
|
|
491
|
+
│
|
|
492
|
+
├── tests/
|
|
493
|
+
│ ├── test_cli.py
|
|
494
|
+
│ ├── test_generator.py
|
|
495
|
+
│ ├── test_registry.py
|
|
496
|
+
│ └── test_utils.py
|
|
497
|
+
│
|
|
498
|
+
├── README.md
|
|
499
|
+
├── LICENSE
|
|
500
|
+
└── pyproject.toml
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
## Main Components
|
|
504
|
+
|
|
505
|
+
### `cli.py`
|
|
506
|
+
|
|
507
|
+
Handles the command-line interface and commands such as:
|
|
508
|
+
|
|
509
|
+
```text
|
|
510
|
+
create
|
|
511
|
+
list
|
|
512
|
+
info
|
|
513
|
+
doctor
|
|
514
|
+
--version
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### `generator.py`
|
|
518
|
+
|
|
519
|
+
Contains the project generation logic for:
|
|
520
|
+
|
|
521
|
+
- Python
|
|
522
|
+
- Django
|
|
523
|
+
- Flask
|
|
524
|
+
- FastAPI
|
|
525
|
+
|
|
526
|
+
It also handles virtual environment creation and dependency installation for supported frameworks.
|
|
527
|
+
|
|
528
|
+
### `registry.py`
|
|
529
|
+
|
|
530
|
+
Contains the registered project generators and project information.
|
|
531
|
+
|
|
532
|
+
### `utils.py`
|
|
533
|
+
|
|
534
|
+
Contains utility functions such as project-name validation.
|
|
535
|
+
|
|
536
|
+
### `doctor.py`
|
|
537
|
+
|
|
538
|
+
Provides the `projectstarter doctor` diagnostic command.
|
|
539
|
+
|
|
540
|
+
### `tests/`
|
|
541
|
+
|
|
542
|
+
Contains the automated test suite.
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
# ➕ Adding a New Generator
|
|
547
|
+
|
|
548
|
+
ProjectStarter is designed so that new project types can be added to the generator system.
|
|
549
|
+
|
|
550
|
+
A new generator generally needs:
|
|
551
|
+
|
|
552
|
+
1. A generator function in `generator.py`.
|
|
553
|
+
2. Registration in `registry.py`.
|
|
554
|
+
3. Project information in `PROJECT_INFO`.
|
|
555
|
+
4. Tests in `tests/test_generator.py`.
|
|
556
|
+
5. CLI tests when necessary.
|
|
557
|
+
6. Documentation in this README.
|
|
558
|
+
|
|
559
|
+
This keeps the CLI organized and makes the tool easier to extend.
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
# 🔐 Project Name Rules
|
|
564
|
+
|
|
565
|
+
ProjectStarter validates project names before creating projects.
|
|
566
|
+
|
|
567
|
+
Valid examples:
|
|
568
|
+
|
|
569
|
+
```text
|
|
570
|
+
myproject
|
|
571
|
+
my_project
|
|
572
|
+
project123
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
Invalid examples:
|
|
576
|
+
|
|
577
|
+
```text
|
|
578
|
+
my-project
|
|
579
|
+
my project
|
|
580
|
+
123project
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
Project names must use letters, numbers, and underscores and must not start with a number.
|
|
584
|
+
|
|
585
|
+
---
|
|
586
|
+
|
|
587
|
+
# 👨💻 Author
|
|
588
|
+
|
|
589
|
+
**Mohamed Ali**
|
|
590
|
+
|
|
591
|
+
ProjectStarter was created and is maintained by Mohamed Ali.
|
|
592
|
+
|
|
593
|
+
## 📞 Contact
|
|
594
|
+
|
|
595
|
+
For questions, suggestions, bug reports, or contributions, contact the project maintainer through GitHub.
|
|
596
|
+
|
|
597
|
+
- GitHub: https://github.com/hamada-cool
|
|
598
|
+
- Project Repository: https://github.com/hamada-cool/projectstarter
|
|
599
|
+
- Bug Reports / Issues: https://github.com/hamada-cool/projectstarter/issues
|
|
600
|
+
- Email: `mohamedali32947@gmail.com`
|
|
601
|
+
- Phone / WhatsApp: `+918341391506` & `+249919532947`
|
|
602
|
+
|
|
603
|
+
You can also open a GitHub Issue if you find a bug or have an idea for improving ProjectStarter.
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
# 🤝 Contributing
|
|
608
|
+
|
|
609
|
+
Contributions, bug reports, suggestions, and improvements are welcome.
|
|
610
|
+
|
|
611
|
+
Before submitting changes:
|
|
612
|
+
|
|
613
|
+
1. Create a branch for your change.
|
|
614
|
+
2. Make your changes.
|
|
615
|
+
3. Run the test suite.
|
|
616
|
+
4. Make sure all tests pass.
|
|
617
|
+
5. Open a pull request.
|
|
618
|
+
|
|
619
|
+
Run tests with:
|
|
620
|
+
|
|
621
|
+
```bash
|
|
622
|
+
python -m pytest
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
---
|
|
626
|
+
|
|
627
|
+
# 📄 License
|
|
628
|
+
|
|
629
|
+
ProjectStarter is licensed under the **MIT License**.
|
|
630
|
+
|
|
631
|
+
See the `LICENSE` file for the complete license text.
|
|
632
|
+
|
|
633
|
+
---
|
|
634
|
+
|
|
635
|
+
# 🎯 Project Status
|
|
636
|
+
|
|
637
|
+
ProjectStarter currently supports:
|
|
638
|
+
|
|
639
|
+
- Python
|
|
640
|
+
- Django
|
|
641
|
+
- Flask
|
|
642
|
+
- FastAPI
|
|
643
|
+
|
|
644
|
+
The project is under active development, and more generators and features may be added in future releases.
|
|
645
|
+
|
|
646
|
+
---
|
|
647
|
+
|
|
648
|
+
## ⭐ Support the Project
|
|
649
|
+
|
|
650
|
+
If you find ProjectStarter useful, you can support the project by:
|
|
651
|
+
|
|
652
|
+
- ⭐ Starring the GitHub repository
|
|
653
|
+
- 🐛 Reporting bugs
|
|
654
|
+
- 💡 Suggesting features
|
|
655
|
+
- 🤝 Contributing code
|
|
656
|
+
- 📢 Sharing the project with other developers
|
|
657
|
+
|
|
658
|
+
---
|
|
659
|
+
|
|
660
|
+
**ProjectStarter — Start your next Python project faster. 🚀**
|
|
661
|
+
|
|
662
|
+
Created by **Mohamed Ali**.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
projectstarter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
projectstarter/cli.py,sha256=la3FKMG-IHtXvezPfrCGvQOmdHDR_HjqRYTDxn9SdaA,4362
|
|
3
|
+
projectstarter/doctor.py,sha256=PUbIJlscjrZ0ygYMnrXet3ZRSVf27kq0bV9I5FCRE5Y,728
|
|
4
|
+
projectstarter/generator.py,sha256=E9MN0Dsj1zOMDbQc_1xFypM0qcuDpHSBh2IghHomlRo,8695
|
|
5
|
+
projectstarter/registry.py,sha256=iPCSDNe-kx4_xpQNNfruTMlmQHqcZc2mXc0Q__INR0A,1142
|
|
6
|
+
projectstarter/utils.py,sha256=ynnZaePI8WHJiSMK3UAoN4KWtewJ3m7su51Mi2KvjSI,238
|
|
7
|
+
projectstarter_cli-0.1.0.dist-info/licenses/LICENSE,sha256=BUUmY_xjQwdENt5OLI0QO1Q_ctwJUM0xz-2Aj4G1vcM,1087
|
|
8
|
+
projectstarter_cli-0.1.0.dist-info/METADATA,sha256=tDG5bq0oZJyDFCCaV28n4ikfURNZ5yMDbuFtzQ_YSPg,12352
|
|
9
|
+
projectstarter_cli-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
10
|
+
projectstarter_cli-0.1.0.dist-info/entry_points.txt,sha256=yHK-APrWsPY-8sod6aDLVFyJHB0MjFc3lFUHqG63JJE,59
|
|
11
|
+
projectstarter_cli-0.1.0.dist-info/top_level.txt,sha256=ICKAYB4LSinvDfQ63-WcbOo4pM8zFsKugY7O0o1Ekdc,15
|
|
12
|
+
projectstarter_cli-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mohamed Ali
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
projectstarter
|