clapp-pm 1.0.20__py3-none-any.whl → 1.0.21__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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "app_name": "clapp",
3
- "version": "1.0.20",
3
+ "version": "1.0.21",
4
4
  "author": "Melih Burak Memiş",
5
5
  "description": "Basit ve güçlü paket yöneticisi",
6
6
  "source": "https://github.com/melihburak/clapp",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clapp-pm
3
- Version: 1.0.20
3
+ Version: 1.0.21
4
4
  Summary: Lightweight cross-language app manager for Python and Lua
5
5
  Home-page: https://github.com/mburakmmm/clapp
6
6
  Author: Melih Burak Memiş
@@ -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=yiQ2e-jrU8UVt36iOC_pdKx6cuv1YPNCTZNIItbEPPU,8263
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=DMXUNBIpCO2h5TM6F6PU54p2mpOWyr1HvIyqrSE7UCo,224
26
+ version.py,sha256=H9_enMWKOmwY_YpwVRxCb26vBaOVq9GK3iQUblkJn68,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.20.data/data/version.json,sha256=FtynQTbhdQzZL8px_bdoOmnDJ3uCbv6bwgSZdh9q4vg,239
64
- clapp_pm-1.0.20.dist-info/licenses/LICENSE,sha256=_hryv9pKR6udRexceUYuoYCJGmYBz7e-vRuFWmm38UY,1075
65
+ clapp_pm-1.0.21.data/data/version.json,sha256=14ypbLPPM7__r9B0nGVxi9y3DQRkDYpd70LvStBPIXQ,239
66
+ clapp_pm-1.0.21.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.20.dist-info/METADATA,sha256=yMASz7ZaVYc8WTMVlHRigxdojDkHqqCXEJ7isHs4h8k,3980
75
- clapp_pm-1.0.20.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
76
- clapp_pm-1.0.20.dist-info/entry_points.txt,sha256=7j-3pQVpQfnaVzUV83g7zlCA30ePlnXkhHLAGGz9xrQ,36
77
- clapp_pm-1.0.20.dist-info/top_level.txt,sha256=PDW9iD4QCnGlt2SkHs89m5CsQQOOCsWm_l99B6CIIio,448
78
- clapp_pm-1.0.20.dist-info/RECORD,,
76
+ clapp_pm-1.0.21.dist-info/METADATA,sha256=x7XdkEWtZ2OidLL19YVZOzCEY1RPf2ilwr6VuZehWgM,3980
77
+ clapp_pm-1.0.21.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
78
+ clapp_pm-1.0.21.dist-info/entry_points.txt,sha256=7j-3pQVpQfnaVzUV83g7zlCA30ePlnXkhHLAGGz9xrQ,36
79
+ clapp_pm-1.0.21.dist-info/top_level.txt,sha256=2FeS-lC1OV3lBqLAHahLU8vcWxlxSDLNJSk-4MmymKk,475
80
+ clapp_pm-1.0.21.dist-info/RECORD,,
@@ -15,10 +15,12 @@ list_command
15
15
  main
16
16
  manifest_schema
17
17
  manifest_validator
18
+ new_command
18
19
  package_registry
19
20
  package_runner
20
21
  package_signing
21
22
  post_install_hint
23
+ progress_utils
22
24
  publish_command
23
25
  remote_registry
24
26
  smart_search
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,274 @@
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
+
15
+ class ProgressBar:
16
+ """Progress bar sınıfı"""
17
+
18
+ def __init__(self, total: int, description: str = "İndiriliyor", width: int = 50):
19
+ self.total = total
20
+ self.description = description
21
+ self.width = width
22
+ self.current = 0
23
+ self.start_time = time.time()
24
+ self.last_update = 0
25
+ self.speed = 0
26
+ self.lock = threading.Lock()
27
+
28
+ def update(self, current: int, speed: Optional[float] = None):
29
+ """Progress bar'ı günceller"""
30
+ with self.lock:
31
+ self.current = current
32
+ if speed is not None:
33
+ self.speed = speed
34
+
35
+ # Hız hesaplama
36
+ if self.current > 0:
37
+ elapsed = time.time() - self.start_time
38
+ if elapsed > 0:
39
+ self.speed = self.current / elapsed
40
+
41
+ def display(self):
42
+ """Progress bar'ı ekranda gösterir"""
43
+ if self.total <= 0:
44
+ return
45
+
46
+ percentage = (self.current / self.total) * 100
47
+ filled_width = int(self.width * self.current // self.total)
48
+
49
+ # Progress bar oluştur
50
+ bar = '█' * filled_width + '░' * (self.width - filled_width)
51
+
52
+ # Hız formatı
53
+ speed_str = self._format_speed(self.speed)
54
+
55
+ # Yüzde ve boyut bilgisi
56
+ current_str = self._format_size(self.current)
57
+ total_str = self._format_size(self.total)
58
+
59
+ # Progress bar çıktısı
60
+ progress_line = f"\r{self.description}: [{bar}] {percentage:5.1f}% | {current_str}/{total_str} | {speed_str}"
61
+
62
+ # Satırı temizle ve yaz
63
+ sys.stdout.write('\r' + ' ' * (len(progress_line) + 10)) # Temizle
64
+ sys.stdout.write(progress_line)
65
+ sys.stdout.flush()
66
+
67
+ def finish(self, success: bool = True):
68
+ """Progress bar'ı tamamlar"""
69
+ if success:
70
+ # Tamamlandı mesajı
71
+ sys.stdout.write('\r' + ' ' * (self.width + 50)) # Temizle
72
+ sys.stdout.write(f"\r✅ {self.description} tamamlandı!\n")
73
+ else:
74
+ # Hata mesajı
75
+ sys.stdout.write('\r' + ' ' * (self.width + 50)) # Temizle
76
+ sys.stdout.write(f"\r❌ {self.description} başarısız!\n")
77
+ sys.stdout.flush()
78
+
79
+ def _format_speed(self, speed: float) -> str:
80
+ """Hızı formatlar (B/s, KB/s, MB/s)"""
81
+ if speed < 1024:
82
+ return f"{speed:.1f} B/s"
83
+ elif speed < 1024 * 1024:
84
+ return f"{speed/1024:.1f} KB/s"
85
+ else:
86
+ return f"{speed/(1024*1024):.1f} MB/s"
87
+
88
+ def _format_size(self, size: int) -> str:
89
+ """Boyutu formatlar (B, KB, MB, GB)"""
90
+ if size < 1024:
91
+ return f"{size} B"
92
+ elif size < 1024 * 1024:
93
+ return f"{size/1024:.1f} KB"
94
+ elif size < 1024 * 1024 * 1024:
95
+ return f"{size/(1024*1024):.1f} MB"
96
+ else:
97
+ return f"{size/(1024*1024*1024):.1f} GB"
98
+
99
+
100
+ def download_with_progress(url: str, filename: str, description: str = "İndiriliyor") -> bool:
101
+ """
102
+ Progress bar ile dosya indirir
103
+
104
+ Args:
105
+ url: İndirilecek URL
106
+ filename: Kaydedilecek dosya adı
107
+ description: Progress bar açıklaması
108
+
109
+ Returns:
110
+ Başarılı ise True
111
+ """
112
+ try:
113
+ # URL'den dosya boyutunu al
114
+ response = urlopen(url)
115
+ total_size = int(response.headers.get('content-length', 0))
116
+ response.close()
117
+
118
+ # Progress bar oluştur
119
+ progress = ProgressBar(total_size, description)
120
+
121
+ # İndirme işlemi
122
+ with urlopen(url) as response:
123
+ with open(filename, 'wb') as file:
124
+ downloaded = 0
125
+ chunk_size = 8192
126
+
127
+ while True:
128
+ chunk = response.read(chunk_size)
129
+ if not chunk:
130
+ break
131
+
132
+ file.write(chunk)
133
+ downloaded += len(chunk)
134
+
135
+ # Progress bar güncelle
136
+ progress.update(downloaded)
137
+ progress.display()
138
+
139
+ # Kısa bekleme (çok sık güncelleme önlemek için)
140
+ time.sleep(0.01)
141
+
142
+ # Tamamlandı
143
+ progress.finish(True)
144
+ return True
145
+
146
+ except Exception as e:
147
+ if 'progress' in locals():
148
+ progress.finish(False)
149
+ print(f"❌ İndirme hatası: {e}")
150
+ return False
151
+
152
+
153
+ def copy_with_progress(src: str, dst: str, description: str = "Kopyalanıyor") -> bool:
154
+ """
155
+ Progress bar ile dosya kopyalar
156
+
157
+ Args:
158
+ src: Kaynak dosya
159
+ dst: Hedef dosya
160
+ description: Progress bar açıklaması
161
+
162
+ Returns:
163
+ Başarılı ise True
164
+ """
165
+ import os
166
+ import shutil
167
+
168
+ try:
169
+ # Dosya boyutunu al
170
+ total_size = os.path.getsize(src)
171
+
172
+ # Progress bar oluştur
173
+ progress = ProgressBar(total_size, description)
174
+
175
+ # Kopyalama işlemi
176
+ with open(src, 'rb') as src_file:
177
+ with open(dst, 'wb') as dst_file:
178
+ copied = 0
179
+ chunk_size = 8192
180
+
181
+ while True:
182
+ chunk = src_file.read(chunk_size)
183
+ if not chunk:
184
+ break
185
+
186
+ dst_file.write(chunk)
187
+ copied += len(chunk)
188
+
189
+ # Progress bar güncelle
190
+ progress.update(copied)
191
+ progress.display()
192
+
193
+ # Kısa bekleme
194
+ time.sleep(0.001)
195
+
196
+ # Tamamlandı
197
+ progress.finish(True)
198
+ return True
199
+
200
+ except Exception as e:
201
+ if 'progress' in locals():
202
+ progress.finish(False)
203
+ print(f"❌ Kopyalama hatası: {e}")
204
+ return False
205
+
206
+
207
+ def extract_with_progress(zip_path: str, extract_path: str, description: str = "Çıkarılıyor") -> bool:
208
+ """
209
+ Progress bar ile ZIP dosyası çıkarır
210
+
211
+ Args:
212
+ zip_path: ZIP dosyası yolu
213
+ extract_path: Çıkarılacak dizin
214
+ description: Progress bar açıklaması
215
+
216
+ Returns:
217
+ Başarılı ise True
218
+ """
219
+ import zipfile
220
+ import os
221
+
222
+ try:
223
+ with zipfile.ZipFile(zip_path, 'r') as zip_ref:
224
+ # Toplam dosya sayısı
225
+ file_list = zip_ref.filelist
226
+ total_files = len(file_list)
227
+
228
+ if total_files == 0:
229
+ print(f"❌ ZIP dosyası boş: {zip_path}")
230
+ return False
231
+
232
+ # Progress bar oluştur
233
+ progress = ProgressBar(total_files, description)
234
+
235
+ # Çıkarma işlemi
236
+ for i, file_info in enumerate(file_list):
237
+ zip_ref.extract(file_info, extract_path)
238
+
239
+ # Progress bar güncelle
240
+ progress.update(i + 1)
241
+ progress.display()
242
+
243
+ # Kısa bekleme
244
+ time.sleep(0.01)
245
+
246
+ # Tamamlandı
247
+ progress.finish(True)
248
+ return True
249
+
250
+ except Exception as e:
251
+ if 'progress' in locals():
252
+ progress.finish(False)
253
+ print(f"❌ Çıkarma hatası: {e}")
254
+ return False
255
+
256
+
257
+ def show_success_message(message: str):
258
+ """Başarı mesajı gösterir"""
259
+ print(f"✅ {message}")
260
+
261
+
262
+ def show_error_message(message: str):
263
+ """Hata mesajı gösterir"""
264
+ print(f"❌ {message}")
265
+
266
+
267
+ def show_info_message(message: str):
268
+ """Bilgi mesajı gösterir"""
269
+ print(f"ℹ️ {message}")
270
+
271
+
272
+ def show_warning_message(message: str):
273
+ """Uyarı mesajı gösterir"""
274
+ print(f"⚠️ {message}")
version.py CHANGED
@@ -2,7 +2,7 @@
2
2
  Version information for clapp-pm package.
3
3
  """
4
4
 
5
- __version__ = "1.0.20"
5
+ __version__ = "1.0.21"
6
6
  __author__ = "Melih Burak Memiş"
7
7
  __email__ = "mburakmemiscy@gmail.com"
8
8
  __description__ = "Lightweight cross-language app manager for Python and Lua"