clapp-pm 1.0.9__py3-none-any.whl → 1.0.11__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.
- backup_current/build_index.py +132 -0
- backup_current/check_env.py +133 -0
- backup_current/clapp_core.py +61 -0
- backup_current/clean_command.py +214 -0
- backup_current/cli_commands.py +404 -0
- backup_current/dependency_resolver.py +272 -0
- backup_current/doctor_command.py +239 -0
- backup_current/info_command.py +194 -0
- backup_current/install_command.py +236 -0
- backup_current/installer.py +323 -0
- backup_current/list_command.py +262 -0
- backup_current/main.py +294 -0
- backup_current/manifest_schema.py +84 -0
- backup_current/manifest_validator.py +245 -0
- backup_current/package_registry.py +127 -0
- backup_current/package_runner.py +85 -0
- backup_current/post_install_hint.py +144 -0
- backup_current/publish_command.py +253 -0
- backup_current/remote_registry.py +285 -0
- backup_current/setup.py +160 -0
- backup_current/system_test.py +477 -0
- backup_current/uninstall_command.py +215 -0
- backup_current/validate_command.py +225 -0
- backup_current/version.py +8 -0
- backup_current/version_command.py +145 -0
- backup_current/where_command.py +207 -0
- check_env.py +1 -8
- clapp-packages-repo/packages/hello-python/main.py +0 -49
- clapp-packages-repo/packages/hello-python/manifest.json +0 -8
- {clapp_pm-1.0.9.data → clapp_pm-1.0.11.data}/data/version.json +1 -1
- {clapp_pm-1.0.9.dist-info → clapp_pm-1.0.11.dist-info}/METADATA +1 -1
- clapp_pm-1.0.11.dist-info/RECORD +71 -0
- {clapp_pm-1.0.9.dist-info → clapp_pm-1.0.11.dist-info}/top_level.txt +2 -0
- doctor_command.py +0 -1
- install_command.py +3 -0
- version.py +8 -0
- clapp_pm-1.0.9.dist-info/RECORD +0 -44
- {clapp_pm-1.0.9.dist-info → clapp_pm-1.0.11.dist-info}/WHEEL +0 -0
- {clapp_pm-1.0.9.dist-info → clapp_pm-1.0.11.dist-info}/entry_points.txt +0 -0
- {clapp_pm-1.0.9.dist-info → clapp_pm-1.0.11.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,477 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Sistem Entegrasyon Testi
|
4
|
+
========================
|
5
|
+
|
6
|
+
Bu script clapp sisteminin tüm bileşenlerinin doğru çalışıp çalışmadığını test eder.
|
7
|
+
"""
|
8
|
+
|
9
|
+
import os
|
10
|
+
import sys
|
11
|
+
import json
|
12
|
+
import subprocess
|
13
|
+
import tempfile
|
14
|
+
import shutil
|
15
|
+
from pathlib import Path
|
16
|
+
from typing import Dict, List, Tuple, Any
|
17
|
+
|
18
|
+
class SystemTester:
|
19
|
+
def __init__(self):
|
20
|
+
self.test_results = []
|
21
|
+
self.errors = []
|
22
|
+
self.warnings = []
|
23
|
+
|
24
|
+
def log_test(self, test_name: str, success: bool, message: str = "", details: Any = None):
|
25
|
+
"""Test sonucunu kaydet"""
|
26
|
+
result = {
|
27
|
+
"test": test_name,
|
28
|
+
"success": success,
|
29
|
+
"message": message,
|
30
|
+
"details": details
|
31
|
+
}
|
32
|
+
self.test_results.append(result)
|
33
|
+
|
34
|
+
if success:
|
35
|
+
print(f"✅ {test_name}: {message}")
|
36
|
+
else:
|
37
|
+
print(f"❌ {test_name}: {message}")
|
38
|
+
self.errors.append(result)
|
39
|
+
|
40
|
+
def log_warning(self, warning: str):
|
41
|
+
"""Uyarı kaydet"""
|
42
|
+
self.warnings.append(warning)
|
43
|
+
print(f"⚠️ {warning}")
|
44
|
+
|
45
|
+
def test_imports(self) -> bool:
|
46
|
+
"""Tüm modüllerin import edilebilirliğini test et"""
|
47
|
+
print("\n🔍 Modül Import Testleri")
|
48
|
+
print("=" * 50)
|
49
|
+
|
50
|
+
modules = [
|
51
|
+
"main", "clapp_core", "package_registry", "package_runner",
|
52
|
+
"manifest_schema", "manifest_validator", "install_command",
|
53
|
+
"list_command", "version_command", "info_command", "doctor_command",
|
54
|
+
"clean_command", "where_command", "validate_command", "uninstall_command",
|
55
|
+
"publish_command", "remote_registry", "dependency_resolver",
|
56
|
+
"installer", "cli_commands", "check_env", "post_install_hint"
|
57
|
+
]
|
58
|
+
|
59
|
+
all_success = True
|
60
|
+
for module in modules:
|
61
|
+
try:
|
62
|
+
__import__(module)
|
63
|
+
self.log_test(f"Import {module}", True, "Başarılı")
|
64
|
+
except ImportError as e:
|
65
|
+
self.log_test(f"Import {module}", False, f"Import hatası: {e}")
|
66
|
+
all_success = False
|
67
|
+
except Exception as e:
|
68
|
+
self.log_test(f"Import {module}", False, f"Beklenmeyen hata: {e}")
|
69
|
+
all_success = False
|
70
|
+
|
71
|
+
return all_success
|
72
|
+
|
73
|
+
def test_version_system(self) -> bool:
|
74
|
+
"""Sürüm sistemi testleri"""
|
75
|
+
print("\n🔍 Sürüm Sistemi Testleri")
|
76
|
+
print("=" * 50)
|
77
|
+
|
78
|
+
try:
|
79
|
+
from version import __version__, __author__, __email__
|
80
|
+
|
81
|
+
# Sürüm formatı kontrolü
|
82
|
+
if not __version__ or __version__ == "0.0.0":
|
83
|
+
self.log_test("Version Format", False, "Geçersiz sürüm numarası")
|
84
|
+
return False
|
85
|
+
|
86
|
+
self.log_test("Version Import", True, f"Sürüm: {__version__}")
|
87
|
+
self.log_test("Author Import", True, f"Yazar: {__author__}")
|
88
|
+
self.log_test("Email Import", True, f"Email: {__email__}")
|
89
|
+
|
90
|
+
# version_command.py testi
|
91
|
+
try:
|
92
|
+
from version_command import get_version_info
|
93
|
+
info = get_version_info()
|
94
|
+
|
95
|
+
if info["version"] == __version__:
|
96
|
+
self.log_test("Version Command Integration", True, "Sürüm bilgisi eşleşiyor")
|
97
|
+
else:
|
98
|
+
self.log_test("Version Command Integration", False,
|
99
|
+
f"Sürüm uyumsuzluğu: {info['version']} != {__version__}")
|
100
|
+
return False
|
101
|
+
|
102
|
+
except Exception as e:
|
103
|
+
self.log_test("Version Command Integration", False, f"Hata: {e}")
|
104
|
+
return False
|
105
|
+
|
106
|
+
return True
|
107
|
+
|
108
|
+
except Exception as e:
|
109
|
+
self.log_test("Version System", False, f"Sürüm sistemi hatası: {e}")
|
110
|
+
return False
|
111
|
+
|
112
|
+
def test_directory_structure(self) -> bool:
|
113
|
+
"""Dizin yapısı testleri"""
|
114
|
+
print("\n🔍 Dizin Yapısı Testleri")
|
115
|
+
print("=" * 50)
|
116
|
+
|
117
|
+
# package_registry.py'deki get_apps_directory() testi
|
118
|
+
try:
|
119
|
+
from package_registry import get_apps_directory
|
120
|
+
apps_dir = get_apps_directory()
|
121
|
+
|
122
|
+
# Dizin oluşturulabilir mi?
|
123
|
+
Path(apps_dir).mkdir(parents=True, exist_ok=True)
|
124
|
+
self.log_test("Apps Directory Creation", True, f"Dizin: {apps_dir}")
|
125
|
+
|
126
|
+
# Dizin yazılabilir mi?
|
127
|
+
test_file = Path(apps_dir) / "test.txt"
|
128
|
+
test_file.write_text("test")
|
129
|
+
test_file.unlink()
|
130
|
+
self.log_test("Apps Directory Write", True, "Yazma testi başarılı")
|
131
|
+
|
132
|
+
return True
|
133
|
+
|
134
|
+
except Exception as e:
|
135
|
+
self.log_test("Directory Structure", False, f"Dizin yapısı hatası: {e}")
|
136
|
+
return False
|
137
|
+
|
138
|
+
def test_manifest_system(self) -> bool:
|
139
|
+
"""Manifest sistemi testleri"""
|
140
|
+
print("\n🔍 Manifest Sistemi Testleri")
|
141
|
+
print("=" * 50)
|
142
|
+
|
143
|
+
# Geçerli manifest örneği
|
144
|
+
valid_manifest = {
|
145
|
+
"name": "test-app",
|
146
|
+
"version": "1.0.0",
|
147
|
+
"language": "python",
|
148
|
+
"entry": "main.py",
|
149
|
+
"description": "Test uygulaması"
|
150
|
+
}
|
151
|
+
|
152
|
+
# Geçersiz manifest örneği
|
153
|
+
invalid_manifest = {
|
154
|
+
"name": "test-app",
|
155
|
+
# version eksik
|
156
|
+
"language": "python"
|
157
|
+
# entry eksik
|
158
|
+
}
|
159
|
+
|
160
|
+
try:
|
161
|
+
from manifest_schema import validate_manifest
|
162
|
+
from manifest_validator import validate_manifest_verbose
|
163
|
+
|
164
|
+
# Geçerli manifest testi
|
165
|
+
is_valid = validate_manifest(valid_manifest)
|
166
|
+
if is_valid:
|
167
|
+
self.log_test("Valid Manifest Schema", True, "Geçerli manifest doğrulandı")
|
168
|
+
else:
|
169
|
+
self.log_test("Valid Manifest Schema", False, "Geçerli manifest reddedildi")
|
170
|
+
return False
|
171
|
+
|
172
|
+
# Geçersiz manifest testi
|
173
|
+
is_valid = validate_manifest(invalid_manifest)
|
174
|
+
if not is_valid:
|
175
|
+
self.log_test("Invalid Manifest Schema", True, "Geçersiz manifest reddedildi")
|
176
|
+
else:
|
177
|
+
self.log_test("Invalid Manifest Schema", False, "Geçersiz manifest kabul edildi")
|
178
|
+
return False
|
179
|
+
|
180
|
+
# Detaylı doğrulama testi
|
181
|
+
is_valid, errors = validate_manifest_verbose(valid_manifest)
|
182
|
+
if is_valid and not errors:
|
183
|
+
self.log_test("Detailed Validation", True, "Detaylı doğrulama başarılı")
|
184
|
+
else:
|
185
|
+
self.log_test("Detailed Validation", False, f"Doğrulama hataları: {errors}")
|
186
|
+
return False
|
187
|
+
|
188
|
+
return True
|
189
|
+
|
190
|
+
except Exception as e:
|
191
|
+
self.log_test("Manifest System", False, f"Manifest sistemi hatası: {e}")
|
192
|
+
return False
|
193
|
+
|
194
|
+
def test_package_registry(self) -> bool:
|
195
|
+
"""Paket kayıt sistemi testleri"""
|
196
|
+
print("\n🔍 Paket Kayıt Sistemi Testleri")
|
197
|
+
print("=" * 50)
|
198
|
+
|
199
|
+
try:
|
200
|
+
from package_registry import list_packages, get_manifest, app_exists, get_apps_directory
|
201
|
+
|
202
|
+
apps_dir = get_apps_directory()
|
203
|
+
|
204
|
+
# Boş liste testi
|
205
|
+
packages = list_packages()
|
206
|
+
if isinstance(packages, list):
|
207
|
+
self.log_test("List Packages Type", True, f"{len(packages)} paket bulundu")
|
208
|
+
else:
|
209
|
+
self.log_test("List Packages Type", False, f"Yanlış tip: {type(packages)}")
|
210
|
+
return False
|
211
|
+
|
212
|
+
# Var olmayan uygulama testi
|
213
|
+
manifest = get_manifest("nonexistent-app")
|
214
|
+
if manifest is None:
|
215
|
+
self.log_test("Non-existent App", True, "Var olmayan uygulama None döndürdü")
|
216
|
+
else:
|
217
|
+
self.log_test("Non-existent App", False, "Var olmayan uygulama None döndürmedi")
|
218
|
+
return False
|
219
|
+
|
220
|
+
# app_exists testi
|
221
|
+
exists = app_exists("nonexistent-app")
|
222
|
+
if not exists:
|
223
|
+
self.log_test("App Exists Check", True, "Var olmayan uygulama False döndürdü")
|
224
|
+
else:
|
225
|
+
self.log_test("App Exists Check", False, "Var olmayan uygulama True döndürdü")
|
226
|
+
return False
|
227
|
+
|
228
|
+
return True
|
229
|
+
|
230
|
+
except Exception as e:
|
231
|
+
self.log_test("Package Registry", False, f"Paket kayıt sistemi hatası: {e}")
|
232
|
+
return False
|
233
|
+
|
234
|
+
def test_cli_commands(self) -> bool:
|
235
|
+
"""CLI komutları testleri"""
|
236
|
+
print("\n🔍 CLI Komutları Testleri")
|
237
|
+
print("=" * 50)
|
238
|
+
|
239
|
+
try:
|
240
|
+
from cli_commands import handle_version_command, handle_list_command
|
241
|
+
|
242
|
+
# Version komutu testi
|
243
|
+
try:
|
244
|
+
# Mock args objesi oluştur
|
245
|
+
class MockArgs:
|
246
|
+
def __init__(self):
|
247
|
+
self.format = 'default'
|
248
|
+
|
249
|
+
args = MockArgs()
|
250
|
+
handle_version_command(args)
|
251
|
+
self.log_test("Version Command", True, "Version komutu çalıştı")
|
252
|
+
except Exception as e:
|
253
|
+
self.log_test("Version Command", False, f"Version komutu hatası: {e}")
|
254
|
+
return False
|
255
|
+
|
256
|
+
# List komutu testi
|
257
|
+
try:
|
258
|
+
# Mock args objesi oluştur
|
259
|
+
class MockArgs:
|
260
|
+
def __init__(self):
|
261
|
+
self.format = 'table'
|
262
|
+
self.language = None
|
263
|
+
self.search = None
|
264
|
+
|
265
|
+
args = MockArgs()
|
266
|
+
handle_list_command(args)
|
267
|
+
self.log_test("List Command", True, "List komutu çalıştı")
|
268
|
+
except Exception as e:
|
269
|
+
self.log_test("List Command", False, f"List komutu hatası: {e}")
|
270
|
+
return False
|
271
|
+
|
272
|
+
return True
|
273
|
+
|
274
|
+
except Exception as e:
|
275
|
+
self.log_test("CLI Commands", False, f"CLI komutları hatası: {e}")
|
276
|
+
return False
|
277
|
+
|
278
|
+
def test_integration(self) -> bool:
|
279
|
+
"""Entegrasyon testleri"""
|
280
|
+
print("\n🔍 Entegrasyon Testleri")
|
281
|
+
print("=" * 50)
|
282
|
+
|
283
|
+
# Test uygulaması oluştur
|
284
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
285
|
+
try:
|
286
|
+
# Test uygulaması dizini
|
287
|
+
test_app_dir = Path(temp_dir) / "test-app"
|
288
|
+
test_app_dir.mkdir()
|
289
|
+
|
290
|
+
# Test manifest.json
|
291
|
+
manifest = {
|
292
|
+
"name": "test-app",
|
293
|
+
"version": "1.0.0",
|
294
|
+
"language": "python",
|
295
|
+
"entry": "main.py",
|
296
|
+
"description": "Test uygulaması"
|
297
|
+
}
|
298
|
+
|
299
|
+
manifest_file = test_app_dir / "manifest.json"
|
300
|
+
with open(manifest_file, 'w', encoding='utf-8') as f:
|
301
|
+
json.dump(manifest, f, indent=2, ensure_ascii=False)
|
302
|
+
|
303
|
+
# Test main.py
|
304
|
+
main_file = test_app_dir / "main.py"
|
305
|
+
main_file.write_text('print("Hello from test app!")')
|
306
|
+
|
307
|
+
# package_registry entegrasyonu
|
308
|
+
from package_registry import get_apps_directory
|
309
|
+
apps_dir = get_apps_directory()
|
310
|
+
target_dir = Path(apps_dir) / "test-app"
|
311
|
+
|
312
|
+
# Kopyala
|
313
|
+
if target_dir.exists():
|
314
|
+
shutil.rmtree(target_dir)
|
315
|
+
shutil.copytree(test_app_dir, target_dir)
|
316
|
+
|
317
|
+
# Manifest doğrulama
|
318
|
+
from manifest_validator import validate_manifest_verbose
|
319
|
+
with open(target_dir / "manifest.json", 'r', encoding='utf-8') as f:
|
320
|
+
loaded_manifest = json.load(f)
|
321
|
+
|
322
|
+
is_valid, errors = validate_manifest_verbose(loaded_manifest)
|
323
|
+
if is_valid:
|
324
|
+
self.log_test("Integration Manifest Validation", True, "Manifest doğrulandı")
|
325
|
+
else:
|
326
|
+
self.log_test("Integration Manifest Validation", False, f"Doğrulama hataları: {errors}")
|
327
|
+
return False
|
328
|
+
|
329
|
+
# package_registry entegrasyonu
|
330
|
+
from package_registry import get_manifest, app_exists
|
331
|
+
manifest = get_manifest("test-app")
|
332
|
+
if manifest and manifest["name"] == "test-app":
|
333
|
+
self.log_test("Integration Package Registry", True, "Paket kayıt sistemi çalışıyor")
|
334
|
+
else:
|
335
|
+
self.log_test("Integration Package Registry", False, "Paket kayıt sistemi hatası")
|
336
|
+
return False
|
337
|
+
|
338
|
+
# app_exists testi
|
339
|
+
if app_exists("test-app"):
|
340
|
+
self.log_test("Integration App Exists", True, "Uygulama varlık kontrolü çalışıyor")
|
341
|
+
else:
|
342
|
+
self.log_test("Integration App Exists", False, "Uygulama varlık kontrolü hatası")
|
343
|
+
return False
|
344
|
+
|
345
|
+
# Temizlik
|
346
|
+
if target_dir.exists():
|
347
|
+
shutil.rmtree(target_dir)
|
348
|
+
|
349
|
+
return True
|
350
|
+
|
351
|
+
except Exception as e:
|
352
|
+
self.log_test("Integration Test", False, f"Entegrasyon testi hatası: {e}")
|
353
|
+
return False
|
354
|
+
|
355
|
+
def test_cli_execution(self) -> bool:
|
356
|
+
"""CLI çalıştırma testleri"""
|
357
|
+
print("\n🔍 CLI Çalıştırma Testleri")
|
358
|
+
print("=" * 50)
|
359
|
+
|
360
|
+
try:
|
361
|
+
# Version komutu
|
362
|
+
result = subprocess.run([sys.executable, "main.py", "version"],
|
363
|
+
capture_output=True, text=True, timeout=10)
|
364
|
+
|
365
|
+
if result.returncode == 0:
|
366
|
+
self.log_test("CLI Version Execution", True, "Version komutu başarıyla çalıştı")
|
367
|
+
else:
|
368
|
+
self.log_test("CLI Version Execution", False, f"Version komutu hatası: {result.stderr}")
|
369
|
+
return False
|
370
|
+
|
371
|
+
# List komutu
|
372
|
+
result = subprocess.run([sys.executable, "main.py", "list"],
|
373
|
+
capture_output=True, text=True, timeout=10)
|
374
|
+
|
375
|
+
if result.returncode == 0:
|
376
|
+
self.log_test("CLI List Execution", True, "List komutu başarıyla çalıştı")
|
377
|
+
else:
|
378
|
+
self.log_test("CLI List Execution", False, f"List komutu hatası: {result.stderr}")
|
379
|
+
return False
|
380
|
+
|
381
|
+
return True
|
382
|
+
|
383
|
+
except subprocess.TimeoutExpired:
|
384
|
+
self.log_test("CLI Execution", False, "CLI komutları zaman aşımı")
|
385
|
+
return False
|
386
|
+
except Exception as e:
|
387
|
+
self.log_test("CLI Execution", False, f"CLI çalıştırma hatası: {e}")
|
388
|
+
return False
|
389
|
+
|
390
|
+
def run_all_tests(self) -> Dict[str, Any]:
|
391
|
+
"""Tüm testleri çalıştır"""
|
392
|
+
print("🚀 CLAPP Sistem Entegrasyon Testi Başlatılıyor")
|
393
|
+
print("=" * 60)
|
394
|
+
|
395
|
+
tests = [
|
396
|
+
("Modül Importları", self.test_imports),
|
397
|
+
("Sürüm Sistemi", self.test_version_system),
|
398
|
+
("Dizin Yapısı", self.test_directory_structure),
|
399
|
+
("Manifest Sistemi", self.test_manifest_system),
|
400
|
+
("Paket Kayıt Sistemi", self.test_package_registry),
|
401
|
+
("CLI Komutları", self.test_cli_commands),
|
402
|
+
("Entegrasyon", self.test_integration),
|
403
|
+
("CLI Çalıştırma", self.test_cli_execution)
|
404
|
+
]
|
405
|
+
|
406
|
+
results = {}
|
407
|
+
for test_name, test_func in tests:
|
408
|
+
try:
|
409
|
+
success = test_func()
|
410
|
+
results[test_name] = success
|
411
|
+
except Exception as e:
|
412
|
+
self.log_test(test_name, False, f"Test hatası: {e}")
|
413
|
+
results[test_name] = False
|
414
|
+
|
415
|
+
return results
|
416
|
+
|
417
|
+
def generate_report(self) -> str:
|
418
|
+
"""Test raporu oluştur"""
|
419
|
+
print("\n" + "=" * 60)
|
420
|
+
print("📊 TEST RAPORU")
|
421
|
+
print("=" * 60)
|
422
|
+
|
423
|
+
total_tests = len(self.test_results)
|
424
|
+
successful_tests = len([r for r in self.test_results if r["success"]])
|
425
|
+
failed_tests = len(self.errors)
|
426
|
+
|
427
|
+
print(f"Toplam Test: {total_tests}")
|
428
|
+
print(f"Başarılı: {successful_tests}")
|
429
|
+
print(f"Başarısız: {failed_tests}")
|
430
|
+
print(f"Başarı Oranı: {(successful_tests/total_tests*100):.1f}%")
|
431
|
+
|
432
|
+
if self.errors:
|
433
|
+
print(f"\n❌ BAŞARISIZ TESTLER:")
|
434
|
+
for error in self.errors:
|
435
|
+
print(f" - {error['test']}: {error['message']}")
|
436
|
+
|
437
|
+
if self.warnings:
|
438
|
+
print(f"\n⚠️ UYARILAR:")
|
439
|
+
for warning in self.warnings:
|
440
|
+
print(f" - {warning}")
|
441
|
+
|
442
|
+
if failed_tests == 0:
|
443
|
+
print(f"\n🎉 TÜM TESTLER BAŞARILI! Sistem tam entegre çalışıyor.")
|
444
|
+
else:
|
445
|
+
print(f"\n🔧 {failed_tests} test başarısız. Sistem entegrasyonunda sorunlar var.")
|
446
|
+
|
447
|
+
return f"Başarı Oranı: {(successful_tests/total_tests*100):.1f}%"
|
448
|
+
|
449
|
+
def main():
|
450
|
+
"""Ana test fonksiyonu"""
|
451
|
+
tester = SystemTester()
|
452
|
+
results = tester.run_all_tests()
|
453
|
+
report = tester.generate_report()
|
454
|
+
|
455
|
+
# Sonuçları JSON olarak kaydet
|
456
|
+
with open("test_results.json", "w", encoding="utf-8") as f:
|
457
|
+
json.dump({
|
458
|
+
"results": results,
|
459
|
+
"test_details": tester.test_results,
|
460
|
+
"errors": tester.errors,
|
461
|
+
"warnings": tester.warnings,
|
462
|
+
"summary": report
|
463
|
+
}, f, indent=2, ensure_ascii=False)
|
464
|
+
|
465
|
+
print(f"\n📄 Detaylı rapor: test_results.json")
|
466
|
+
|
467
|
+
# Başarı oranına göre exit code
|
468
|
+
total_tests = len(tester.test_results)
|
469
|
+
successful_tests = len([r for r in tester.test_results if r["success"]])
|
470
|
+
|
471
|
+
if successful_tests == total_tests:
|
472
|
+
sys.exit(0) # Başarılı
|
473
|
+
else:
|
474
|
+
sys.exit(1) # Başarısız
|
475
|
+
|
476
|
+
if __name__ == "__main__":
|
477
|
+
main()
|
@@ -0,0 +1,215 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
uninstall_command.py - clapp Uninstall Command
|
4
|
+
|
5
|
+
Bu modül 'clapp uninstall <app_name>' komutunu uygular.
|
6
|
+
Kurulu uygulamaları güvenli bir şekilde kaldırır.
|
7
|
+
"""
|
8
|
+
|
9
|
+
import os
|
10
|
+
import shutil
|
11
|
+
import sys
|
12
|
+
from pathlib import Path
|
13
|
+
from typing import Tuple, List
|
14
|
+
|
15
|
+
def get_apps_directory() -> str:
|
16
|
+
"""Uygulamaların kurulu olduğu dizini döndürür"""
|
17
|
+
# Kullanıcının home dizininde .clapp klasörü
|
18
|
+
home_dir = Path.home()
|
19
|
+
clapp_dir = home_dir / ".clapp"
|
20
|
+
apps_dir = clapp_dir / "apps"
|
21
|
+
|
22
|
+
return str(apps_dir)
|
23
|
+
|
24
|
+
def get_installed_apps() -> List[str]:
|
25
|
+
"""Kurulu uygulamaların listesini döndürür"""
|
26
|
+
apps_dir = get_apps_directory()
|
27
|
+
|
28
|
+
if not os.path.exists(apps_dir):
|
29
|
+
return []
|
30
|
+
|
31
|
+
apps = []
|
32
|
+
for item in os.listdir(apps_dir):
|
33
|
+
item_path = os.path.join(apps_dir, item)
|
34
|
+
if os.path.isdir(item_path) and not item.startswith('.'):
|
35
|
+
# manifest.json varlığını kontrol et
|
36
|
+
manifest_path = os.path.join(item_path, "manifest.json")
|
37
|
+
if os.path.exists(manifest_path):
|
38
|
+
apps.append(item)
|
39
|
+
|
40
|
+
return apps
|
41
|
+
|
42
|
+
def is_app_installed(app_name: str) -> bool:
|
43
|
+
"""Uygulamanın kurulu olup olmadığını kontrol eder"""
|
44
|
+
apps_dir = get_apps_directory()
|
45
|
+
app_path = os.path.join(apps_dir, app_name)
|
46
|
+
|
47
|
+
if not os.path.exists(app_path):
|
48
|
+
return False
|
49
|
+
|
50
|
+
if not os.path.isdir(app_path):
|
51
|
+
return False
|
52
|
+
|
53
|
+
# manifest.json varlığını kontrol et
|
54
|
+
manifest_path = os.path.join(app_path, "manifest.json")
|
55
|
+
return os.path.exists(manifest_path)
|
56
|
+
|
57
|
+
def get_app_info(app_name: str) -> Tuple[bool, str, dict]:
|
58
|
+
"""Uygulamanın bilgilerini getirir"""
|
59
|
+
apps_dir = get_apps_directory()
|
60
|
+
app_path = os.path.join(apps_dir, app_name)
|
61
|
+
manifest_path = os.path.join(app_path, "manifest.json")
|
62
|
+
|
63
|
+
try:
|
64
|
+
import json
|
65
|
+
with open(manifest_path, 'r', encoding='utf-8') as f:
|
66
|
+
manifest = json.load(f)
|
67
|
+
|
68
|
+
return True, "Bilgiler alındı", manifest
|
69
|
+
except Exception as e:
|
70
|
+
return False, f"Manifest okunamadı: {e}", {}
|
71
|
+
|
72
|
+
def confirm_uninstall(app_name: str, app_info: dict, skip_confirmation: bool = False) -> bool:
|
73
|
+
"""Kullanıcıdan kaldırma onayı alır"""
|
74
|
+
if skip_confirmation:
|
75
|
+
return True
|
76
|
+
|
77
|
+
print(f"\n📋 Kaldırılacak uygulama:")
|
78
|
+
print(f" Ad: {app_info.get('name', app_name)}")
|
79
|
+
print(f" Sürüm: {app_info.get('version', 'Bilinmiyor')}")
|
80
|
+
print(f" Dil: {app_info.get('language', 'Bilinmiyor')}")
|
81
|
+
print(f" Açıklama: {app_info.get('description', 'Yok')}")
|
82
|
+
|
83
|
+
while True:
|
84
|
+
response = input(f"\n❓ '{app_name}' uygulamasını kaldırmak istediğinizden emin misiniz? (e/h): ").lower().strip()
|
85
|
+
if response in ['e', 'evet', 'y', 'yes']:
|
86
|
+
return True
|
87
|
+
elif response in ['h', 'hayır', 'n', 'no']:
|
88
|
+
return False
|
89
|
+
else:
|
90
|
+
print("Lütfen 'e' (evet) veya 'h' (hayır) giriniz.")
|
91
|
+
|
92
|
+
def remove_app_directory(app_name: str) -> Tuple[bool, str]:
|
93
|
+
"""Uygulama klasörünü güvenli şekilde kaldırır"""
|
94
|
+
try:
|
95
|
+
apps_dir = get_apps_directory()
|
96
|
+
app_path = os.path.join(apps_dir, app_name)
|
97
|
+
|
98
|
+
# Güvenlik kontrolü - sadece .clapp/apps altındaki klasörleri sil
|
99
|
+
if not app_path.startswith(apps_dir):
|
100
|
+
return False, "Güvenlik hatası: Geçersiz klasör yolu"
|
101
|
+
|
102
|
+
if not os.path.exists(app_path):
|
103
|
+
return False, "Uygulama klasörü bulunamadı"
|
104
|
+
|
105
|
+
# Klasörü sil
|
106
|
+
shutil.rmtree(app_path)
|
107
|
+
|
108
|
+
return True, f"Uygulama klasörü kaldırıldı: {app_path}"
|
109
|
+
|
110
|
+
except PermissionError:
|
111
|
+
return False, "İzin hatası: Klasör kaldırılamadı"
|
112
|
+
except Exception as e:
|
113
|
+
return False, f"Kaldırma hatası: {e}"
|
114
|
+
|
115
|
+
def uninstall_app(app_name: str, skip_confirmation: bool = False) -> Tuple[bool, str]:
|
116
|
+
"""
|
117
|
+
Ana uninstall fonksiyonu
|
118
|
+
|
119
|
+
Args:
|
120
|
+
app_name: Kaldırılacak uygulamanın adı
|
121
|
+
skip_confirmation: Onay sorma (--yes flag için)
|
122
|
+
|
123
|
+
Returns:
|
124
|
+
(success, message)
|
125
|
+
"""
|
126
|
+
print(f"🗑️ Kaldırma başlatılıyor: {app_name}")
|
127
|
+
print("=" * 50)
|
128
|
+
|
129
|
+
# 1. Uygulama kurulu mu kontrol et
|
130
|
+
print("1️⃣ Uygulama kontrol ediliyor...")
|
131
|
+
|
132
|
+
if not is_app_installed(app_name):
|
133
|
+
installed_apps = get_installed_apps()
|
134
|
+
if installed_apps:
|
135
|
+
return False, f"Uygulama kurulu değil: {app_name}\nKurulu uygulamalar: {', '.join(installed_apps)}"
|
136
|
+
else:
|
137
|
+
return False, f"Uygulama kurulu değil: {app_name}\nHiç uygulama kurulu değil."
|
138
|
+
|
139
|
+
print(f"✅ {app_name} kurulu")
|
140
|
+
|
141
|
+
# 2. Uygulama bilgilerini al
|
142
|
+
print("2️⃣ Uygulama bilgileri alınıyor...")
|
143
|
+
info_success, info_message, app_info = get_app_info(app_name)
|
144
|
+
|
145
|
+
if not info_success:
|
146
|
+
print(f"⚠️ {info_message}")
|
147
|
+
app_info = {'name': app_name}
|
148
|
+
|
149
|
+
# 3. Kullanıcı onayı
|
150
|
+
if not skip_confirmation:
|
151
|
+
print("3️⃣ Kullanıcı onayı bekleniyor...")
|
152
|
+
if not confirm_uninstall(app_name, app_info, skip_confirmation):
|
153
|
+
return False, "Kaldırma işlemi iptal edildi"
|
154
|
+
|
155
|
+
# 4. Uygulamayı kaldır
|
156
|
+
print("4️⃣ Uygulama kaldırılıyor...")
|
157
|
+
remove_success, remove_message = remove_app_directory(app_name)
|
158
|
+
|
159
|
+
if not remove_success:
|
160
|
+
return False, remove_message
|
161
|
+
|
162
|
+
return True, f"🎉 '{app_name}' başarıyla kaldırıldı!"
|
163
|
+
|
164
|
+
def list_installed_apps():
|
165
|
+
"""Kurulu uygulamaları listeler"""
|
166
|
+
apps = get_installed_apps()
|
167
|
+
|
168
|
+
if not apps:
|
169
|
+
print("📭 Hiç uygulama kurulu değil.")
|
170
|
+
return
|
171
|
+
|
172
|
+
print(f"📦 Kurulu uygulamalar ({len(apps)}):")
|
173
|
+
print("-" * 30)
|
174
|
+
|
175
|
+
for app_name in sorted(apps):
|
176
|
+
info_success, _, app_info = get_app_info(app_name)
|
177
|
+
if info_success:
|
178
|
+
version = app_info.get('version', '?')
|
179
|
+
language = app_info.get('language', '?')
|
180
|
+
print(f" • {app_name} (v{version}) - {language}")
|
181
|
+
else:
|
182
|
+
print(f" • {app_name} - bilgi alınamadı")
|
183
|
+
|
184
|
+
def main():
|
185
|
+
"""CLI entry point"""
|
186
|
+
if len(sys.argv) < 2:
|
187
|
+
print("Kullanım: python uninstall_command.py <app_name> [--yes]")
|
188
|
+
print(" python uninstall_command.py --list")
|
189
|
+
print()
|
190
|
+
print("Örnekler:")
|
191
|
+
print(" python uninstall_command.py hello-python")
|
192
|
+
print(" python uninstall_command.py hello-python --yes")
|
193
|
+
print(" python uninstall_command.py --list")
|
194
|
+
sys.exit(1)
|
195
|
+
|
196
|
+
# --list flag kontrolü
|
197
|
+
if sys.argv[1] == "--list":
|
198
|
+
list_installed_apps()
|
199
|
+
sys.exit(0)
|
200
|
+
|
201
|
+
app_name = sys.argv[1]
|
202
|
+
skip_confirmation = "--yes" in sys.argv
|
203
|
+
|
204
|
+
success, message = uninstall_app(app_name, skip_confirmation)
|
205
|
+
|
206
|
+
print("\n" + "=" * 50)
|
207
|
+
if success:
|
208
|
+
print(f"✅ {message}")
|
209
|
+
sys.exit(0)
|
210
|
+
else:
|
211
|
+
print(f"❌ {message}")
|
212
|
+
sys.exit(1)
|
213
|
+
|
214
|
+
if __name__ == "__main__":
|
215
|
+
main()
|