archiforge 0.1.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.
- archiforge-0.1.0/PKG-INFO +23 -0
- archiforge-0.1.0/README.md +12 -0
- archiforge-0.1.0/pyproject.toml +24 -0
- archiforge-0.1.0/setup.cfg +4 -0
- archiforge-0.1.0/src/archiforge/__init__.py +0 -0
- archiforge-0.1.0/src/archiforge/cli/main.py +102 -0
- archiforge-0.1.0/src/archiforge/core/engine.py +81 -0
- archiforge-0.1.0/src/archiforge.egg-info/PKG-INFO +23 -0
- archiforge-0.1.0/src/archiforge.egg-info/SOURCES.txt +11 -0
- archiforge-0.1.0/src/archiforge.egg-info/dependency_links.txt +1 -0
- archiforge-0.1.0/src/archiforge.egg-info/entry_points.txt +2 -0
- archiforge-0.1.0/src/archiforge.egg-info/requires.txt +3 -0
- archiforge-0.1.0/src/archiforge.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: archiforge
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A smart project scaffolding tool for developers
|
|
5
|
+
Author-email: Abdullah <your-email@example.com>
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: click
|
|
9
|
+
Requires-Dist: jinja2
|
|
10
|
+
Requires-Dist: pyyaml
|
|
11
|
+
|
|
12
|
+
# Archiforge 🛠️
|
|
13
|
+
|
|
14
|
+
**Archiforge** is a multi-language project scaffolding engine. It helps developers "forge" standardized project structures for Python, JavaScript, Go, and more.
|
|
15
|
+
|
|
16
|
+
## 🎯 Key Goals
|
|
17
|
+
- **Multi-language Support**: Generate blueprints for any stack.
|
|
18
|
+
- **Customizable**: Users can create their own project templates.
|
|
19
|
+
- **CLI Driven**: Fast and intuitive command-line interface.
|
|
20
|
+
|
|
21
|
+
## 📂 Structure
|
|
22
|
+
- `src/archiforge/core`: The logic that builds the files.
|
|
23
|
+
- `src/archiforge/blueprints`: Templates for different languages.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Archiforge 🛠️
|
|
2
|
+
|
|
3
|
+
**Archiforge** is a multi-language project scaffolding engine. It helps developers "forge" standardized project structures for Python, JavaScript, Go, and more.
|
|
4
|
+
|
|
5
|
+
## 🎯 Key Goals
|
|
6
|
+
- **Multi-language Support**: Generate blueprints for any stack.
|
|
7
|
+
- **Customizable**: Users can create their own project templates.
|
|
8
|
+
- **CLI Driven**: Fast and intuitive command-line interface.
|
|
9
|
+
|
|
10
|
+
## 📂 Structure
|
|
11
|
+
- `src/archiforge/core`: The logic that builds the files.
|
|
12
|
+
- `src/archiforge/blueprints`: Templates for different languages.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "archiforge"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name="Abdullah", email="your-email@example.com" },
|
|
10
|
+
]
|
|
11
|
+
description = "A smart project scaffolding tool for developers"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.8"
|
|
14
|
+
dependencies = [
|
|
15
|
+
"click",
|
|
16
|
+
"jinja2",
|
|
17
|
+
"pyyaml",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.scripts]
|
|
21
|
+
archiforge = "archiforge.cli.main:cli"
|
|
22
|
+
|
|
23
|
+
[tool.setuptools.packages.find]
|
|
24
|
+
where = ["src"]
|
|
File without changes
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import os
|
|
3
|
+
import subprocess
|
|
4
|
+
import time
|
|
5
|
+
from archiforge.core.engine import ForgeEngine
|
|
6
|
+
|
|
7
|
+
@click.group()
|
|
8
|
+
def cli():
|
|
9
|
+
"""Archiforge: أداة بناء المشاريع الذكية المتعددة اللغات 🛠️"""
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
@cli.command()
|
|
13
|
+
@click.option('--name', prompt='Project Name', help='اسم المشروع الجديد')
|
|
14
|
+
@click.option('--author', prompt='Author Name', help='اسم المبرمج')
|
|
15
|
+
@click.option('--description', prompt='Description', help='وصف مختصر للمشروع')
|
|
16
|
+
@click.option('--lang', default='python', help='اللغة المستخدمة')
|
|
17
|
+
@click.option('--git-init', is_flag=True, help='تهيئة مستودع Git تلقائياً')
|
|
18
|
+
@click.option('--include-tests', prompt='Include tests directory?', is_flag=True, default=False)
|
|
19
|
+
@click.option('--with-db', prompt='Include Database (SQLAlchemy)?', is_flag=True, default=False)
|
|
20
|
+
|
|
21
|
+
@click.option('--code', is_flag=True, help='Open the project in VS Code after forging')
|
|
22
|
+
def create(name, author, description, lang, git_init, include_tests, with_db, code):
|
|
23
|
+
|
|
24
|
+
"""إنشاء مشروع جديد مع شريط تقدم وتفاعل ذكي"""
|
|
25
|
+
|
|
26
|
+
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
27
|
+
template_path = os.path.join(base_dir, "blueprints", lang)
|
|
28
|
+
output_path = os.path.join(os.getcwd(), name)
|
|
29
|
+
|
|
30
|
+
if not os.path.exists(template_path):
|
|
31
|
+
click.secho(f"❌ Error: Template '{lang}' not found!", fg="red", bold=True)
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
if os.path.exists(output_path):
|
|
35
|
+
|
|
36
|
+
if not click.confirm(click.style(f"⚠️ The directory '{name}' already exists. Overwrite?", fg="yellow")):
|
|
37
|
+
click.echo("❌ Operation cancelled.")
|
|
38
|
+
return
|
|
39
|
+
if code:
|
|
40
|
+
click.echo(click.style("🖥️ Opening VS Code...", fg="cyan"))
|
|
41
|
+
try:
|
|
42
|
+
# أمر 'code .' يفتح المجلد الحالي في VS Code
|
|
43
|
+
subprocess.run(['code', output_path], shell=True)
|
|
44
|
+
except Exception as e:
|
|
45
|
+
click.secho(f"⚠️ Could not open VS Code: {e}", fg="yellow")
|
|
46
|
+
context = {
|
|
47
|
+
"project_name": name,
|
|
48
|
+
"author": author,
|
|
49
|
+
"description": description,
|
|
50
|
+
"include_tests": include_tests
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
engine = ForgeEngine(template_path, output_path, context)
|
|
55
|
+
|
|
56
|
+
# --- شريط التحميل الجمالي ---
|
|
57
|
+
click.echo(click.style(f"\n🚀 Starting the forge for '{name}'...", fg="magenta", bold=True))
|
|
58
|
+
|
|
59
|
+
with click.progressbar(length=100, label='⚒️ Forging project structure') as bar:
|
|
60
|
+
# محاكاة خطوات العمل لجعل الشريط يبدو واقعياً
|
|
61
|
+
time.sleep(0.3)
|
|
62
|
+
bar.update(20)
|
|
63
|
+
|
|
64
|
+
engine.forge() # العملية الحقيقية تحدث هنا
|
|
65
|
+
|
|
66
|
+
time.sleep(0.3)
|
|
67
|
+
bar.update(80)
|
|
68
|
+
# ---------------------------
|
|
69
|
+
|
|
70
|
+
if git_init:
|
|
71
|
+
click.echo(click.style("⚓ Integrating Git repository...", fg="blue"))
|
|
72
|
+
os.chdir(output_path)
|
|
73
|
+
subprocess.run(['git', 'init'], check=True, capture_output=True)
|
|
74
|
+
subprocess.run(['git', 'add', '.'], check=True)
|
|
75
|
+
subprocess.run(['git', 'commit', '-m', 'Initial commit by Archiforge'], check=True, capture_output=True)
|
|
76
|
+
click.secho("✅ Git integration complete!", fg="green")
|
|
77
|
+
|
|
78
|
+
click.echo(click.style(f"\n✨ Project '{name}' is ready at: ", fg="green") + click.style(output_path, underline=True))
|
|
79
|
+
|
|
80
|
+
except Exception as e:
|
|
81
|
+
click.secho(f"💥 An unexpected error occurred: {e}", fg="red", bold=True)
|
|
82
|
+
|
|
83
|
+
@cli.command()
|
|
84
|
+
def list():
|
|
85
|
+
"""عرض كافة القوالب المتاحة"""
|
|
86
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
87
|
+
base_dir = os.path.dirname(current_dir) # سيعود لمجلد archiforge داخل src
|
|
88
|
+
blueprints_path = os.path.join(base_dir, "blueprints")
|
|
89
|
+
|
|
90
|
+
if not os.path.exists(blueprints_path):
|
|
91
|
+
click.secho("📂 No blueprints directory found.", fg="yellow")
|
|
92
|
+
return
|
|
93
|
+
|
|
94
|
+
blueprints = [d for d in os.listdir(blueprints_path)
|
|
95
|
+
if os.path.isdir(os.path.join(blueprints_path, d))]
|
|
96
|
+
|
|
97
|
+
click.secho("📂 Available Blueprints in Archiforge:", fg="cyan", bold=True)
|
|
98
|
+
for bp in blueprints:
|
|
99
|
+
click.echo(f" - {bp}")
|
|
100
|
+
|
|
101
|
+
if __name__ == "__main__":
|
|
102
|
+
cli()
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import yaml
|
|
3
|
+
import subprocess
|
|
4
|
+
from jinja2 import Template
|
|
5
|
+
|
|
6
|
+
class ForgeEngine:
|
|
7
|
+
def __init__(self, template_path, output_path, context):
|
|
8
|
+
"""
|
|
9
|
+
template_path: مسار مجلد القالب
|
|
10
|
+
output_path: مسار المشروع الجديد المراد إنشاؤه
|
|
11
|
+
context: البيانات (الاسم، المؤلف، الوصف)
|
|
12
|
+
"""
|
|
13
|
+
self.template_path = template_path
|
|
14
|
+
self.output_path = output_path
|
|
15
|
+
self.context = context
|
|
16
|
+
|
|
17
|
+
def load_structure(self):
|
|
18
|
+
"""تحميل ومعالجة ملف structure.yaml كقالب Jinja2 أولاً"""
|
|
19
|
+
yaml_file = os.path.join(self.template_path, "structure.yaml")
|
|
20
|
+
if not os.path.exists(yaml_file):
|
|
21
|
+
raise FileNotFoundError(f"Missing structure.yaml in {self.template_path}")
|
|
22
|
+
|
|
23
|
+
with open(yaml_file, 'r', encoding='utf-8') as f:
|
|
24
|
+
raw_yaml = f.read()
|
|
25
|
+
|
|
26
|
+
# السحر هنا: معالجة الـ YAML نفسه كقالب قبل تحويله لبيانات
|
|
27
|
+
rendered_yaml = Template(raw_yaml).render(self.context)
|
|
28
|
+
return yaml.safe_load(rendered_yaml)
|
|
29
|
+
|
|
30
|
+
def forge(self):
|
|
31
|
+
"""الوظيفة الأساسية لبناء المشروع"""
|
|
32
|
+
structure = self.load_structure()
|
|
33
|
+
|
|
34
|
+
# التأكد من إنشاء المجلد الرئيسي للمشروع أولاً
|
|
35
|
+
if not os.path.exists(self.output_path):
|
|
36
|
+
os.makedirs(self.output_path, exist_ok=True)
|
|
37
|
+
print(f"🏗️ Created project root: {self.output_path}")
|
|
38
|
+
|
|
39
|
+
# 1. إنشاء المجلدات الفرعية المذكورة في القالب
|
|
40
|
+
for folder in structure.get('directories', []):
|
|
41
|
+
rendered_folder = Template(folder).render(self.context)
|
|
42
|
+
path = os.path.join(self.output_path, rendered_folder)
|
|
43
|
+
os.makedirs(path, exist_ok=True)
|
|
44
|
+
print(f"📁 Created directory: {path}")
|
|
45
|
+
|
|
46
|
+
# 2. إنشاء الملفات وتعبئة محتواها
|
|
47
|
+
for file_info in structure.get('files', []):
|
|
48
|
+
rendered_path = Template(file_info['path']).render(self.context)
|
|
49
|
+
rendered_content = Template(file_info['content']).render(self.context)
|
|
50
|
+
|
|
51
|
+
full_path = os.path.join(self.output_path, rendered_path)
|
|
52
|
+
|
|
53
|
+
# التأكد من وجود المجلد الأب للملف (في حال كان ملفاً عميقاً)
|
|
54
|
+
os.makedirs(os.path.dirname(full_path), exist_ok=True)
|
|
55
|
+
|
|
56
|
+
with open(full_path, 'w', encoding='utf-8') as f:
|
|
57
|
+
f.write(rendered_content)
|
|
58
|
+
print(f"📄 Created file: {full_path}")
|
|
59
|
+
|
|
60
|
+
# 3. تنفيذ أوامر ما بعد البناء
|
|
61
|
+
self.run_post_commands(structure.get('post_commands', []))
|
|
62
|
+
|
|
63
|
+
print(f"\n✅ Archiforge: Project '{self.context['project_name']}' forged successfully!")
|
|
64
|
+
|
|
65
|
+
def run_post_commands(self, commands):
|
|
66
|
+
"""تنفيذ أوامر مثل git init أو npm install"""
|
|
67
|
+
if not commands:
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
original_dir = os.getcwd()
|
|
71
|
+
os.chdir(self.output_path)
|
|
72
|
+
|
|
73
|
+
for cmd in commands:
|
|
74
|
+
rendered_cmd = Template(cmd).render(self.context)
|
|
75
|
+
print(f"⚡ Running: {rendered_cmd}...")
|
|
76
|
+
try:
|
|
77
|
+
subprocess.run(rendered_cmd, shell=True, check=True)
|
|
78
|
+
except subprocess.CalledProcessError as e:
|
|
79
|
+
print(f"⚠️ Command failed: {e}")
|
|
80
|
+
|
|
81
|
+
os.chdir(original_dir)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: archiforge
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A smart project scaffolding tool for developers
|
|
5
|
+
Author-email: Abdullah <your-email@example.com>
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: click
|
|
9
|
+
Requires-Dist: jinja2
|
|
10
|
+
Requires-Dist: pyyaml
|
|
11
|
+
|
|
12
|
+
# Archiforge 🛠️
|
|
13
|
+
|
|
14
|
+
**Archiforge** is a multi-language project scaffolding engine. It helps developers "forge" standardized project structures for Python, JavaScript, Go, and more.
|
|
15
|
+
|
|
16
|
+
## 🎯 Key Goals
|
|
17
|
+
- **Multi-language Support**: Generate blueprints for any stack.
|
|
18
|
+
- **Customizable**: Users can create their own project templates.
|
|
19
|
+
- **CLI Driven**: Fast and intuitive command-line interface.
|
|
20
|
+
|
|
21
|
+
## 📂 Structure
|
|
22
|
+
- `src/archiforge/core`: The logic that builds the files.
|
|
23
|
+
- `src/archiforge/blueprints`: Templates for different languages.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/archiforge/__init__.py
|
|
4
|
+
src/archiforge.egg-info/PKG-INFO
|
|
5
|
+
src/archiforge.egg-info/SOURCES.txt
|
|
6
|
+
src/archiforge.egg-info/dependency_links.txt
|
|
7
|
+
src/archiforge.egg-info/entry_points.txt
|
|
8
|
+
src/archiforge.egg-info/requires.txt
|
|
9
|
+
src/archiforge.egg-info/top_level.txt
|
|
10
|
+
src/archiforge/cli/main.py
|
|
11
|
+
src/archiforge/core/engine.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
archiforge
|