clapp-pm 1.0.20__py3-none-any.whl → 1.0.22__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.
- {clapp_pm-1.0.20.data → clapp_pm-1.0.22.data}/data/version.json +1 -1
- {clapp_pm-1.0.20.dist-info → clapp_pm-1.0.22.dist-info}/METADATA +1 -1
- {clapp_pm-1.0.20.dist-info → clapp_pm-1.0.22.dist-info}/RECORD +10 -8
- {clapp_pm-1.0.20.dist-info → clapp_pm-1.0.22.dist-info}/top_level.txt +2 -0
- new_command.py +181 -0
- progress_utils.py +173 -0
- version.py +1 -1
- {clapp_pm-1.0.20.dist-info → clapp_pm-1.0.22.dist-info}/WHEEL +0 -0
- {clapp_pm-1.0.20.dist-info → clapp_pm-1.0.22.dist-info}/entry_points.txt +0 -0
- {clapp_pm-1.0.20.dist-info → clapp_pm-1.0.22.dist-info}/licenses/LICENSE +0 -0
@@ -12,16 +12,18 @@ list_command.py,sha256=qbeocvrg2eXRklxbYS3audQhYHGXTlMBk_tNh1cMxd0,8391
|
|
12
12
|
main.py,sha256=uf2-LzBBFIwIiyg1kcyZG4J1B9f5U33VHieBXu1uLi8,23889
|
13
13
|
manifest_schema.py,sha256=qR6dIpYL1zwAJmrij05gkgE_urN3qVamoUi2BgR7Lv4,2801
|
14
14
|
manifest_validator.py,sha256=JW0mETHDQCSMhodZ5sntr5KPU8T5LYv4IiVoAp4zOIY,8092
|
15
|
+
new_command.py,sha256=gz1w8zMf-gFITtRQAc9G2WES2akuCwdH7dtuDu9TacU,5926
|
15
16
|
package_registry.py,sha256=Rco15cvz-6lpCEDdCzwGZNCKtvVhlFIsEPy-WFAESMM,4233
|
16
17
|
package_runner.py,sha256=GqLPlQRxh7g3bDgGDSVpmHdeRXaP5f6s8kp8QVnw5LM,5783
|
17
18
|
package_signing.py,sha256=ModMAzLk08rkI6zd8QKhyCH5BFbB-7dy8pwqKYatFQo,4579
|
18
19
|
post_install_hint.py,sha256=wjMPCgRurZiGu6hv_se-XA36KqBCdeYdRCD1q7FrJzQ,4918
|
20
|
+
progress_utils.py,sha256=ZH73QNLd5mI4h-JU0hSFR2OU8lesr2XteSZdmFD0bFA,5995
|
19
21
|
publish_command.py,sha256=P05AFbu_mxcc1yAiwShN5Yi9PX1o_7TFXD1mowJcqJE,8589
|
20
22
|
remote_registry.py,sha256=rPBIM_ESXUt0br5cARQ4YbzUoTda0G4e1KGzfyYMbpQ,8235
|
21
23
|
smart_search.py,sha256=R5O5CDXqlQc-N-6R6D5k36_-arCB-wnKfmWr5zMYWUI,15741
|
22
24
|
uninstall_command.py,sha256=rQYbZ-XMw8Xxw1fmgGdDaBQmgBGqyJ_rTBZkvEV5HV0,7066
|
23
25
|
validate_command.py,sha256=idaujErzrwuZNT6DYCVTVwZqBDEEi1GTxIXAGBgKMKM,7623
|
24
|
-
version.py,sha256=
|
26
|
+
version.py,sha256=eieXzRht0Gi6TgXgx-HNBh7q-2wbwT9FgWwXK-Ph6Yk,224
|
25
27
|
version_command.py,sha256=DZuYWtohSeM5PJNYCflBy36_k0vex3tYV2C8ixEA9ho,4259
|
26
28
|
version_manager.py,sha256=fpC7jxhIW1wZhJ9IkVwyqkgJN4mhBjUUbaLefXLDMiM,11423
|
27
29
|
where_command.py,sha256=TcLoXLGmrPSHQuvlceVuuKBsfeadIwz-E0G_5okH14g,6420
|
@@ -60,8 +62,8 @@ clapp-packages-repo/packages/test-app/main.py,sha256=rN4Zo9u53bIVjcUlul059knx6v-
|
|
60
62
|
clapp-packages-repo/packages/test-app/manifest.json,sha256=kJe4sjYdPRNZD5hEeca80jj3lxeEWBMJoZ59RW7tiKI,118
|
61
63
|
clapp-packages-repo/packages/test-app2/main.py,sha256=lHkbjTmehFY4VuYYF2dYiVBH7W0oqHHeY0I5W85iPTY,35
|
62
64
|
clapp-packages-repo/packages/test-app2/manifest.json,sha256=vshXJrtRxBc_ISM6E8KT5BSmveMbjWszenlgxgSN86w,121
|
63
|
-
clapp_pm-1.0.
|
64
|
-
clapp_pm-1.0.
|
65
|
+
clapp_pm-1.0.22.data/data/version.json,sha256=Rzn1cwLuEJd-nwrMAw5onWyppNZsXZtMsnndzyYQaPg,239
|
66
|
+
clapp_pm-1.0.22.dist-info/licenses/LICENSE,sha256=_hryv9pKR6udRexceUYuoYCJGmYBz7e-vRuFWmm38UY,1075
|
65
67
|
docs/developer_guide.md,sha256=B-S141TSNy7e8T9KaV6Fr-ZAFhYqqgcwqWijjX0C2Xc,7336
|
66
68
|
templates/dart/manifest.json,sha256=ycVKZxrArzcSoRZ5LKKe8aOerwk5Z-7VX0td86aim0M,267
|
67
69
|
templates/lua/manifest.json,sha256=CRIy0dP6Pr3vH6IV4dObGs4KqqJ_sURsY0wAgK2av7E,262
|
@@ -71,8 +73,8 @@ templates/python/manifest.json,sha256=hjmKqsEkWEBTwxFgm35MkvuwWZ2CQWq9Zo8uHodqHr
|
|
71
73
|
test-app/README.md,sha256=AqVgCZ-cwXBuDHFoJdYkAHAuB6SjSjqXQrjhLu0q7cc,964
|
72
74
|
test-app/main.py,sha256=24IEuyHSuPWJp2-xYhInUNEWqeueGxAO3NBgHkEgLdQ,1562
|
73
75
|
test-app/manifest.json,sha256=MM1nl5Bljrnsik3fwsrgFBchfgwIb2REoBwwzNpFHQU,284
|
74
|
-
clapp_pm-1.0.
|
75
|
-
clapp_pm-1.0.
|
76
|
-
clapp_pm-1.0.
|
77
|
-
clapp_pm-1.0.
|
78
|
-
clapp_pm-1.0.
|
76
|
+
clapp_pm-1.0.22.dist-info/METADATA,sha256=6RDt7lHkh-BGtTBEWX-XeSZURL5D7DENBYi-qgJP_W4,3980
|
77
|
+
clapp_pm-1.0.22.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
78
|
+
clapp_pm-1.0.22.dist-info/entry_points.txt,sha256=7j-3pQVpQfnaVzUV83g7zlCA30ePlnXkhHLAGGz9xrQ,36
|
79
|
+
clapp_pm-1.0.22.dist-info/top_level.txt,sha256=2FeS-lC1OV3lBqLAHahLU8vcWxlxSDLNJSk-4MmymKk,475
|
80
|
+
clapp_pm-1.0.22.dist-info/RECORD,,
|
new_command.py
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
new_command.py - Yeni Uygulama Oluşturma Komutu
|
4
|
+
|
5
|
+
Bu modül clapp için yeni uygulama şablonları oluşturur.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import os
|
9
|
+
import shutil
|
10
|
+
import json
|
11
|
+
from pathlib import Path
|
12
|
+
from package_runner import get_supported_languages
|
13
|
+
|
14
|
+
def create_new_app(language: str, app_name: str, target_dir: str | None = None) -> tuple[bool, str]:
|
15
|
+
"""
|
16
|
+
Yeni bir clapp uygulaması oluşturur
|
17
|
+
|
18
|
+
Args:
|
19
|
+
language: Programlama dili
|
20
|
+
app_name: Uygulama adı
|
21
|
+
target_dir: Hedef dizin (opsiyonel)
|
22
|
+
|
23
|
+
Returns:
|
24
|
+
(success, message)
|
25
|
+
"""
|
26
|
+
try:
|
27
|
+
# Dil kontrolü
|
28
|
+
if language.lower() not in get_supported_languages():
|
29
|
+
supported = ', '.join(get_supported_languages())
|
30
|
+
return False, f"Desteklenmeyen dil: {language}. Desteklenen diller: {supported}"
|
31
|
+
|
32
|
+
# Uygulama adı kontrolü
|
33
|
+
if not app_name or not app_name.strip():
|
34
|
+
return False, "Uygulama adı boş olamaz"
|
35
|
+
|
36
|
+
app_name = app_name.strip().lower()
|
37
|
+
|
38
|
+
# Geçersiz karakter kontrolü
|
39
|
+
invalid_chars = ['/', '\\', ':', '*', '?', '"', '<', '>', '|']
|
40
|
+
for char in invalid_chars:
|
41
|
+
if char in app_name:
|
42
|
+
return False, f"Uygulama adında geçersiz karakter: {char}"
|
43
|
+
|
44
|
+
# Hedef dizin belirleme
|
45
|
+
if target_dir:
|
46
|
+
target_path = Path(target_dir) / app_name
|
47
|
+
else:
|
48
|
+
target_path = Path.cwd() / app_name
|
49
|
+
|
50
|
+
# Dizin zaten var mı kontrol et
|
51
|
+
if target_path.exists():
|
52
|
+
return False, f"Dizin zaten mevcut: {target_path}"
|
53
|
+
|
54
|
+
# Şablon dizini
|
55
|
+
template_dir = Path(__file__).parent / "templates" / language.lower()
|
56
|
+
|
57
|
+
if not template_dir.exists():
|
58
|
+
return False, f"Şablon bulunamadı: {language}"
|
59
|
+
|
60
|
+
# Dizini oluştur
|
61
|
+
target_path.mkdir(parents=True, exist_ok=True)
|
62
|
+
|
63
|
+
# Şablon dosyalarını kopyala
|
64
|
+
for item in template_dir.iterdir():
|
65
|
+
if item.is_file():
|
66
|
+
# Dosya adını uygulama adına göre güncelle
|
67
|
+
if item.name == "manifest.json":
|
68
|
+
update_manifest(item, target_path / item.name, app_name, language)
|
69
|
+
else:
|
70
|
+
shutil.copy2(item, target_path / item.name)
|
71
|
+
elif item.is_dir():
|
72
|
+
# Alt dizinleri kopyala
|
73
|
+
shutil.copytree(item, target_path / item.name)
|
74
|
+
|
75
|
+
# Başarı mesajı
|
76
|
+
success_message = f"""
|
77
|
+
✅ Yeni {language} uygulaması oluşturuldu!
|
78
|
+
|
79
|
+
📁 Dizin: {target_path}
|
80
|
+
🚀 Çalıştırmak için:
|
81
|
+
cd {app_name}
|
82
|
+
clapp validate .
|
83
|
+
clapp install .
|
84
|
+
clapp run {app_name}
|
85
|
+
|
86
|
+
📖 Geliştirme için docs/developer_guide.md dosyasını inceleyin.
|
87
|
+
""".strip()
|
88
|
+
|
89
|
+
return True, success_message
|
90
|
+
|
91
|
+
except Exception as e:
|
92
|
+
return False, f"Uygulama oluşturma hatası: {str(e)}"
|
93
|
+
|
94
|
+
def update_manifest(template_path: Path, target_path: Path, app_name: str, language: str):
|
95
|
+
"""
|
96
|
+
Manifest dosyasını uygulama adına göre günceller
|
97
|
+
|
98
|
+
Args:
|
99
|
+
template_path: Şablon manifest dosyası
|
100
|
+
target_path: Hedef manifest dosyası
|
101
|
+
app_name: Uygulama adı
|
102
|
+
language: Programlama dili
|
103
|
+
"""
|
104
|
+
try:
|
105
|
+
# Şablon manifest'i oku
|
106
|
+
with open(template_path, 'r', encoding='utf-8') as f:
|
107
|
+
manifest = json.load(f)
|
108
|
+
|
109
|
+
# Uygulama adını güncelle
|
110
|
+
manifest['name'] = app_name
|
111
|
+
|
112
|
+
# Açıklamayı güncelle
|
113
|
+
if 'description' in manifest:
|
114
|
+
manifest['description'] = manifest['description'].replace(
|
115
|
+
'hello-' + language.lower(), app_name
|
116
|
+
)
|
117
|
+
|
118
|
+
# Hedef dosyaya yaz
|
119
|
+
with open(target_path, 'w', encoding='utf-8') as f:
|
120
|
+
json.dump(manifest, f, indent=2, ensure_ascii=False)
|
121
|
+
|
122
|
+
except Exception as e:
|
123
|
+
print(f"⚠️ Manifest güncelleme hatası: {e}")
|
124
|
+
|
125
|
+
def list_available_templates() -> str:
|
126
|
+
"""
|
127
|
+
Mevcut şablonları listeler
|
128
|
+
|
129
|
+
Returns:
|
130
|
+
Formatlanmış şablon listesi
|
131
|
+
"""
|
132
|
+
templates_dir = Path(__file__).parent / "templates"
|
133
|
+
|
134
|
+
if not templates_dir.exists():
|
135
|
+
return "❌ Şablon dizini bulunamadı"
|
136
|
+
|
137
|
+
result = "📋 Mevcut Şablonlar:\n"
|
138
|
+
result += "=" * 30 + "\n\n"
|
139
|
+
|
140
|
+
for template in sorted(templates_dir.iterdir()):
|
141
|
+
if template.is_dir():
|
142
|
+
# Şablon bilgilerini oku
|
143
|
+
manifest_path = template / "manifest.json"
|
144
|
+
if manifest_path.exists():
|
145
|
+
try:
|
146
|
+
with open(manifest_path, 'r', encoding='utf-8') as f:
|
147
|
+
manifest = json.load(f)
|
148
|
+
|
149
|
+
name = manifest.get('name', template.name)
|
150
|
+
description = manifest.get('description', 'Açıklama yok')
|
151
|
+
language = manifest.get('language', 'unknown')
|
152
|
+
|
153
|
+
result += f"🌐 {language.upper()}\n"
|
154
|
+
result += f" 📝 {description}\n"
|
155
|
+
result += f" 📁 Şablon: {template.name}\n\n"
|
156
|
+
|
157
|
+
except Exception:
|
158
|
+
result += f"🌐 {template.name.upper()}\n"
|
159
|
+
result += f" 📁 Şablon: {template.name}\n\n"
|
160
|
+
|
161
|
+
result += "💡 Kullanım: clapp new <dil> <uygulama-adı>"
|
162
|
+
|
163
|
+
return result
|
164
|
+
|
165
|
+
def handle_new_command(args) -> tuple[bool, str]:
|
166
|
+
"""
|
167
|
+
new komutunu işler
|
168
|
+
|
169
|
+
Args:
|
170
|
+
args: Argümanlar
|
171
|
+
|
172
|
+
Returns:
|
173
|
+
(success, message)
|
174
|
+
"""
|
175
|
+
if args.list:
|
176
|
+
return True, list_available_templates()
|
177
|
+
|
178
|
+
if not args.language or not args.app_name:
|
179
|
+
return False, "Dil ve uygulama adı gerekli. Örnek: clapp new python my-app"
|
180
|
+
|
181
|
+
return create_new_app(args.language, args.app_name, args.target_dir)
|
progress_utils.py
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
progress_utils.py - Progress Bar ve İndirme Hızı Göstergesi
|
4
|
+
|
5
|
+
Bu modül indirme ve yükleme işlemleri için progress bar ve hız göstergesi sağlar.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import sys
|
9
|
+
import time
|
10
|
+
import threading
|
11
|
+
from typing import Optional, Callable
|
12
|
+
from urllib.request import urlopen
|
13
|
+
from urllib.error import URLError
|
14
|
+
from tqdm import tqdm
|
15
|
+
|
16
|
+
|
17
|
+
class ProgressBar:
|
18
|
+
"""Progress bar sınıfı"""
|
19
|
+
|
20
|
+
def __init__(self, total: int, description: str = "İndiriliyor", width: int = 50):
|
21
|
+
self.total = total
|
22
|
+
self.description = description
|
23
|
+
self.width = width
|
24
|
+
self.current = 0
|
25
|
+
self.start_time = time.time()
|
26
|
+
self.last_update = 0
|
27
|
+
self.speed = 0
|
28
|
+
self.lock = threading.Lock()
|
29
|
+
self.last_line_length = 0 # Son satır uzunluğunu takip et
|
30
|
+
|
31
|
+
def update(self, current: int, speed: Optional[float] = None):
|
32
|
+
"""Progress bar'ı günceller"""
|
33
|
+
with self.lock:
|
34
|
+
self.current = current
|
35
|
+
if speed is not None:
|
36
|
+
self.speed = speed
|
37
|
+
|
38
|
+
# Hız hesaplama
|
39
|
+
if self.current > 0:
|
40
|
+
elapsed = time.time() - self.start_time
|
41
|
+
if elapsed > 0:
|
42
|
+
self.speed = self.current / elapsed
|
43
|
+
|
44
|
+
def display(self):
|
45
|
+
if self.total <= 0:
|
46
|
+
return
|
47
|
+
|
48
|
+
percentage = (self.current / self.total) * 100
|
49
|
+
filled_width = int(self.width * self.current // self.total)
|
50
|
+
bar = '█' * filled_width + '░' * (self.width - filled_width)
|
51
|
+
speed_str = self._format_speed(self.speed)
|
52
|
+
current_str = self._format_size(self.current)
|
53
|
+
total_str = self._format_size(self.total)
|
54
|
+
progress_line = f"{self.description}: [{bar}] {percentage:5.1f}% | {current_str}/{total_str} | {speed_str}"
|
55
|
+
|
56
|
+
# Satır başına dön, progress barı yaz, kalan karakterleri temizle
|
57
|
+
pad = getattr(self, 'last_line_length', 0) - len(progress_line)
|
58
|
+
sys.stdout.write('\r' + progress_line + (' ' * pad if pad > 0 else ''))
|
59
|
+
sys.stdout.flush()
|
60
|
+
self.last_line_length = len(progress_line)
|
61
|
+
|
62
|
+
def finish(self, success: bool = True):
|
63
|
+
# Satırı temizle
|
64
|
+
sys.stdout.write('\r' + ' ' * getattr(self, 'last_line_length', 80) + '\r')
|
65
|
+
if success:
|
66
|
+
print(f"✅ {self.description} tamamlandı!")
|
67
|
+
else:
|
68
|
+
print(f"❌ {self.description} başarısız!")
|
69
|
+
sys.stdout.flush()
|
70
|
+
|
71
|
+
def _format_speed(self, speed: float) -> str:
|
72
|
+
"""Hızı formatlar (B/s, KB/s, MB/s)"""
|
73
|
+
if speed < 1024:
|
74
|
+
return f"{speed:.1f} B/s"
|
75
|
+
elif speed < 1024 * 1024:
|
76
|
+
return f"{speed/1024:.1f} KB/s"
|
77
|
+
else:
|
78
|
+
return f"{speed/(1024*1024):.1f} MB/s"
|
79
|
+
|
80
|
+
def _format_size(self, size: int) -> str:
|
81
|
+
"""Boyutu formatlar (B, KB, MB, GB)"""
|
82
|
+
if size < 1024:
|
83
|
+
return f"{size} B"
|
84
|
+
elif size < 1024 * 1024:
|
85
|
+
return f"{size/1024:.1f} KB"
|
86
|
+
elif size < 1024 * 1024 * 1024:
|
87
|
+
return f"{size/(1024*1024):.1f} MB"
|
88
|
+
else:
|
89
|
+
return f"{size/(1024*1024*1024):.1f} GB"
|
90
|
+
|
91
|
+
|
92
|
+
def download_with_progress(url: str, filename: str, description: str = "İndiriliyor") -> bool:
|
93
|
+
"""
|
94
|
+
tqdm ile dosya indirir
|
95
|
+
"""
|
96
|
+
try:
|
97
|
+
response = urlopen(url)
|
98
|
+
total_size = int(response.headers.get('content-length', 0))
|
99
|
+
response.close()
|
100
|
+
with urlopen(url) as response, open(filename, 'wb') as file, tqdm(
|
101
|
+
total=total_size, unit='B', unit_scale=True, desc=description, ncols=80
|
102
|
+
) as bar:
|
103
|
+
downloaded = 0
|
104
|
+
chunk_size = 8192
|
105
|
+
while True:
|
106
|
+
chunk = response.read(chunk_size)
|
107
|
+
if not chunk:
|
108
|
+
break
|
109
|
+
file.write(chunk)
|
110
|
+
downloaded += len(chunk)
|
111
|
+
bar.update(len(chunk))
|
112
|
+
print(f"✅ {description} tamamlandı!")
|
113
|
+
return True
|
114
|
+
except Exception as e:
|
115
|
+
print(f"❌ İndirme hatası: {e}")
|
116
|
+
return False
|
117
|
+
|
118
|
+
def copy_with_progress(src: str, dst: str, description: str = "Kopyalanıyor") -> bool:
|
119
|
+
import os
|
120
|
+
try:
|
121
|
+
total_size = os.path.getsize(src)
|
122
|
+
with open(src, 'rb') as src_file, open(dst, 'wb') as dst_file, tqdm(
|
123
|
+
total=total_size, unit='B', unit_scale=True, desc=description, ncols=80
|
124
|
+
) as bar:
|
125
|
+
copied = 0
|
126
|
+
chunk_size = 8192
|
127
|
+
while True:
|
128
|
+
chunk = src_file.read(chunk_size)
|
129
|
+
if not chunk:
|
130
|
+
break
|
131
|
+
dst_file.write(chunk)
|
132
|
+
copied += len(chunk)
|
133
|
+
bar.update(len(chunk))
|
134
|
+
print(f"✅ {description} tamamlandı!")
|
135
|
+
return True
|
136
|
+
except Exception as e:
|
137
|
+
print(f"❌ Kopyalama hatası: {e}")
|
138
|
+
return False
|
139
|
+
|
140
|
+
def extract_with_progress(zip_path: str, extract_path: str, description: str = "Çıkarılıyor") -> bool:
|
141
|
+
"""
|
142
|
+
tqdm ile ZIP dosyası çıkarır
|
143
|
+
"""
|
144
|
+
import zipfile
|
145
|
+
import os
|
146
|
+
try:
|
147
|
+
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
148
|
+
file_list = zip_ref.filelist
|
149
|
+
total_files = len(file_list)
|
150
|
+
if total_files == 0:
|
151
|
+
print(f"❌ ZIP dosyası boş: {zip_path}")
|
152
|
+
return False
|
153
|
+
with tqdm(total=total_files, desc=description, ncols=80, unit='dosya') as bar:
|
154
|
+
for file_info in file_list:
|
155
|
+
zip_ref.extract(file_info, extract_path)
|
156
|
+
bar.update(1)
|
157
|
+
print(f"✅ {description} tamamlandı!")
|
158
|
+
return True
|
159
|
+
except Exception as e:
|
160
|
+
print(f"❌ Çıkarma hatası: {e}")
|
161
|
+
return False
|
162
|
+
|
163
|
+
def show_success_message(message: str):
|
164
|
+
print(f"✅ {message}")
|
165
|
+
|
166
|
+
def show_error_message(message: str):
|
167
|
+
print(f"❌ {message}")
|
168
|
+
|
169
|
+
def show_info_message(message: str):
|
170
|
+
print(f"ℹ️ {message}")
|
171
|
+
|
172
|
+
def show_warning_message(message: str):
|
173
|
+
print(f"⚠️ {message}")
|
version.py
CHANGED
File without changes
|
File without changes
|
File without changes
|