git0 0.2.5 → 0.2.6
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/bun.lock +159 -0
- package/docs/404.html +2 -2
- package/docs/Footer/index.html +2 -2
- package/docs/assets/js/{22dd74f7.5e857962.js → 22dd74f7.040a4546.js} +1 -1
- package/docs/assets/js/4a829dc8.10d7db0a.js +1 -0
- package/docs/assets/js/{main.c71c09a5.js → main.6b27aee7.js} +2 -2
- package/docs/assets/js/{runtime~main.ef55418f.js → runtime~main.5c54c19c.js} +1 -1
- package/docs/functions/globals/index.html +18 -27
- package/docs/functions/index.html +2 -2
- package/docs/index.html +2 -2
- package/docs/lunr-index-1749612068805.json +1 -0
- package/docs/lunr-index.json +1 -1
- package/docs/search-doc-1749612068805.json +1 -0
- package/docs/search-doc.json +1 -1
- package/docs-config/.docusaurus/DONT-EDIT-THIS-FOLDER +5 -0
- package/docs-config/.docusaurus/client-manifest.json +247 -0
- package/docs-config/.docusaurus/client-modules.js +8 -0
- package/docs-config/.docusaurus/codeTranslations.json +1 -0
- package/docs-config/.docusaurus/docusaurus-lunr-search/default/__plugin.json +4 -0
- package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/__mdx-loader-dependency.json +1 -0
- package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/__plugin.json +4 -0
- package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/p/index-466.json +1 -0
- package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-functions-globals-md-4a8.json +19 -0
- package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-functions-index-md-c3a.json +19 -0
- package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-index-md-d14.json +21 -0
- package/docs-config/.docusaurus/docusaurus-plugin-content-pages/default/__plugin.json +4 -0
- package/docs-config/.docusaurus/docusaurus-plugin-google-gtag/default/__plugin.json +4 -0
- package/docs-config/.docusaurus/docusaurus.config.mjs +385 -0
- package/docs-config/.docusaurus/globalData.json +60 -0
- package/docs-config/.docusaurus/i18n.json +17 -0
- package/docs-config/.docusaurus/lunr.client.js +5 -0
- package/docs-config/.docusaurus/registry.js +14 -0
- package/docs-config/.docusaurus/routes.js +55 -0
- package/docs-config/.docusaurus/routesChunkNames.json +41 -0
- package/docs-config/.docusaurus/site-metadata.json +51 -0
- package/docs-config/.docusaurus/site-storage.json +4 -0
- package/docs-config/bun.lock +6139 -0
- package/docs-config/config/customize-docs.js +1 -1
- package/docs-config/src/functions/globals.md +25 -79
- package/docs-config/tsconfig.json +1 -1
- package/package.json +10 -7
- package/src/git0.js +380 -0
- package/src/github-api.js +473 -0
- package/docs/assets/js/4a829dc8.728a4445.js +0 -1
- package/docs/lunr-index-1749601667754.json +0 -1
- package/docs/search-doc-1749601667754.json +0 -1
- package/docs-config/tailwind.config.js +0 -13
- package/git0.js +0 -646
- /package/docs/assets/js/{main.c71c09a5.js.LICENSE.txt → main.6b27aee7.js.LICENSE.txt} +0 -0
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
typedocFolders: [
|
|
5
5
|
{
|
|
6
6
|
id: "functions",
|
|
7
|
-
entryPoints: ["../git0.js"], // also remember to set in ../tsconfig.json {entryPoints:[...]}
|
|
7
|
+
entryPoints: ["../src/git0.js"], // also remember to set in ../tsconfig.json {entryPoints:[...]}
|
|
8
8
|
},
|
|
9
9
|
],
|
|
10
10
|
showEditsOnGitHub: true,
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
##
|
|
1
|
+
## installDependencies()
|
|
2
2
|
|
|
3
3
|
```ts
|
|
4
|
-
function
|
|
4
|
+
function installDependencies(targetDir: string): Promise<void>;
|
|
5
5
|
```
|
|
6
6
|
|
|
7
|
-
Defined in:
|
|
7
|
+
Defined in: git0.js:208
|
|
8
|
+
|
|
9
|
+
Automatically detects project type and installs dependencies
|
|
10
|
+
Supports Node.js, Docker, Python, Rust, and Go projects
|
|
8
11
|
|
|
9
12
|
### Parameters
|
|
10
13
|
|
|
@@ -13,57 +16,24 @@ Defined in: [git0.js:506](https://github.com/vtempest/git0/blob/f5565c601a25c627
|
|
|
13
16
|
<tr>
|
|
14
17
|
<th>Parameter</th>
|
|
15
18
|
<th>Type</th>
|
|
19
|
+
<th>Description</th>
|
|
16
20
|
</tr>
|
|
17
21
|
</thead>
|
|
18
22
|
<tbody>
|
|
19
23
|
<tr>
|
|
20
24
|
<td>
|
|
21
25
|
|
|
22
|
-
`
|
|
26
|
+
`targetDir`
|
|
23
27
|
|
|
24
28
|
</td>
|
|
25
29
|
<td>
|
|
26
30
|
|
|
27
|
-
`
|
|
28
|
-
|
|
29
|
-
</td>
|
|
30
|
-
</tr>
|
|
31
|
-
</tbody>
|
|
32
|
-
</table>
|
|
33
|
-
|
|
34
|
-
### Returns
|
|
35
|
-
|
|
36
|
-
`Promise`<`void`>
|
|
37
|
-
|
|
38
|
-
***
|
|
39
|
-
|
|
40
|
-
## installDependencies()
|
|
41
|
-
|
|
42
|
-
```ts
|
|
43
|
-
function installDependencies(targetDir: any): Promise<void>;
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Defined in: [git0.js:397](https://github.com/vtempest/git0/blob/f5565c601a25c627e02f22dfda1f72982fbcaeae/git0.js#L397)
|
|
47
|
-
|
|
48
|
-
### Parameters
|
|
49
|
-
|
|
50
|
-
<table>
|
|
51
|
-
<thead>
|
|
52
|
-
<tr>
|
|
53
|
-
<th>Parameter</th>
|
|
54
|
-
<th>Type</th>
|
|
55
|
-
</tr>
|
|
56
|
-
</thead>
|
|
57
|
-
<tbody>
|
|
58
|
-
<tr>
|
|
59
|
-
<td>
|
|
60
|
-
|
|
61
|
-
`targetDir`
|
|
31
|
+
`string`
|
|
62
32
|
|
|
63
33
|
</td>
|
|
64
34
|
<td>
|
|
65
35
|
|
|
66
|
-
|
|
36
|
+
Path to the project directory
|
|
67
37
|
|
|
68
38
|
</td>
|
|
69
39
|
</tr>
|
|
@@ -74,15 +44,22 @@ Defined in: [git0.js:397](https://github.com/vtempest/git0/blob/f5565c601a25c627
|
|
|
74
44
|
|
|
75
45
|
`Promise`<`void`>
|
|
76
46
|
|
|
47
|
+
### Export
|
|
48
|
+
|
|
49
|
+
### Async
|
|
50
|
+
|
|
77
51
|
***
|
|
78
52
|
|
|
79
53
|
## openInIDE()
|
|
80
54
|
|
|
81
55
|
```ts
|
|
82
|
-
function openInIDE(targetDir:
|
|
56
|
+
function openInIDE(targetDir: string): void;
|
|
83
57
|
```
|
|
84
58
|
|
|
85
|
-
Defined in:
|
|
59
|
+
Defined in: git0.js:158
|
|
60
|
+
|
|
61
|
+
Opens a directory in the first available IDE/editor
|
|
62
|
+
Also attempts to open a README or package.json file after 3 seconds
|
|
86
63
|
|
|
87
64
|
### Parameters
|
|
88
65
|
|
|
@@ -91,6 +68,7 @@ Defined in: [git0.js:354](https://github.com/vtempest/git0/blob/f5565c601a25c627
|
|
|
91
68
|
<tr>
|
|
92
69
|
<th>Parameter</th>
|
|
93
70
|
<th>Type</th>
|
|
71
|
+
<th>Description</th>
|
|
94
72
|
</tr>
|
|
95
73
|
</thead>
|
|
96
74
|
<tbody>
|
|
@@ -102,46 +80,12 @@ Defined in: [git0.js:354](https://github.com/vtempest/git0/blob/f5565c601a25c627
|
|
|
102
80
|
</td>
|
|
103
81
|
<td>
|
|
104
82
|
|
|
105
|
-
`
|
|
106
|
-
|
|
107
|
-
</td>
|
|
108
|
-
</tr>
|
|
109
|
-
</tbody>
|
|
110
|
-
</table>
|
|
111
|
-
|
|
112
|
-
### Returns
|
|
113
|
-
|
|
114
|
-
`void`
|
|
115
|
-
|
|
116
|
-
***
|
|
117
|
-
|
|
118
|
-
## searchRepositories()
|
|
119
|
-
|
|
120
|
-
```ts
|
|
121
|
-
function searchRepositories(query: any): Promise<any>;
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
Defined in: [git0.js:467](https://github.com/vtempest/git0/blob/f5565c601a25c627e02f22dfda1f72982fbcaeae/git0.js#L467)
|
|
125
|
-
|
|
126
|
-
### Parameters
|
|
127
|
-
|
|
128
|
-
<table>
|
|
129
|
-
<thead>
|
|
130
|
-
<tr>
|
|
131
|
-
<th>Parameter</th>
|
|
132
|
-
<th>Type</th>
|
|
133
|
-
</tr>
|
|
134
|
-
</thead>
|
|
135
|
-
<tbody>
|
|
136
|
-
<tr>
|
|
137
|
-
<td>
|
|
138
|
-
|
|
139
|
-
`query`
|
|
83
|
+
`string`
|
|
140
84
|
|
|
141
85
|
</td>
|
|
142
86
|
<td>
|
|
143
87
|
|
|
144
|
-
|
|
88
|
+
Path to the directory to open
|
|
145
89
|
|
|
146
90
|
</td>
|
|
147
91
|
</tr>
|
|
@@ -150,4 +94,6 @@ Defined in: [git0.js:467](https://github.com/vtempest/git0/blob/f5565c601a25c627
|
|
|
150
94
|
|
|
151
95
|
### Returns
|
|
152
96
|
|
|
153
|
-
`
|
|
97
|
+
`void`
|
|
98
|
+
|
|
99
|
+
### Export
|
package/package.json
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git0",
|
|
3
3
|
"description": "CLI tool to search GitHub repositories, download source & releases for your system, and instantly set up, then install dependencies and open code editor.",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.6",
|
|
5
5
|
"author": "vtempest",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"axios": "^1.9.0",
|
|
8
7
|
"chalk": "^5.4.1",
|
|
9
8
|
"git-url-parse": "^16.1.0",
|
|
10
|
-
"grab-api.js": "^0.9.
|
|
9
|
+
"grab-api.js": "^0.9.124",
|
|
11
10
|
"inquirer": "^12.6.3",
|
|
12
|
-
"
|
|
11
|
+
"ora": "^8.2.0",
|
|
13
12
|
"tar": "^7.4.3"
|
|
14
13
|
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": "./src/github-api.js"
|
|
16
|
+
},
|
|
15
17
|
"bin": {
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
+
"g": "./src/git0.js",
|
|
19
|
+
"gg": "./src/git0.js",
|
|
20
|
+
"git0": "./src/git0.js"
|
|
18
21
|
},
|
|
19
22
|
"keywords": [
|
|
20
23
|
"github",
|
|
@@ -24,7 +27,7 @@
|
|
|
24
27
|
"license": "MIT",
|
|
25
28
|
"scripts": {
|
|
26
29
|
"docs": "cd docs-config && bun run build:docs",
|
|
27
|
-
"demo": "bun git0.js react template",
|
|
30
|
+
"demo": "bun src/git0.js react template",
|
|
28
31
|
"publish:npm": "npm version patch && npm publish --access public"
|
|
29
32
|
},
|
|
30
33
|
"type": "module"
|
package/src/git0.js
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { execSync, spawn } from 'child_process';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import ora from ora;
|
|
8
|
+
import GithubAPI from './github-api'
|
|
9
|
+
|
|
10
|
+
const Github = new GithubAPI({ debug: false })
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Prints the git0 ASCII logo to the console
|
|
14
|
+
*/
|
|
15
|
+
function printLogo() {
|
|
16
|
+
console.log(chalk.cyan(` ___
|
|
17
|
+
__ _(_)‾|_ / _ \\
|
|
18
|
+
/ _ | | __| | | |
|
|
19
|
+
| (_| | | |_| |_| |
|
|
20
|
+
\\__, |_|\\__|\\___/
|
|
21
|
+
|___/`))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Shows an interactive menu for selecting packages from GitHub releases
|
|
26
|
+
* Organizes packages by platform and highlights the user's current platform
|
|
27
|
+
* @param {Object} selectedRepo - The selected repository object containing release information
|
|
28
|
+
* @param {Array} selectedRepo.allReleases - Array of release objects
|
|
29
|
+
* @param {string} selectedRepo.allReleases[].tag_name - Release tag name
|
|
30
|
+
* @param {Object} selectedRepo.allReleases[].platformAssets - Assets organized by platform
|
|
31
|
+
* @returns {Promise<void>}
|
|
32
|
+
*/
|
|
33
|
+
async function showPackageMenu(selectedRepo) {
|
|
34
|
+
const currentPlatform = Github.getCurrentPlatform();
|
|
35
|
+
const releaseChoices = [];
|
|
36
|
+
const limitReleases = 2;
|
|
37
|
+
|
|
38
|
+
// Add section headers and organize by platform
|
|
39
|
+
selectedRepo.allReleases.slice(0, limitReleases).forEach(release => {
|
|
40
|
+
const platforms = ['windows', 'macos', 'linux', 'universal'];
|
|
41
|
+
|
|
42
|
+
platforms.forEach(platform => {
|
|
43
|
+
const assets = release.platformAssets[platform];
|
|
44
|
+
if (assets.length > 0) {
|
|
45
|
+
// Add platform header
|
|
46
|
+
const platformEmoji = {
|
|
47
|
+
windows: '🪟',
|
|
48
|
+
macos: '🍎',
|
|
49
|
+
linux: '🐧',
|
|
50
|
+
universal: '🌐'
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const platformName = {
|
|
54
|
+
windows: 'Windows',
|
|
55
|
+
macos: 'macOS',
|
|
56
|
+
linux: 'Linux',
|
|
57
|
+
universal: 'Universal'
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const isCurrentPlatform = platform === currentPlatform.os || platform === 'universal';
|
|
61
|
+
const platformHeader = isCurrentPlatform
|
|
62
|
+
? chalk.green(`${platformEmoji[platform]} ${platformName[platform]} (Your Platform)`)
|
|
63
|
+
: chalk.gray(`${platformEmoji[platform]} ${platformName[platform]}`);
|
|
64
|
+
|
|
65
|
+
// Add separator if not first platform in this release
|
|
66
|
+
const needsSeparator = releaseChoices.length > 0 &&
|
|
67
|
+
!releaseChoices[releaseChoices.length - 1].name.includes('────');
|
|
68
|
+
|
|
69
|
+
if (needsSeparator) {
|
|
70
|
+
releaseChoices.push({
|
|
71
|
+
name: chalk.gray('────────────────────────────────'),
|
|
72
|
+
disabled: true
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
releaseChoices.push({
|
|
77
|
+
name: `${chalk.bold(release.tag_name)} - ${platformHeader}`,
|
|
78
|
+
disabled: true
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Add assets for this platform
|
|
82
|
+
assets.forEach(asset => {
|
|
83
|
+
const sizeStr = (asset.size / 1024 / 1024).toFixed(2);
|
|
84
|
+
const archInfo = asset.detectedArch !== 'unknown' && asset.detectedArch !== 'universal'
|
|
85
|
+
? chalk.cyan(`[${asset.detectedArch}]`)
|
|
86
|
+
: '';
|
|
87
|
+
|
|
88
|
+
const highlight = isCurrentPlatform ? chalk.white : chalk.gray;
|
|
89
|
+
|
|
90
|
+
releaseChoices.push({
|
|
91
|
+
name: ` ${highlight(`${asset.name} ${archInfo} (${sizeStr} MB)`)}`,
|
|
92
|
+
value: { release, asset }
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
if (releaseChoices.filter(choice => !choice.disabled).length === 0) {
|
|
100
|
+
log(chalk.yellow('No packages found for download.'));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const { selectedPackage } = await inquirer.prompt({
|
|
105
|
+
type: 'list',
|
|
106
|
+
name: 'selectedPackage',
|
|
107
|
+
message: 'Select a package to download:',
|
|
108
|
+
choices: releaseChoices,
|
|
109
|
+
pageSize: 15
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const downloadDir = path.resolve(process.cwd());
|
|
113
|
+
fs.mkdirSync(downloadDir, { recursive: true });
|
|
114
|
+
|
|
115
|
+
const downloadPath = path.join(downloadDir, asset.name);
|
|
116
|
+
await Github.downloadPackage(selectedPackage.asset.browser_download_url, downloadPath);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Detects available IDE/editor commands on the system
|
|
121
|
+
* Checks for popular code editors in priority order
|
|
122
|
+
* @returns {Object|null} IDE object with name and command, or null if none found
|
|
123
|
+
* @returns {string} returns.name - Human-readable name of the IDE
|
|
124
|
+
* @returns {string} returns.cmd - Command to execute the IDE
|
|
125
|
+
*/
|
|
126
|
+
function getIdeCommand() {
|
|
127
|
+
const ides = [
|
|
128
|
+
{ name: 'Cursor', cmd: 'cursor' },
|
|
129
|
+
{ name: 'Windsurf', cmd: 'windsurf' },
|
|
130
|
+
{ name: 'VSCode', cmd: 'code' },
|
|
131
|
+
{ name: 'Code Server', cmd: 'code-server' },
|
|
132
|
+
{ name: 'Neovim', cmd: 'nvim' },
|
|
133
|
+
{ name: 'Webstorm', cmd: 'webstorm' }
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
for (const ide of ides) {
|
|
137
|
+
try {
|
|
138
|
+
execSync(
|
|
139
|
+
process.platform === 'win32'
|
|
140
|
+
? `where ${ide.cmd}`
|
|
141
|
+
: `command -v ${ide.cmd}`,
|
|
142
|
+
{ stdio: 'ignore' }
|
|
143
|
+
);
|
|
144
|
+
return ide;
|
|
145
|
+
} catch (error) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Opens a directory in the first available IDE/editor
|
|
154
|
+
* Also attempts to open a README or package.json file after 3 seconds
|
|
155
|
+
* @export
|
|
156
|
+
* @param {string} targetDir - Path to the directory to open
|
|
157
|
+
*/
|
|
158
|
+
export function openInIDE(targetDir) {
|
|
159
|
+
const ide = getIdeCommand();
|
|
160
|
+
if (!ide) {
|
|
161
|
+
log(chalk.yellow('⚠️ No supported IDE found'));
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
const args = ide.cmd === 'code-server'
|
|
167
|
+
? [targetDir, '--open']
|
|
168
|
+
: [targetDir];
|
|
169
|
+
|
|
170
|
+
spawn(ide.cmd, args, {
|
|
171
|
+
detached: true,
|
|
172
|
+
stdio: 'ignore',
|
|
173
|
+
shell: process.platform === 'win32'
|
|
174
|
+
}).unref();
|
|
175
|
+
|
|
176
|
+
// open readme after 3 seconds
|
|
177
|
+
setTimeout(() => {
|
|
178
|
+
|
|
179
|
+
const readme = fs.existsSync('./readme.md') ? './readme.md' :
|
|
180
|
+
fs.existsSync('./Readme.md') ? './Readme.md' :
|
|
181
|
+
fs.existsSync('./README.md') ? './README.md' :
|
|
182
|
+
fs.existsSync('./package.json') ? './package.json' :
|
|
183
|
+
null;
|
|
184
|
+
|
|
185
|
+
if (readme)
|
|
186
|
+
spawn(ide.cmd, ide.cmd === 'code-server'
|
|
187
|
+
? [readme, '--open']
|
|
188
|
+
: [readme], {
|
|
189
|
+
detached: true,
|
|
190
|
+
stdio: 'ignore',
|
|
191
|
+
shell: process.platform === 'win32'
|
|
192
|
+
}).unref();
|
|
193
|
+
}, 3000);
|
|
194
|
+
|
|
195
|
+
log(chalk.green(`🚀 Opening ${path.basename(targetDir)} in ${ide.name}`));
|
|
196
|
+
} catch (error) {
|
|
197
|
+
// console.error(chalk.red(`❌ Failed to open ${ide.name}:`), error.message);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Automatically detects project type and installs dependencies
|
|
203
|
+
* Supports Node.js, Docker, Python, Rust, and Go projects
|
|
204
|
+
* @export
|
|
205
|
+
* @async
|
|
206
|
+
* @param {string} targetDir - Path to the project directory
|
|
207
|
+
*/
|
|
208
|
+
export async function installDependencies(targetDir) {
|
|
209
|
+
process.chdir(targetDir);
|
|
210
|
+
|
|
211
|
+
// Project type detection
|
|
212
|
+
const detectors = {
|
|
213
|
+
nodejs: () => fs.existsSync('package.json'),
|
|
214
|
+
docker: () => fs.existsSync('Dockerfile'),
|
|
215
|
+
python: () => fs.existsSync('requirements.txt') || fs.existsSync('setup.py'),
|
|
216
|
+
rust: () => fs.existsSync('Cargo.toml'),
|
|
217
|
+
go: () => fs.existsSync('go.mod')
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
// Install commands for each project type
|
|
221
|
+
const installers = {
|
|
222
|
+
nodejs: () => {
|
|
223
|
+
try {
|
|
224
|
+
execSync(
|
|
225
|
+
process.platform === 'win32'
|
|
226
|
+
? `where bun`
|
|
227
|
+
: `command -v bun`,
|
|
228
|
+
{ stdio: 'ignore' }
|
|
229
|
+
);
|
|
230
|
+
exec('bun install');
|
|
231
|
+
exec('bun run dev; bun run start');
|
|
232
|
+
} catch (error) {
|
|
233
|
+
exec('npm install');
|
|
234
|
+
exec('npm run dev; npm run start');
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
docker: () => {
|
|
238
|
+
if (fs.existsSync('docker-compose.yml')) {
|
|
239
|
+
exec('sudo docker-compose up -d');
|
|
240
|
+
} else if (fs.existsSync('Dockerfile')) {
|
|
241
|
+
exec('sudo docker build -t project .');
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
python: () => {
|
|
245
|
+
exec('python -m venv .venv');
|
|
246
|
+
exec('source .venv/bin/activate');
|
|
247
|
+
|
|
248
|
+
if (fs.existsSync('requirements.txt')) {
|
|
249
|
+
exec('pip install -r requirements.txt');
|
|
250
|
+
}
|
|
251
|
+
if (fs.existsSync('setup.py')) {
|
|
252
|
+
exec('pip install -e .');
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
rust: () => exec('cargo build'),
|
|
256
|
+
go: () => exec('go mod tidy')
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
// Run detections and installations
|
|
260
|
+
Object.entries(detectors).forEach(([name, check]) => {
|
|
261
|
+
if (check()) {
|
|
262
|
+
// log(chalk.yellow(`⚙️ Detected ${name} project`));
|
|
263
|
+
installers[name]?.();
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Executes a shell command with error handling
|
|
270
|
+
* @param {string} cmd - Command to execute
|
|
271
|
+
* @param {boolean} [showError=false] - Whether to display error messages
|
|
272
|
+
*/
|
|
273
|
+
function exec(cmd, showError = false) {
|
|
274
|
+
try {
|
|
275
|
+
execSync(cmd, { stdio: 'inherit' });
|
|
276
|
+
} catch (error) {
|
|
277
|
+
if (showError)
|
|
278
|
+
console.error(chalk.red(`❌ Failed: ${cmd}`));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Downloads a GitHub repository and sets it up for development
|
|
284
|
+
* Opens the project in an IDE and installs dependencies automatically
|
|
285
|
+
* @async
|
|
286
|
+
* @param {string} repo - Repository URL or identifier
|
|
287
|
+
* @param {string|null} [folderPath=null] - Optional custom folder path for extraction
|
|
288
|
+
*/
|
|
289
|
+
async function downloadRepoAndSetup(repo, folderPath = null) {
|
|
290
|
+
|
|
291
|
+
printLogo()
|
|
292
|
+
|
|
293
|
+
var extractPath = await Github.downloadRepo(repo, folderPath)
|
|
294
|
+
|
|
295
|
+
setTimeout(() => {
|
|
296
|
+
openInIDE(extractPath);
|
|
297
|
+
}, 500);
|
|
298
|
+
installDependencies(extractPath);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Main CLI function that handles argument parsing and repository selection
|
|
303
|
+
* Supports both download of direct GitHub URLs and search queries
|
|
304
|
+
* @async
|
|
305
|
+
* @throws {Error} When no search query is provided or no repositories are found
|
|
306
|
+
*/
|
|
307
|
+
async function main() {
|
|
308
|
+
|
|
309
|
+
printLogo()
|
|
310
|
+
const args = process.argv.slice(2);
|
|
311
|
+
if (!args.length) {
|
|
312
|
+
log(chalk.yellow('Usage: git0 <search-query>'));
|
|
313
|
+
process.exit(1);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const query = args.join(' ');
|
|
317
|
+
// Try parsing as a GitHub URL or shorthand
|
|
318
|
+
let parsed = Github.parseURL(query)
|
|
319
|
+
if (parsed && parsed.owner && parsed.name) {
|
|
320
|
+
if (typeof args[1] !== 'undefined')
|
|
321
|
+
await downloadRepoAndSetup(parsed.href, args[1]);
|
|
322
|
+
else
|
|
323
|
+
await downloadRepoAndSetup(parsed.href);
|
|
324
|
+
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const results = await Github.searchRepositories(query);
|
|
329
|
+
|
|
330
|
+
if (!results || !results.length) {
|
|
331
|
+
log(chalk.yellow('No repositories found'));
|
|
332
|
+
process.exit(1);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const { selectedRepo } = await inquirer.prompt({
|
|
336
|
+
type: 'list',
|
|
337
|
+
name: 'selectedRepo',
|
|
338
|
+
message: 'Select a repository to download:',
|
|
339
|
+
choices: results.map(repo => {
|
|
340
|
+
const packageInfo = repo.hasCompatibleReleases
|
|
341
|
+
? chalk.green(' 📦 Packages available')
|
|
342
|
+
: repo.hasReleases
|
|
343
|
+
? chalk.yellow(' 📦 Packages (other platforms)')
|
|
344
|
+
: '';
|
|
345
|
+
|
|
346
|
+
return {
|
|
347
|
+
name: `${chalk.bold(repo.full_name)} - ${chalk.gray(repo.description || 'No description')}
|
|
348
|
+
${chalk.yellow(`★ ${repo.stargazers_count}`)} | ${chalk.blue(repo.language || 'Unknown')}${packageInfo}`,
|
|
349
|
+
value: repo
|
|
350
|
+
};
|
|
351
|
+
})
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
// If the selected repo has any releases, show download options
|
|
355
|
+
if (selectedRepo.hasReleases || selectedRepo.hasCompatibleReleases) {
|
|
356
|
+
const { downloadChoice } = await inquirer.prompt({
|
|
357
|
+
type: 'list',
|
|
358
|
+
name: 'downloadChoice',
|
|
359
|
+
message: 'This repository has downloadable packages. What would you like to do?',
|
|
360
|
+
choices: [
|
|
361
|
+
{ name: '📦 Download package/binary', value: 'package' },
|
|
362
|
+
{ name: '📂 Download source code', value: 'source' },
|
|
363
|
+
{ name: '📦📂 Download both package and source', value: 'both' }
|
|
364
|
+
]
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
if (downloadChoice === 'package' || downloadChoice === 'both') {
|
|
368
|
+
await showPackageMenu(selectedRepo);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (downloadChoice === 'source' || downloadChoice === 'both') {
|
|
372
|
+
await downloadRepoAndSetup(selectedRepo.url);
|
|
373
|
+
}
|
|
374
|
+
} else {
|
|
375
|
+
// No packages, just download source
|
|
376
|
+
await downloadRepoAndSetup(selectedRepo.url);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
main();
|