gitarsenal-cli 1.1.1 → 1.1.2
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.
- package/package.json +1 -1
- package/python/README.md +78 -35
- package/python/gitarsenal.py +83 -1
- package/python/requirements.txt +4 -0
- package/python/test_modalSandboxScript.py +225 -64
package/package.json
CHANGED
package/python/README.md
CHANGED
@@ -13,50 +13,51 @@ cd gitarsenal-cli/python
|
|
13
13
|
pip install -r requirements.txt
|
14
14
|
```
|
15
15
|
|
16
|
-
##
|
16
|
+
## First-Time Setup
|
17
17
|
|
18
|
-
GitArsenal CLI
|
18
|
+
Before using GitArsenal CLI, you need to set up your credentials and authenticate with Modal:
|
19
19
|
|
20
|
-
|
21
|
-
- **Modal Token**: Used to create cloud environments
|
22
|
-
- **Hugging Face Token**: Used for accessing Hugging Face models
|
23
|
-
- **Weights & Biases API Key**: Used for experiment tracking
|
24
|
-
|
25
|
-
You can set up your credentials using the credentials manager:
|
20
|
+
### 1. Install Modal
|
26
21
|
|
27
22
|
```bash
|
28
|
-
|
23
|
+
pip install modal
|
29
24
|
```
|
30
25
|
|
31
|
-
|
26
|
+
### 2. Create a Modal Account and Get a Token
|
32
27
|
|
33
|
-
|
28
|
+
If you don't have a Modal account:
|
29
|
+
1. Go to https://modal.com and create an account
|
30
|
+
2. Run the following command to authenticate:
|
31
|
+
```bash
|
32
|
+
modal token new
|
33
|
+
```
|
34
|
+
3. Follow the instructions to complete authentication
|
34
35
|
|
35
|
-
|
36
|
+
### 3. Set Up GitArsenal Credentials
|
36
37
|
|
37
38
|
```bash
|
38
|
-
# Set
|
39
|
-
|
39
|
+
# Set up all required credentials
|
40
|
+
./gitarsenal.py credentials setup
|
41
|
+
```
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
+
This will guide you through setting up:
|
44
|
+
- **Modal Token**: Required for creating cloud environments
|
45
|
+
- **OpenAI API Key**: Used for debugging failed commands (optional)
|
46
|
+
- **Hugging Face Token**: Used for accessing Hugging Face models (optional)
|
47
|
+
- **Weights & Biases API Key**: Used for experiment tracking (optional)
|
43
48
|
|
44
|
-
|
45
|
-
python manage_credentials.py clear huggingface_token
|
49
|
+
## Usage
|
46
50
|
|
47
|
-
|
48
|
-
python manage_credentials.py clear
|
51
|
+
### Creating a Modal Sandbox
|
49
52
|
|
50
|
-
|
51
|
-
|
53
|
+
```bash
|
54
|
+
./gitarsenal.py sandbox --gpu A10G --repo-url "https://github.com/username/repo.git"
|
52
55
|
```
|
53
56
|
|
54
|
-
|
55
|
-
|
56
|
-
### Creating a Modal Sandbox
|
57
|
+
### Creating an SSH Container
|
57
58
|
|
58
59
|
```bash
|
59
|
-
|
60
|
+
./gitarsenal.py ssh --gpu A10G --repo-url "https://github.com/username/repo.git"
|
60
61
|
```
|
61
62
|
|
62
63
|
### Options
|
@@ -66,6 +67,31 @@ python test_modalSandboxScript.py --gpu A10G --repo-url "https://github.com/user
|
|
66
67
|
- `--repo-name`: Repository name override
|
67
68
|
- `--setup-commands`: Setup commands to run
|
68
69
|
- `--volume-name`: Name of the Modal volume for persistent storage
|
70
|
+
- `--timeout`: Container timeout in minutes (SSH mode only, default: 60)
|
71
|
+
|
72
|
+
## Managing Credentials
|
73
|
+
|
74
|
+
You can manage your credentials using the following commands:
|
75
|
+
|
76
|
+
```bash
|
77
|
+
# Set up all credentials
|
78
|
+
./gitarsenal.py credentials setup
|
79
|
+
|
80
|
+
# Set a specific credential
|
81
|
+
./gitarsenal.py credentials set modal_token
|
82
|
+
|
83
|
+
# View a credential (masked for security)
|
84
|
+
./gitarsenal.py credentials get modal_token
|
85
|
+
|
86
|
+
# Clear a specific credential
|
87
|
+
./gitarsenal.py credentials clear huggingface_token
|
88
|
+
|
89
|
+
# Clear all credentials
|
90
|
+
./gitarsenal.py credentials clear
|
91
|
+
|
92
|
+
# List all saved credentials (without showing values)
|
93
|
+
./gitarsenal.py credentials list
|
94
|
+
```
|
69
95
|
|
70
96
|
## Security
|
71
97
|
|
@@ -73,23 +99,40 @@ Your credentials are stored securely in `~/.gitarsenal/credentials.json` with re
|
|
73
99
|
|
74
100
|
## Troubleshooting
|
75
101
|
|
76
|
-
|
102
|
+
### Modal Authentication Issues
|
77
103
|
|
78
|
-
|
104
|
+
If you see errors like "Token missing" or "Could not authenticate client":
|
105
|
+
|
106
|
+
1. Ensure Modal is installed:
|
79
107
|
```bash
|
80
|
-
|
108
|
+
pip install modal
|
81
109
|
```
|
82
110
|
|
83
|
-
2.
|
111
|
+
2. Get a new Modal token:
|
84
112
|
```bash
|
85
|
-
|
86
|
-
python manage_credentials.py setup
|
113
|
+
modal token new
|
87
114
|
```
|
88
115
|
|
89
|
-
3.
|
116
|
+
3. Save the token in GitArsenal:
|
90
117
|
```bash
|
91
|
-
|
92
|
-
|
118
|
+
./gitarsenal.py credentials set modal_token
|
119
|
+
```
|
120
|
+
|
121
|
+
### API Timeout Issues
|
122
|
+
|
123
|
+
If the GitArsenal API times out when analyzing repositories, the tool will automatically use fallback setup commands based on the detected programming language and technologies.
|
124
|
+
|
125
|
+
### Other Issues
|
126
|
+
|
127
|
+
1. Check that your credentials are set up correctly:
|
128
|
+
```bash
|
129
|
+
./gitarsenal.py credentials list
|
130
|
+
```
|
131
|
+
|
132
|
+
2. If needed, clear and reset your credentials:
|
133
|
+
```bash
|
134
|
+
./gitarsenal.py credentials clear
|
135
|
+
./gitarsenal.py credentials setup
|
93
136
|
```
|
94
137
|
|
95
138
|
## License
|
package/python/gitarsenal.py
CHANGED
@@ -9,6 +9,55 @@ import argparse
|
|
9
9
|
import sys
|
10
10
|
import os
|
11
11
|
import subprocess
|
12
|
+
import json
|
13
|
+
from pathlib import Path
|
14
|
+
|
15
|
+
def check_modal_auth():
|
16
|
+
"""Check if Modal is authenticated and guide user if not"""
|
17
|
+
try:
|
18
|
+
# Try to run a simple Modal command to check authentication
|
19
|
+
result = subprocess.run(["modal", "app", "list"],
|
20
|
+
capture_output=True, text=True, timeout=10)
|
21
|
+
|
22
|
+
# If the command was successful, Modal is authenticated
|
23
|
+
if result.returncode == 0:
|
24
|
+
return True
|
25
|
+
|
26
|
+
# Check for specific authentication errors
|
27
|
+
if "Token missing" in result.stderr or "Could not authenticate" in result.stderr:
|
28
|
+
print("\n" + "="*80)
|
29
|
+
print("🔑 MODAL AUTHENTICATION REQUIRED")
|
30
|
+
print("="*80)
|
31
|
+
print("GitArsenal requires Modal authentication to create cloud environments.")
|
32
|
+
print("\nTo authenticate with Modal, you need to:")
|
33
|
+
print("1. Create a Modal account at https://modal.com if you don't have one")
|
34
|
+
print("2. Run the following command to get a token:")
|
35
|
+
print(" modal token new")
|
36
|
+
print("3. Then set up your credentials in GitArsenal:")
|
37
|
+
print(" ./gitarsenal.py credentials set modal_token")
|
38
|
+
print("\nAfter completing these steps, try your command again.")
|
39
|
+
print("="*80)
|
40
|
+
return False
|
41
|
+
|
42
|
+
# Other errors
|
43
|
+
print(f"⚠️ Modal command returned error: {result.stderr}")
|
44
|
+
return False
|
45
|
+
|
46
|
+
except FileNotFoundError:
|
47
|
+
print("\n" + "="*80)
|
48
|
+
print("❌ MODAL CLI NOT INSTALLED")
|
49
|
+
print("="*80)
|
50
|
+
print("GitArsenal requires the Modal CLI to be installed.")
|
51
|
+
print("\nTo install Modal CLI, run:")
|
52
|
+
print(" pip install modal")
|
53
|
+
print("\nAfter installation, set up your credentials:")
|
54
|
+
print("1. Run 'modal token new' to authenticate")
|
55
|
+
print("2. Run './gitarsenal.py credentials set modal_token'")
|
56
|
+
print("="*80)
|
57
|
+
return False
|
58
|
+
except Exception as e:
|
59
|
+
print(f"⚠️ Error checking Modal authentication: {e}")
|
60
|
+
return False
|
12
61
|
|
13
62
|
def main():
|
14
63
|
parser = argparse.ArgumentParser(description="GitArsenal CLI - GPU-accelerated cloud environments")
|
@@ -82,8 +131,41 @@ def main():
|
|
82
131
|
|
83
132
|
return run_script("manage_credentials.py", cred_args)
|
84
133
|
|
134
|
+
# For sandbox and SSH commands, check Modal authentication first
|
135
|
+
if args.command in ["sandbox", "ssh"]:
|
136
|
+
# Check if Modal is authenticated
|
137
|
+
if not check_modal_auth():
|
138
|
+
print("\n⚠️ Please authenticate with Modal before proceeding.")
|
139
|
+
return 1
|
140
|
+
|
141
|
+
# Try to load credentials and set Modal token if available
|
142
|
+
try:
|
143
|
+
from credentials_manager import CredentialsManager
|
144
|
+
credentials_manager = CredentialsManager()
|
145
|
+
credentials = credentials_manager.load_credentials()
|
146
|
+
|
147
|
+
if "modal_token" in credentials:
|
148
|
+
# Set the Modal token in the environment
|
149
|
+
os.environ["MODAL_TOKEN_ID"] = credentials["modal_token"]
|
150
|
+
print("✅ Using Modal token from credentials")
|
151
|
+
|
152
|
+
# Try to authenticate with the token
|
153
|
+
try:
|
154
|
+
token_result = subprocess.run(
|
155
|
+
["modal", "token", "set", credentials["modal_token"]],
|
156
|
+
capture_output=True, text=True
|
157
|
+
)
|
158
|
+
if token_result.returncode == 0:
|
159
|
+
print("✅ Successfully authenticated with Modal")
|
160
|
+
except Exception as e:
|
161
|
+
print(f"⚠️ Error setting Modal token: {e}")
|
162
|
+
except ImportError:
|
163
|
+
print("⚠️ Could not load credentials manager")
|
164
|
+
except Exception as e:
|
165
|
+
print(f"⚠️ Error loading credentials: {e}")
|
166
|
+
|
85
167
|
# Handle sandbox command
|
86
|
-
|
168
|
+
if args.command == "sandbox":
|
87
169
|
sandbox_args = []
|
88
170
|
|
89
171
|
if args.gpu:
|
@@ -478,36 +478,73 @@ def create_modal_sandbox(gpu_type, repo_url=None, repo_name=None, setup_commands
|
|
478
478
|
|
479
479
|
# Check if Modal is authenticated
|
480
480
|
try:
|
481
|
-
# Try to
|
482
|
-
import
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
481
|
+
# Try to import modal first to check if it's installed
|
482
|
+
import modal
|
483
|
+
|
484
|
+
# Try to access Modal token to check authentication
|
485
|
+
try:
|
486
|
+
# This will raise an exception if not authenticated
|
487
|
+
modal.config.get_current_workspace_name()
|
488
|
+
print("✅ Modal authentication verified")
|
489
|
+
except modal.exception.AuthError:
|
490
|
+
print("\n" + "="*80)
|
491
|
+
print("🔑 MODAL AUTHENTICATION REQUIRED")
|
492
|
+
print("="*80)
|
493
|
+
print("GitArsenal requires Modal authentication to create cloud environments.")
|
494
|
+
|
495
|
+
# Try to get token from credentials manager
|
496
|
+
modal_token = None
|
488
497
|
if credentials_manager:
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
498
|
+
try:
|
499
|
+
modal_token = credentials_manager.get_modal_token()
|
500
|
+
if modal_token:
|
501
|
+
# Set the token in the environment
|
502
|
+
os.environ["MODAL_TOKEN_ID"] = modal_token
|
503
|
+
print("✅ Modal token set from credentials manager")
|
504
|
+
|
505
|
+
# Try to authenticate with the token
|
506
|
+
try:
|
507
|
+
import subprocess
|
508
|
+
token_result = subprocess.run(
|
509
|
+
["modal", "token", "set", modal_token],
|
510
|
+
capture_output=True, text=True
|
511
|
+
)
|
512
|
+
if token_result.returncode == 0:
|
513
|
+
print("✅ Successfully authenticated with Modal")
|
514
|
+
else:
|
515
|
+
print(f"⚠️ Failed to authenticate with Modal: {token_result.stderr}")
|
516
|
+
print("\nPlease authenticate manually:")
|
517
|
+
print("1. Run 'modal token new' to get a new token")
|
518
|
+
print("2. Then restart this command")
|
519
|
+
return None
|
520
|
+
except Exception as e:
|
521
|
+
print(f"⚠️ Error setting Modal token: {e}")
|
504
522
|
return None
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
print("
|
523
|
+
except Exception as e:
|
524
|
+
print(f"⚠️ Error getting Modal token: {e}")
|
525
|
+
|
526
|
+
if not modal_token:
|
527
|
+
print("\nTo authenticate with Modal, you need to:")
|
528
|
+
print("1. Create a Modal account at https://modal.com if you don't have one")
|
529
|
+
print("2. Run the following command to get a token:")
|
530
|
+
print(" modal token new")
|
531
|
+
print("3. Then set up your credentials in GitArsenal:")
|
532
|
+
print(" ./gitarsenal.py credentials set modal_token")
|
533
|
+
print("\nAfter completing these steps, try your command again.")
|
534
|
+
print("="*80)
|
510
535
|
return None
|
536
|
+
except ImportError:
|
537
|
+
print("\n" + "="*80)
|
538
|
+
print("❌ MODAL PACKAGE NOT INSTALLED")
|
539
|
+
print("="*80)
|
540
|
+
print("GitArsenal requires the Modal package to be installed.")
|
541
|
+
print("\nTo install Modal, run:")
|
542
|
+
print(" pip install modal")
|
543
|
+
print("\nAfter installation, authenticate with Modal:")
|
544
|
+
print("1. Run 'modal token new'")
|
545
|
+
print("2. Then run './gitarsenal.py credentials set modal_token'")
|
546
|
+
print("="*80)
|
547
|
+
return None
|
511
548
|
except Exception as e:
|
512
549
|
print(f"⚠️ Error checking Modal authentication: {e}")
|
513
550
|
print("Continuing anyway, but Modal operations may fail")
|
@@ -2393,53 +2430,177 @@ def fetch_setup_commands_from_api(repo_url):
|
|
2393
2430
|
|
2394
2431
|
# Make the API request
|
2395
2432
|
print(f"🌐 Making POST request to: {api_url}")
|
2396
|
-
|
2397
|
-
|
2398
|
-
|
2399
|
-
|
2400
|
-
|
2401
|
-
|
2402
|
-
|
2403
|
-
|
2404
|
-
|
2405
|
-
# Extract setup commands from the response
|
2406
|
-
if "setupInstructions" in data and "commands" in data["setupInstructions"]:
|
2407
|
-
commands = data["setupInstructions"]["commands"]
|
2408
|
-
print(f"✅ Successfully fetched {len(commands)} setup commands from API")
|
2409
|
-
|
2410
|
-
# Print the commands for reference
|
2411
|
-
for i, cmd in enumerate(commands, 1):
|
2412
|
-
print(f" {i}. {cmd}")
|
2433
|
+
try:
|
2434
|
+
response = requests.post(api_url, json=payload, timeout=60)
|
2435
|
+
|
2436
|
+
print(f"📥 API Response status code: {response.status_code}")
|
2437
|
+
|
2438
|
+
if response.status_code == 200:
|
2439
|
+
try:
|
2440
|
+
data = response.json()
|
2441
|
+
print(f"📄 API Response data received")
|
2413
2442
|
|
2414
|
-
|
2415
|
-
|
2416
|
-
|
2417
|
-
|
2418
|
-
|
2419
|
-
|
2420
|
-
|
2421
|
-
|
2422
|
-
|
2423
|
-
|
2424
|
-
|
2425
|
-
|
2426
|
-
|
2427
|
-
|
2428
|
-
|
2429
|
-
|
2430
|
-
|
2431
|
-
|
2432
|
-
|
2443
|
+
# Extract setup commands from the response
|
2444
|
+
if "setupInstructions" in data and "commands" in data["setupInstructions"]:
|
2445
|
+
commands = data["setupInstructions"]["commands"]
|
2446
|
+
print(f"✅ Successfully fetched {len(commands)} setup commands from API")
|
2447
|
+
|
2448
|
+
# Print the commands for reference
|
2449
|
+
for i, cmd in enumerate(commands, 1):
|
2450
|
+
print(f" {i}. {cmd}")
|
2451
|
+
|
2452
|
+
return commands
|
2453
|
+
else:
|
2454
|
+
print("⚠️ API response did not contain setupInstructions.commands field")
|
2455
|
+
print("📋 Available fields in response:")
|
2456
|
+
for key in data.keys():
|
2457
|
+
print(f" - {key}")
|
2458
|
+
# Return fallback commands
|
2459
|
+
return generate_fallback_commands(gitingest_data)
|
2460
|
+
except json.JSONDecodeError as e:
|
2461
|
+
print(f"❌ Failed to parse API response as JSON: {e}")
|
2462
|
+
print(f"Raw response: {response.text[:500]}...")
|
2463
|
+
# Return fallback commands
|
2464
|
+
return generate_fallback_commands(gitingest_data)
|
2465
|
+
elif response.status_code == 504:
|
2466
|
+
print(f"❌ API request timed out (504 Gateway Timeout)")
|
2467
|
+
print("⚠️ The server took too long to respond. Using fallback commands instead.")
|
2468
|
+
# Return fallback commands
|
2469
|
+
return generate_fallback_commands(gitingest_data)
|
2470
|
+
else:
|
2471
|
+
print(f"❌ API request failed with status code: {response.status_code}")
|
2472
|
+
print(f"Error response: {response.text[:500]}...")
|
2473
|
+
# Return fallback commands
|
2474
|
+
return generate_fallback_commands(gitingest_data)
|
2475
|
+
except requests.exceptions.Timeout:
|
2476
|
+
print("❌ API request timed out after 60 seconds")
|
2477
|
+
print("⚠️ Using fallback commands instead")
|
2478
|
+
# Return fallback commands
|
2479
|
+
return generate_fallback_commands(gitingest_data)
|
2480
|
+
except requests.exceptions.ConnectionError:
|
2481
|
+
print(f"❌ Connection error: Could not connect to {api_url}")
|
2482
|
+
print("⚠️ Using fallback commands instead")
|
2483
|
+
# Return fallback commands
|
2484
|
+
return generate_fallback_commands(gitingest_data)
|
2433
2485
|
except Exception as e:
|
2434
2486
|
print(f"❌ Error fetching setup commands from API: {e}")
|
2435
2487
|
import traceback
|
2436
2488
|
traceback.print_exc()
|
2437
|
-
|
2489
|
+
# Return fallback commands
|
2490
|
+
return generate_fallback_commands(None)
|
2438
2491
|
finally:
|
2439
2492
|
# Clean up the temporary directory
|
2440
2493
|
print(f"🧹 Cleaning up temporary directory...")
|
2441
2494
|
shutil.rmtree(temp_dir, ignore_errors=True)
|
2442
2495
|
|
2496
|
+
def generate_fallback_commands(gitingest_data):
|
2497
|
+
"""Generate fallback setup commands based on repository analysis"""
|
2498
|
+
print("\n" + "="*80)
|
2499
|
+
print("📋 GENERATING FALLBACK SETUP COMMANDS")
|
2500
|
+
print("="*80)
|
2501
|
+
print("Using basic repository analysis to generate setup commands")
|
2502
|
+
|
2503
|
+
# Default commands that work for most repositories
|
2504
|
+
default_commands = [
|
2505
|
+
"apt-get update -y",
|
2506
|
+
"apt-get install -y git curl wget",
|
2507
|
+
"pip install --upgrade pip setuptools wheel"
|
2508
|
+
]
|
2509
|
+
|
2510
|
+
# If we don't have any analysis data, return default commands
|
2511
|
+
if not gitingest_data:
|
2512
|
+
print("⚠️ No repository analysis data available. Using default commands.")
|
2513
|
+
return default_commands
|
2514
|
+
|
2515
|
+
# Extract language and technologies information
|
2516
|
+
detected_language = gitingest_data.get("system_info", {}).get("detected_language", "Unknown")
|
2517
|
+
detected_technologies = gitingest_data.get("system_info", {}).get("detected_technologies", [])
|
2518
|
+
primary_package_manager = gitingest_data.get("system_info", {}).get("primary_package_manager", "Unknown")
|
2519
|
+
|
2520
|
+
# Add language-specific commands
|
2521
|
+
language_commands = []
|
2522
|
+
|
2523
|
+
print(f"📋 Detected primary language: {detected_language}")
|
2524
|
+
print(f"📋 Detected technologies: {', '.join(detected_technologies) if detected_technologies else 'None'}")
|
2525
|
+
print(f"📋 Detected package manager: {primary_package_manager}")
|
2526
|
+
|
2527
|
+
# Python-specific commands
|
2528
|
+
if detected_language == "Python" or primary_package_manager == "pip":
|
2529
|
+
print("📦 Adding Python-specific setup commands")
|
2530
|
+
|
2531
|
+
# Check for requirements.txt
|
2532
|
+
requirements_check = [
|
2533
|
+
"if [ -f requirements.txt ]; then",
|
2534
|
+
" echo 'Installing from requirements.txt'",
|
2535
|
+
" pip install -r requirements.txt",
|
2536
|
+
"elif [ -f setup.py ]; then",
|
2537
|
+
" echo 'Installing from setup.py'",
|
2538
|
+
" pip install -e .",
|
2539
|
+
"fi"
|
2540
|
+
]
|
2541
|
+
language_commands.extend(requirements_check)
|
2542
|
+
|
2543
|
+
# Add common Python packages
|
2544
|
+
language_commands.append("pip install pytest numpy pandas matplotlib")
|
2545
|
+
|
2546
|
+
# JavaScript/Node.js specific commands
|
2547
|
+
elif detected_language in ["JavaScript", "TypeScript"] or primary_package_manager in ["npm", "yarn", "pnpm"]:
|
2548
|
+
print("📦 Adding JavaScript/Node.js-specific setup commands")
|
2549
|
+
|
2550
|
+
# Install Node.js if not available
|
2551
|
+
language_commands.append("apt-get install -y nodejs npm")
|
2552
|
+
|
2553
|
+
# Check for package.json
|
2554
|
+
package_json_check = [
|
2555
|
+
"if [ -f package.json ]; then",
|
2556
|
+
" echo 'Installing from package.json'",
|
2557
|
+
" npm install",
|
2558
|
+
"fi"
|
2559
|
+
]
|
2560
|
+
language_commands.extend(package_json_check)
|
2561
|
+
|
2562
|
+
# Java specific commands
|
2563
|
+
elif detected_language == "Java" or primary_package_manager in ["maven", "gradle"]:
|
2564
|
+
print("📦 Adding Java-specific setup commands")
|
2565
|
+
|
2566
|
+
language_commands.append("apt-get install -y openjdk-11-jdk maven gradle")
|
2567
|
+
|
2568
|
+
# Check for Maven or Gradle
|
2569
|
+
build_check = [
|
2570
|
+
"if [ -f pom.xml ]; then",
|
2571
|
+
" echo 'Building with Maven'",
|
2572
|
+
" mvn clean install -DskipTests",
|
2573
|
+
"elif [ -f build.gradle ]; then",
|
2574
|
+
" echo 'Building with Gradle'",
|
2575
|
+
" gradle build --no-daemon",
|
2576
|
+
"fi"
|
2577
|
+
]
|
2578
|
+
language_commands.extend(build_check)
|
2579
|
+
|
2580
|
+
# Go specific commands
|
2581
|
+
elif detected_language == "Go" or primary_package_manager == "go":
|
2582
|
+
print("📦 Adding Go-specific setup commands")
|
2583
|
+
|
2584
|
+
language_commands.append("apt-get install -y golang-go")
|
2585
|
+
language_commands.append("go mod tidy")
|
2586
|
+
|
2587
|
+
# Rust specific commands
|
2588
|
+
elif detected_language == "Rust" or primary_package_manager == "cargo":
|
2589
|
+
print("📦 Adding Rust-specific setup commands")
|
2590
|
+
|
2591
|
+
language_commands.append("curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y")
|
2592
|
+
language_commands.append("source $HOME/.cargo/env")
|
2593
|
+
language_commands.append("cargo build")
|
2594
|
+
|
2595
|
+
# Combine all commands
|
2596
|
+
all_commands = default_commands + language_commands
|
2597
|
+
|
2598
|
+
print("\n📋 Generated fallback setup commands:")
|
2599
|
+
for i, cmd in enumerate(all_commands, 1):
|
2600
|
+
print(f" {i}. {cmd}")
|
2601
|
+
|
2602
|
+
return all_commands
|
2603
|
+
|
2443
2604
|
def generate_basic_repo_analysis_from_url(repo_url):
|
2444
2605
|
"""Generate basic repository analysis data from a repository URL."""
|
2445
2606
|
import tempfile
|