clapp-pm 1.0.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.
- check_env.py +133 -0
- clapp-packages-repo/README.md +46 -0
- clapp-packages-repo/index.json +35 -0
- clapp-packages-repo/packages/hello-python/main.py +49 -0
- clapp-packages-repo/packages/hello-python/manifest.json +8 -0
- clapp-packages-repo/packages/test-app/main.py +1 -0
- clapp-packages-repo/packages/test-app/manifest.json +1 -0
- clapp-packages-repo/packages/test-app2/main.py +1 -0
- clapp-packages-repo/packages/test-app2/manifest.json +1 -0
- clapp-packages-repo/packages.json +40 -0
- clapp_core.py +61 -0
- clapp_pm-1.0.0.data/data/version.json +9 -0
- clapp_pm-1.0.0.dist-info/METADATA +117 -0
- clapp_pm-1.0.0.dist-info/RECORD +40 -0
- clapp_pm-1.0.0.dist-info/WHEEL +5 -0
- clapp_pm-1.0.0.dist-info/entry_points.txt +2 -0
- clapp_pm-1.0.0.dist-info/licenses/LICENSE +21 -0
- clapp_pm-1.0.0.dist-info/top_level.txt +20 -0
- clean_command.py +214 -0
- cli_commands.py +404 -0
- dependency_resolver.py +272 -0
- doctor_command.py +279 -0
- info_command.py +194 -0
- installer.py +320 -0
- main.py +294 -0
- manifest_schema.py +84 -0
- manifest_validator.py +245 -0
- package_registry.py +127 -0
- package_runner.py +85 -0
- packages/hello-python/main.py +49 -0
- packages/hello-python/manifest.json +8 -0
- packages/test-app/main.py +1 -0
- packages/test-app/manifest.json +1 -0
- packages/test-app2/main.py +1 -0
- packages/test-app2/manifest.json +1 -0
- post_install_hint.py +144 -0
- remote_registry.py +285 -0
- validate_command.py +225 -0
- version_command.py +145 -0
- where_command.py +207 -0
remote_registry.py
ADDED
@@ -0,0 +1,285 @@
|
|
1
|
+
import json
|
2
|
+
import urllib.request
|
3
|
+
import urllib.parse
|
4
|
+
from typing import List, Dict, Optional
|
5
|
+
|
6
|
+
# Uzak paket deposu URL'si
|
7
|
+
REMOTE_PACKAGES_URL = "https://raw.githubusercontent.com/mburakmmm/clapp-packages/main/packages.json"
|
8
|
+
|
9
|
+
def fetch_remote_packages() -> List[Dict]:
|
10
|
+
"""
|
11
|
+
Uzak paket deposundan paket listesini indirir.
|
12
|
+
|
13
|
+
Returns:
|
14
|
+
list: Paket listesi (dict formatında)
|
15
|
+
"""
|
16
|
+
try:
|
17
|
+
print("Uzak paket deposu kontrol ediliyor...")
|
18
|
+
|
19
|
+
# HTTP isteği gönder
|
20
|
+
with urllib.request.urlopen(REMOTE_PACKAGES_URL) as response:
|
21
|
+
data = response.read().decode('utf-8')
|
22
|
+
|
23
|
+
# JSON'u parse et
|
24
|
+
packages = json.loads(data)
|
25
|
+
|
26
|
+
print(f"✅ {len(packages)} paket bulundu")
|
27
|
+
return packages
|
28
|
+
|
29
|
+
except urllib.error.URLError as e:
|
30
|
+
print(f"❌ Ağ hatası: {e}")
|
31
|
+
return []
|
32
|
+
except json.JSONDecodeError as e:
|
33
|
+
print(f"❌ JSON parse hatası: {e}")
|
34
|
+
return []
|
35
|
+
except Exception as e:
|
36
|
+
print(f"❌ Beklenmeyen hata: {e}")
|
37
|
+
return []
|
38
|
+
|
39
|
+
def get_package_info(app_name: str) -> Optional[Dict]:
|
40
|
+
"""
|
41
|
+
Belirtilen uygulama için uzak paket bilgilerini döndürür.
|
42
|
+
|
43
|
+
Args:
|
44
|
+
app_name (str): Uygulama adı
|
45
|
+
|
46
|
+
Returns:
|
47
|
+
dict or None: Paket bilgileri veya None
|
48
|
+
"""
|
49
|
+
packages = fetch_remote_packages()
|
50
|
+
|
51
|
+
for package in packages:
|
52
|
+
if package.get('name') == app_name:
|
53
|
+
return package
|
54
|
+
|
55
|
+
return None
|
56
|
+
|
57
|
+
def search_packages(query: str) -> List[Dict]:
|
58
|
+
"""
|
59
|
+
Paket deposunda arama yapar.
|
60
|
+
|
61
|
+
Args:
|
62
|
+
query (str): Arama terimi
|
63
|
+
|
64
|
+
Returns:
|
65
|
+
list: Eşleşen paketler
|
66
|
+
"""
|
67
|
+
packages = fetch_remote_packages()
|
68
|
+
results = []
|
69
|
+
|
70
|
+
query_lower = query.lower()
|
71
|
+
|
72
|
+
for package in packages:
|
73
|
+
# İsim, açıklama ve dilde arama yap
|
74
|
+
name = package.get('name', '').lower()
|
75
|
+
description = package.get('description', '').lower()
|
76
|
+
language = package.get('language', '').lower()
|
77
|
+
|
78
|
+
if (query_lower in name or
|
79
|
+
query_lower in description or
|
80
|
+
query_lower in language):
|
81
|
+
results.append(package)
|
82
|
+
|
83
|
+
return results
|
84
|
+
|
85
|
+
def get_packages_by_language(language: str) -> List[Dict]:
|
86
|
+
"""
|
87
|
+
Belirtilen dildeki paketleri döndürür.
|
88
|
+
|
89
|
+
Args:
|
90
|
+
language (str): Programlama dili
|
91
|
+
|
92
|
+
Returns:
|
93
|
+
list: Belirtilen dildeki paketler
|
94
|
+
"""
|
95
|
+
packages = fetch_remote_packages()
|
96
|
+
filtered_packages = []
|
97
|
+
|
98
|
+
for package in packages:
|
99
|
+
if package.get('language', '').lower() == language.lower():
|
100
|
+
filtered_packages.append(package)
|
101
|
+
|
102
|
+
return filtered_packages
|
103
|
+
|
104
|
+
def list_remote_packages(show_details=False) -> str:
|
105
|
+
"""
|
106
|
+
Uzak paket deposundaki paketleri listeler.
|
107
|
+
|
108
|
+
Args:
|
109
|
+
show_details (bool): Detayları göster
|
110
|
+
|
111
|
+
Returns:
|
112
|
+
str: Formatlanmış paket listesi
|
113
|
+
"""
|
114
|
+
packages = fetch_remote_packages()
|
115
|
+
|
116
|
+
if not packages:
|
117
|
+
return "❌ Uzak paket deposuna erişilemedi veya paket bulunamadı"
|
118
|
+
|
119
|
+
output = f"🌐 Uzak Paket Deposu ({len(packages)} paket)\n"
|
120
|
+
output += "=" * 50 + "\n"
|
121
|
+
|
122
|
+
# Dillere göre grupla
|
123
|
+
by_language = {}
|
124
|
+
for package in packages:
|
125
|
+
language = package.get('language', 'unknown')
|
126
|
+
if language not in by_language:
|
127
|
+
by_language[language] = []
|
128
|
+
by_language[language].append(package)
|
129
|
+
|
130
|
+
for language, lang_packages in sorted(by_language.items()):
|
131
|
+
output += f"\n📚 {language.upper()} ({len(lang_packages)} paket):\n"
|
132
|
+
|
133
|
+
for package in sorted(lang_packages, key=lambda x: x.get('name', '')):
|
134
|
+
name = package.get('name', 'Bilinmiyor')
|
135
|
+
version = package.get('version', '0.0.0')
|
136
|
+
description = package.get('description', 'Açıklama yok')
|
137
|
+
|
138
|
+
output += f" 📦 {name} (v{version})\n"
|
139
|
+
|
140
|
+
if show_details:
|
141
|
+
output += f" Açıklama: {description}\n"
|
142
|
+
output += f" İndirme: {package.get('download_url', 'Yok')}\n"
|
143
|
+
|
144
|
+
if package.get('dependencies'):
|
145
|
+
deps = ', '.join(package['dependencies'])
|
146
|
+
output += f" Bağımlılıklar: {deps}\n"
|
147
|
+
|
148
|
+
return output
|
149
|
+
|
150
|
+
def validate_package_url(url: str) -> bool:
|
151
|
+
"""
|
152
|
+
Paket URL'sinin geçerli olup olmadığını kontrol eder.
|
153
|
+
|
154
|
+
Args:
|
155
|
+
url (str): Kontrol edilecek URL
|
156
|
+
|
157
|
+
Returns:
|
158
|
+
bool: Geçerliyse True
|
159
|
+
"""
|
160
|
+
try:
|
161
|
+
# URL formatını kontrol et
|
162
|
+
parsed = urllib.parse.urlparse(url)
|
163
|
+
if not parsed.scheme or not parsed.netloc:
|
164
|
+
return False
|
165
|
+
|
166
|
+
# HTTP HEAD isteği gönder
|
167
|
+
request = urllib.request.Request(url, method='HEAD')
|
168
|
+
with urllib.request.urlopen(request) as response:
|
169
|
+
return response.status == 200
|
170
|
+
|
171
|
+
except Exception:
|
172
|
+
return False
|
173
|
+
|
174
|
+
def get_package_statistics() -> Dict:
|
175
|
+
"""
|
176
|
+
Paket deposu istatistiklerini döndürür.
|
177
|
+
|
178
|
+
Returns:
|
179
|
+
dict: İstatistik bilgileri
|
180
|
+
"""
|
181
|
+
packages = fetch_remote_packages()
|
182
|
+
|
183
|
+
stats = {
|
184
|
+
"total_packages": len(packages),
|
185
|
+
"languages": {},
|
186
|
+
"with_dependencies": 0,
|
187
|
+
"without_dependencies": 0,
|
188
|
+
"total_dependencies": 0
|
189
|
+
}
|
190
|
+
|
191
|
+
for package in packages:
|
192
|
+
# Dil istatistikleri
|
193
|
+
language = package.get('language', 'unknown')
|
194
|
+
stats["languages"][language] = stats["languages"].get(language, 0) + 1
|
195
|
+
|
196
|
+
# Bağımlılık istatistikleri
|
197
|
+
dependencies = package.get('dependencies', [])
|
198
|
+
if dependencies:
|
199
|
+
stats["with_dependencies"] += 1
|
200
|
+
stats["total_dependencies"] += len(dependencies)
|
201
|
+
else:
|
202
|
+
stats["without_dependencies"] += 1
|
203
|
+
|
204
|
+
return stats
|
205
|
+
|
206
|
+
def get_statistics_report() -> str:
|
207
|
+
"""
|
208
|
+
İstatistik raporunu döndürür.
|
209
|
+
|
210
|
+
Returns:
|
211
|
+
str: Formatlanmış istatistik raporu
|
212
|
+
"""
|
213
|
+
stats = get_package_statistics()
|
214
|
+
|
215
|
+
if stats["total_packages"] == 0:
|
216
|
+
return "❌ Paket deposu verisi alınamadı"
|
217
|
+
|
218
|
+
report = "📊 Paket Deposu İstatistikleri\n"
|
219
|
+
report += "=" * 40 + "\n"
|
220
|
+
|
221
|
+
report += f"📦 Toplam Paket: {stats['total_packages']}\n"
|
222
|
+
report += f"🔗 Bağımlılığa Sahip: {stats['with_dependencies']}\n"
|
223
|
+
report += f"🆓 Bağımlılıksız: {stats['without_dependencies']}\n"
|
224
|
+
report += f"📊 Toplam Bağımlılık: {stats['total_dependencies']}\n\n"
|
225
|
+
|
226
|
+
# Dil dağılımı
|
227
|
+
report += "💻 Dil Dağılımı:\n"
|
228
|
+
for language, count in sorted(stats["languages"].items()):
|
229
|
+
percentage = (count / stats["total_packages"]) * 100
|
230
|
+
report += f" {language}: {count} paket (%{percentage:.1f})\n"
|
231
|
+
|
232
|
+
return report
|
233
|
+
|
234
|
+
def check_remote_connectivity() -> bool:
|
235
|
+
"""
|
236
|
+
Uzak paket deposuna bağlantıyı kontrol eder.
|
237
|
+
|
238
|
+
Returns:
|
239
|
+
bool: Bağlantı varsa True
|
240
|
+
"""
|
241
|
+
try:
|
242
|
+
request = urllib.request.Request(REMOTE_PACKAGES_URL, method='HEAD')
|
243
|
+
with urllib.request.urlopen(request, timeout=5) as response:
|
244
|
+
return response.status == 200
|
245
|
+
except Exception:
|
246
|
+
return False
|
247
|
+
|
248
|
+
def get_package_versions(app_name: str) -> List[str]:
|
249
|
+
"""
|
250
|
+
Paketin mevcut sürümlerini döndürür (şu an sadece mevcut sürüm).
|
251
|
+
|
252
|
+
Args:
|
253
|
+
app_name (str): Uygulama adı
|
254
|
+
|
255
|
+
Returns:
|
256
|
+
list: Sürüm listesi
|
257
|
+
"""
|
258
|
+
package = get_package_info(app_name)
|
259
|
+
|
260
|
+
if package:
|
261
|
+
return [package.get('version', '0.0.0')]
|
262
|
+
|
263
|
+
return []
|
264
|
+
|
265
|
+
if __name__ == "__main__":
|
266
|
+
# Test için örnek kullanım
|
267
|
+
print("Remote Registry Test")
|
268
|
+
print("=" * 30)
|
269
|
+
|
270
|
+
# Bağlantı testi
|
271
|
+
if check_remote_connectivity():
|
272
|
+
print("✅ Uzak paket deposuna bağlantı başarılı")
|
273
|
+
|
274
|
+
# Paket listesi
|
275
|
+
print("\nPaket listesi:")
|
276
|
+
print(list_remote_packages())
|
277
|
+
|
278
|
+
# İstatistikler
|
279
|
+
print("\nİstatistikler:")
|
280
|
+
print(get_statistics_report())
|
281
|
+
|
282
|
+
else:
|
283
|
+
print("❌ Uzak paket deposuna bağlantı kurulamadı")
|
284
|
+
|
285
|
+
print("\nTest tamamlandı.")
|
validate_command.py
ADDED
@@ -0,0 +1,225 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
validate_command.py - Uygulama doğrulama modülü
|
4
|
+
|
5
|
+
Bu modül `clapp validate <folder>` komutunu destekler ve
|
6
|
+
uygulama klasörlerinin doğru yapıda olup olmadığını kontrol eder.
|
7
|
+
"""
|
8
|
+
|
9
|
+
import os
|
10
|
+
import json
|
11
|
+
from pathlib import Path
|
12
|
+
from manifest_validator import validate_manifest_verbose
|
13
|
+
|
14
|
+
def validate_app_folder(folder_path):
|
15
|
+
"""Uygulama klasörünü doğrular"""
|
16
|
+
folder = Path(folder_path)
|
17
|
+
|
18
|
+
print(f"🔍 '{folder_path}' klasörü doğrulanıyor...")
|
19
|
+
print("=" * 50)
|
20
|
+
|
21
|
+
# Klasörün var olup olmadığını kontrol et
|
22
|
+
if not folder.exists():
|
23
|
+
print(f"❌ Klasör bulunamadı: {folder_path}")
|
24
|
+
return False
|
25
|
+
|
26
|
+
if not folder.is_dir():
|
27
|
+
print(f"❌ Belirtilen yol bir klasör değil: {folder_path}")
|
28
|
+
return False
|
29
|
+
|
30
|
+
errors = []
|
31
|
+
warnings = []
|
32
|
+
|
33
|
+
# 1. manifest.json kontrolü
|
34
|
+
manifest_path = folder / "manifest.json"
|
35
|
+
if not manifest_path.exists():
|
36
|
+
errors.append("manifest.json dosyası bulunamadı")
|
37
|
+
else:
|
38
|
+
print("✅ manifest.json dosyası mevcut")
|
39
|
+
|
40
|
+
# Manifest içeriğini kontrol et
|
41
|
+
try:
|
42
|
+
with open(manifest_path, 'r', encoding='utf-8') as f:
|
43
|
+
manifest_data = json.load(f)
|
44
|
+
|
45
|
+
# Manifest'i doğrula
|
46
|
+
is_valid, validation_errors = validate_manifest_verbose(manifest_data)
|
47
|
+
|
48
|
+
if is_valid:
|
49
|
+
print("✅ manifest.json geçerli")
|
50
|
+
else:
|
51
|
+
print("❌ manifest.json geçersiz:")
|
52
|
+
for error in validation_errors:
|
53
|
+
print(f" • {error}")
|
54
|
+
errors.append(f"Manifest hatası: {error}")
|
55
|
+
|
56
|
+
# Giriş dosyası kontrolü
|
57
|
+
if "entry" in manifest_data:
|
58
|
+
entry_file = folder / manifest_data["entry"]
|
59
|
+
if entry_file.exists():
|
60
|
+
print(f"✅ Giriş dosyası mevcut: {manifest_data['entry']}")
|
61
|
+
else:
|
62
|
+
error_msg = f"Giriş dosyası bulunamadı: {manifest_data['entry']}"
|
63
|
+
print(f"❌ {error_msg}")
|
64
|
+
errors.append(error_msg)
|
65
|
+
|
66
|
+
# Dil kontrolü
|
67
|
+
if "language" in manifest_data:
|
68
|
+
language = manifest_data["language"].lower()
|
69
|
+
if language in ["python", "lua"]:
|
70
|
+
print(f"✅ Desteklenen dil: {language}")
|
71
|
+
else:
|
72
|
+
warning_msg = f"Desteklenmeyen dil: {language}"
|
73
|
+
print(f"⚠️ {warning_msg}")
|
74
|
+
warnings.append(warning_msg)
|
75
|
+
|
76
|
+
except json.JSONDecodeError as e:
|
77
|
+
error_msg = f"manifest.json JSON formatı geçersiz: {str(e)}"
|
78
|
+
print(f"❌ {error_msg}")
|
79
|
+
errors.append(error_msg)
|
80
|
+
except Exception as e:
|
81
|
+
error_msg = f"manifest.json okunamadı: {str(e)}"
|
82
|
+
print(f"❌ {error_msg}")
|
83
|
+
errors.append(error_msg)
|
84
|
+
|
85
|
+
# 2. Klasör içeriği kontrolü
|
86
|
+
files = list(folder.iterdir())
|
87
|
+
if not files:
|
88
|
+
warnings.append("Klasör boş")
|
89
|
+
print("⚠️ Klasör boş")
|
90
|
+
else:
|
91
|
+
print(f"✅ Klasör içeriği: {len(files)} öğe")
|
92
|
+
|
93
|
+
# 3. Önerilen dosya yapısı kontrolü
|
94
|
+
recommended_files = ["manifest.json", "README.md", "requirements.txt"]
|
95
|
+
missing_recommended = []
|
96
|
+
|
97
|
+
for rec_file in recommended_files:
|
98
|
+
if not (folder / rec_file).exists():
|
99
|
+
missing_recommended.append(rec_file)
|
100
|
+
|
101
|
+
if missing_recommended:
|
102
|
+
print("💡 Önerilen dosyalar eksik:")
|
103
|
+
for missing in missing_recommended:
|
104
|
+
print(f" • {missing}")
|
105
|
+
|
106
|
+
# 4. Dosya boyutu kontrolü
|
107
|
+
try:
|
108
|
+
total_size = 0
|
109
|
+
file_count = 0
|
110
|
+
|
111
|
+
for file_path in folder.rglob("*"):
|
112
|
+
if file_path.is_file():
|
113
|
+
file_count += 1
|
114
|
+
total_size += file_path.stat().st_size
|
115
|
+
|
116
|
+
print(f"📊 İstatistikler: {file_count} dosya, {format_size(total_size)}")
|
117
|
+
|
118
|
+
# Büyük dosyalar için uyarı
|
119
|
+
if total_size > 100 * 1024 * 1024: # 100MB
|
120
|
+
warnings.append(f"Büyük uygulama boyutu: {format_size(total_size)}")
|
121
|
+
|
122
|
+
except Exception as e:
|
123
|
+
warnings.append(f"Dosya boyutu hesaplanamadı: {str(e)}")
|
124
|
+
|
125
|
+
# Sonuçları göster
|
126
|
+
print("\n" + "=" * 50)
|
127
|
+
print("📋 Doğrulama Sonuçları:")
|
128
|
+
|
129
|
+
if not errors and not warnings:
|
130
|
+
print("🎉 Mükemmel! Uygulama klasörü tamamen geçerli.")
|
131
|
+
print("✅ Kurulum için hazır.")
|
132
|
+
elif not errors:
|
133
|
+
print("✅ Uygulama klasörü geçerli.")
|
134
|
+
if warnings:
|
135
|
+
print("⚠️ Bazı uyarılar var:")
|
136
|
+
for warning in warnings:
|
137
|
+
print(f" • {warning}")
|
138
|
+
else:
|
139
|
+
print("❌ Uygulama klasörü geçersiz.")
|
140
|
+
print("🔧 Düzeltilmesi gereken hatalar:")
|
141
|
+
for error in errors:
|
142
|
+
print(f" • {error}")
|
143
|
+
|
144
|
+
if warnings:
|
145
|
+
print("⚠️ Ek uyarılar:")
|
146
|
+
for warning in warnings:
|
147
|
+
print(f" • {warning}")
|
148
|
+
|
149
|
+
# Öneriler
|
150
|
+
if errors or warnings:
|
151
|
+
print("\n💡 Öneriler:")
|
152
|
+
if not manifest_path.exists():
|
153
|
+
print("• manifest.json dosyası oluşturun")
|
154
|
+
print("• Örnek: clapp init komutu ile başlayabilirsiniz")
|
155
|
+
|
156
|
+
if missing_recommended:
|
157
|
+
print("• Önerilen dosyaları ekleyin:")
|
158
|
+
for missing in missing_recommended:
|
159
|
+
if missing == "README.md":
|
160
|
+
print(f" - {missing}: Uygulama açıklaması")
|
161
|
+
elif missing == "requirements.txt":
|
162
|
+
print(f" - {missing}: Python bağımlılıkları (Python uygulamaları için)")
|
163
|
+
|
164
|
+
if warnings:
|
165
|
+
print("• Uyarıları gözden geçirin ve gerekirse düzeltin")
|
166
|
+
|
167
|
+
print(f"\n🔧 Daha fazla yardım için: clapp doctor")
|
168
|
+
|
169
|
+
return len(errors) == 0
|
170
|
+
|
171
|
+
def format_size(size_bytes):
|
172
|
+
"""Dosya boyutunu formatlar"""
|
173
|
+
if size_bytes == 0:
|
174
|
+
return "0 B"
|
175
|
+
|
176
|
+
for unit in ['B', 'KB', 'MB', 'GB']:
|
177
|
+
if size_bytes < 1024.0:
|
178
|
+
return f"{size_bytes:.1f} {unit}"
|
179
|
+
size_bytes /= 1024.0
|
180
|
+
|
181
|
+
return f"{size_bytes:.1f} TB"
|
182
|
+
|
183
|
+
def validate_multiple_folders(folder_paths):
|
184
|
+
"""Birden fazla klasörü doğrular"""
|
185
|
+
results = []
|
186
|
+
|
187
|
+
for folder_path in folder_paths:
|
188
|
+
print(f"\n{'='*60}")
|
189
|
+
result = validate_app_folder(folder_path)
|
190
|
+
results.append((folder_path, result))
|
191
|
+
|
192
|
+
# Özet
|
193
|
+
print(f"\n{'='*60}")
|
194
|
+
print("📊 Toplu Doğrulama Özeti:")
|
195
|
+
|
196
|
+
valid_count = sum(1 for _, result in results if result)
|
197
|
+
invalid_count = len(results) - valid_count
|
198
|
+
|
199
|
+
print(f"✅ Geçerli: {valid_count}")
|
200
|
+
print(f"❌ Geçersiz: {invalid_count}")
|
201
|
+
|
202
|
+
if invalid_count > 0:
|
203
|
+
print("\n❌ Geçersiz klasörler:")
|
204
|
+
for folder_path, result in results:
|
205
|
+
if not result:
|
206
|
+
print(f" • {folder_path}")
|
207
|
+
|
208
|
+
return invalid_count == 0
|
209
|
+
|
210
|
+
if __name__ == "__main__":
|
211
|
+
import sys
|
212
|
+
|
213
|
+
if len(sys.argv) < 2:
|
214
|
+
print("Kullanım: python validate_command.py <klasör_yolu>")
|
215
|
+
print("Örnek: python validate_command.py apps/my-app")
|
216
|
+
sys.exit(1)
|
217
|
+
|
218
|
+
folder_paths = sys.argv[1:]
|
219
|
+
|
220
|
+
if len(folder_paths) == 1:
|
221
|
+
success = validate_app_folder(folder_paths[0])
|
222
|
+
sys.exit(0 if success else 1)
|
223
|
+
else:
|
224
|
+
success = validate_multiple_folders(folder_paths)
|
225
|
+
sys.exit(0 if success else 1)
|
version_command.py
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
version_command.py - Sürüm bilgisi modülü
|
4
|
+
|
5
|
+
Bu modül `clapp version` komutunu destekler ve
|
6
|
+
clapp'in sürüm bilgilerini gösterir.
|
7
|
+
"""
|
8
|
+
|
9
|
+
import sys
|
10
|
+
import platform
|
11
|
+
import json
|
12
|
+
from pathlib import Path
|
13
|
+
|
14
|
+
def get_version_info():
|
15
|
+
"""Sürüm bilgilerini toplar"""
|
16
|
+
# version.json dosyasından sürüm bilgisini oku
|
17
|
+
version_file = Path("version.json")
|
18
|
+
|
19
|
+
if version_file.exists():
|
20
|
+
try:
|
21
|
+
with open(version_file, 'r', encoding='utf-8') as f:
|
22
|
+
version_data = json.load(f)
|
23
|
+
|
24
|
+
app_name = version_data.get("name", "clapp")
|
25
|
+
version = version_data.get("version", "1.0.0")
|
26
|
+
author = version_data.get("author", "Bilinmiyor")
|
27
|
+
|
28
|
+
except Exception:
|
29
|
+
app_name = "clapp"
|
30
|
+
version = "1.0.0"
|
31
|
+
author = "Bilinmiyor"
|
32
|
+
else:
|
33
|
+
app_name = "clapp"
|
34
|
+
version = "1.0.0"
|
35
|
+
author = "Bilinmiyor"
|
36
|
+
|
37
|
+
# Sistem bilgileri
|
38
|
+
python_version = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
|
39
|
+
system_info = platform.system()
|
40
|
+
machine = platform.machine()
|
41
|
+
|
42
|
+
return {
|
43
|
+
"app_name": app_name,
|
44
|
+
"version": version,
|
45
|
+
"author": author,
|
46
|
+
"python_version": python_version,
|
47
|
+
"system": system_info,
|
48
|
+
"machine": machine,
|
49
|
+
"platform": f"{system_info} {platform.release()}"
|
50
|
+
}
|
51
|
+
|
52
|
+
def print_version(format_type="default"):
|
53
|
+
"""Sürüm bilgisini yazdırır"""
|
54
|
+
info = get_version_info()
|
55
|
+
|
56
|
+
if format_type == "short":
|
57
|
+
print(info["version"])
|
58
|
+
elif format_type == "json":
|
59
|
+
import json
|
60
|
+
output = {
|
61
|
+
"version": info["version"],
|
62
|
+
"python": info["python_version"],
|
63
|
+
"os": info["system"],
|
64
|
+
"machine": info["machine"]
|
65
|
+
}
|
66
|
+
print(json.dumps(output, indent=2))
|
67
|
+
else: # default
|
68
|
+
print(f"🚀 {info['app_name']} v{info['version']}")
|
69
|
+
print(f"🐍 Python {info['python_version']}")
|
70
|
+
print(f"💻 Platform: {info['platform']} ({info['machine']})")
|
71
|
+
print(f"👨💻 Yazar: {info['author']}")
|
72
|
+
|
73
|
+
def print_detailed_version():
|
74
|
+
"""Detaylı sürüm bilgisini yazdırır"""
|
75
|
+
info = get_version_info()
|
76
|
+
|
77
|
+
print("📋 clapp Detaylı Sürüm Bilgileri")
|
78
|
+
print("=" * 50)
|
79
|
+
|
80
|
+
# Temel bilgiler
|
81
|
+
print("🚀 Uygulama Bilgileri:")
|
82
|
+
print(f" Ad: {info['app_name']}")
|
83
|
+
print(f" Sürüm: {info['version']}")
|
84
|
+
print(f" Yazar: {info['author']}")
|
85
|
+
print()
|
86
|
+
|
87
|
+
# Python bilgileri
|
88
|
+
print("🐍 Python Bilgileri:")
|
89
|
+
print(f" Sürüm: {info['python_version']}")
|
90
|
+
print(f" Çalıştırılabilir: {sys.executable}")
|
91
|
+
print(f" Prefix: {sys.prefix}")
|
92
|
+
print()
|
93
|
+
|
94
|
+
# Platform bilgileri
|
95
|
+
print("💻 Platform Bilgileri:")
|
96
|
+
print(f" İşletim Sistemi: {info['system']}")
|
97
|
+
print(f" Sürüm: {platform.release()}")
|
98
|
+
print(f" Mimari: {info['machine']}")
|
99
|
+
print(f" İşlemci: {platform.processor()}")
|
100
|
+
print()
|
101
|
+
|
102
|
+
# Modül bilgileri
|
103
|
+
print("📦 Modül Bilgileri:")
|
104
|
+
try:
|
105
|
+
import flet
|
106
|
+
print(f" Flet: v{flet.__version__}")
|
107
|
+
except ImportError:
|
108
|
+
print(" Flet: Yüklü değil")
|
109
|
+
|
110
|
+
# Ek bilgiler
|
111
|
+
print()
|
112
|
+
print("📁 Dizin Bilgileri:")
|
113
|
+
print(f" Çalışma Dizini: {Path.cwd()}")
|
114
|
+
|
115
|
+
# apps/ dizini kontrolü
|
116
|
+
apps_dir = Path("apps")
|
117
|
+
if apps_dir.exists():
|
118
|
+
app_count = len([d for d in apps_dir.iterdir() if d.is_dir()])
|
119
|
+
print(f" Apps Dizini: {apps_dir.resolve()} ({app_count} uygulama)")
|
120
|
+
else:
|
121
|
+
print(" Apps Dizini: Bulunamadı")
|
122
|
+
|
123
|
+
def check_latest_version():
|
124
|
+
"""En son sürümü kontrol eder (placeholder)"""
|
125
|
+
print("🔍 En son sürüm kontrol ediliyor...")
|
126
|
+
print("⚠️ Bu özellik henüz mevcut değil.")
|
127
|
+
print("📞 Manuel kontrol için: https://github.com/user/clapp")
|
128
|
+
|
129
|
+
if __name__ == "__main__":
|
130
|
+
import sys
|
131
|
+
|
132
|
+
if len(sys.argv) > 1:
|
133
|
+
arg = sys.argv[1]
|
134
|
+
if arg == "--short":
|
135
|
+
print_version("short")
|
136
|
+
elif arg == "--json":
|
137
|
+
print_version("json")
|
138
|
+
elif arg == "--detailed":
|
139
|
+
print_detailed_version()
|
140
|
+
elif arg == "--latest":
|
141
|
+
check_latest_version()
|
142
|
+
else:
|
143
|
+
print_version("default")
|
144
|
+
else:
|
145
|
+
print_version("default")
|