Compare commits
3 Commits
030234c195
...
1166af05a7
| Author | SHA1 | Date |
|---|---|---|
|
|
1166af05a7 | |
|
|
3e89b30b3c | |
|
|
b4d73b7daf |
|
|
@ -68,6 +68,7 @@ Select **Yes**, then provide a source:
|
||||||
| Input Type | Example |
|
| Input Type | Example |
|
||||||
| --------------------- | ------------------------------------------------- |
|
| --------------------- | ------------------------------------------------- |
|
||||||
| HTTPS URL (any host) | `https://github.com/org/repo` |
|
| HTTPS URL (any host) | `https://github.com/org/repo` |
|
||||||
|
| HTTP URL (any host) | `http://host/org/repo` |
|
||||||
| HTTPS URL with subdir | `https://github.com/org/repo/tree/main/my-module` |
|
| HTTPS URL with subdir | `https://github.com/org/repo/tree/main/my-module` |
|
||||||
| SSH URL | `git@github.com:org/repo.git` |
|
| SSH URL | `git@github.com:org/repo.git` |
|
||||||
| Local path | `/Users/me/projects/my-module` |
|
| Local path | `/Users/me/projects/my-module` |
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ Chọn **Yes**, rồi nhập nguồn:
|
||||||
| Loại đầu vào | Ví dụ |
|
| Loại đầu vào | Ví dụ |
|
||||||
| --------------------- | ------------------------------------------------- |
|
| --------------------- | ------------------------------------------------- |
|
||||||
| HTTPS URL trên bất kỳ host nào | `https://github.com/org/repo` |
|
| HTTPS URL trên bất kỳ host nào | `https://github.com/org/repo` |
|
||||||
|
| HTTP URL trên bất kỳ host nào | `http://host/org/repo` |
|
||||||
| HTTPS URL trỏ vào một thư mục con | `https://github.com/org/repo/tree/main/my-module` |
|
| HTTPS URL trỏ vào một thư mục con | `https://github.com/org/repo/tree/main/my-module` |
|
||||||
| SSH URL | `git@github.com:org/repo.git` |
|
| SSH URL | `git@github.com:org/repo.git` |
|
||||||
| Đường dẫn cục bộ | `/Users/me/projects/my-module` |
|
| Đường dẫn cục bộ | `/Users/me/projects/my-module` |
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ Would you like to install from a custom source (Git URL or local path)?
|
||||||
| 输入类型 | 示例 |
|
| 输入类型 | 示例 |
|
||||||
| -------- | ---- |
|
| -------- | ---- |
|
||||||
| HTTPS URL(任意主机) | `https://github.com/org/repo` |
|
| HTTPS URL(任意主机) | `https://github.com/org/repo` |
|
||||||
|
| HTTP URL(任意主机) | `http://host/org/repo` |
|
||||||
| 带子目录的 HTTPS URL | `https://github.com/org/repo/tree/main/my-module` |
|
| 带子目录的 HTTPS URL | `https://github.com/org/repo/tree/main/my-module` |
|
||||||
| SSH URL | `git@github.com:org/repo.git` |
|
| SSH URL | `git@github.com:org/repo.git` |
|
||||||
| 本地路径 | `/Users/me/projects/my-module` |
|
| 本地路径 | `/Users/me/projects/my-module` |
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,9 @@ class CustomModuleManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a user-provided source input into a structured descriptor.
|
* Parse a user-provided source input into a structured descriptor.
|
||||||
* Accepts local file paths, HTTPS Git URLs, and SSH Git URLs.
|
* Accepts local file paths, HTTPS Git URLs, HTTP Git URLs, and SSH Git URLs.
|
||||||
* For HTTPS URLs with deep paths (e.g., /tree/main/subdir), extracts the subdir.
|
* For HTTPS/HTTP URLs with deep paths (e.g., /tree/main/subdir), extracts the subdir.
|
||||||
|
* The original protocol (http or https) is preserved in the returned cloneUrl.
|
||||||
*
|
*
|
||||||
* @param {string} input - URL or local file path
|
* @param {string} input - URL or local file path
|
||||||
* @returns {Object} Parsed source descriptor:
|
* @returns {Object} Parsed source descriptor:
|
||||||
|
|
@ -127,11 +128,11 @@ class CustomModuleManager {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPS URL: https://host/owner/repo[/tree/branch/subdir][.git]
|
// HTTPS/HTTP URL: https://host/owner/repo[/tree/branch/subdir][.git]
|
||||||
const httpsMatch = trimmed.match(/^https?:\/\/([^/]+)\/([^/]+)\/([^/.]+?)(?:\.git)?(\/.*)?$/);
|
const httpsMatch = trimmed.match(/^(https?):\/\/([^/]+)\/([^/]+)\/([^/.]+?)(?:\.git)?(\/.*)?$/);
|
||||||
if (httpsMatch) {
|
if (httpsMatch) {
|
||||||
const [, host, owner, repo, remainder] = httpsMatch;
|
const [, protocol, host, owner, repo, remainder] = httpsMatch;
|
||||||
const cloneUrl = `https://${host}/${owner}/${repo}`;
|
const cloneUrl = `${protocol}://${host}/${owner}/${repo}`;
|
||||||
let subdir = null;
|
let subdir = null;
|
||||||
let urlRef = null; // branch/tag extracted from /tree/<ref>/subdir
|
let urlRef = null; // branch/tag extracted from /tree/<ref>/subdir
|
||||||
|
|
||||||
|
|
@ -311,7 +312,7 @@ class CustomModuleManager {
|
||||||
/**
|
/**
|
||||||
* Clone a custom module repository to cache.
|
* Clone a custom module repository to cache.
|
||||||
* Supports any Git host (GitHub, GitLab, Bitbucket, self-hosted, etc.).
|
* Supports any Git host (GitHub, GitLab, Bitbucket, self-hosted, etc.).
|
||||||
* @param {string} sourceInput - Git URL (HTTPS or SSH)
|
* @param {string} sourceInput - Git URL (HTTPS, HTTP, or SSH)
|
||||||
* @param {Object} [options] - Clone options
|
* @param {Object} [options] - Clone options
|
||||||
* @param {boolean} [options.silent] - Suppress spinner output
|
* @param {boolean} [options.silent] - Suppress spinner output
|
||||||
* @param {boolean} [options.skipInstall] - Skip npm install (for browsing before user confirms)
|
* @param {boolean} [options.skipInstall] - Skip npm install (for browsing before user confirms)
|
||||||
|
|
|
||||||
|
|
@ -200,12 +200,15 @@ class UI {
|
||||||
actionType = options.action;
|
actionType = options.action;
|
||||||
await prompts.log.info(`Using action from command-line: ${actionType}`);
|
await prompts.log.info(`Using action from command-line: ${actionType}`);
|
||||||
} else if (options.yes) {
|
} else if (options.yes) {
|
||||||
// Default to quick-update if available, otherwise first available choice
|
// Default to quick-update if available, unless flags that require the
|
||||||
|
// full update path are present (e.g. --custom-source which re-clones
|
||||||
|
// modules at a new version — quick-update skips that entirely).
|
||||||
if (choices.length === 0) {
|
if (choices.length === 0) {
|
||||||
throw new Error('No valid actions available for this installation');
|
throw new Error('No valid actions available for this installation');
|
||||||
}
|
}
|
||||||
const hasQuickUpdate = choices.some((c) => c.value === 'quick-update');
|
const hasQuickUpdate = choices.some((c) => c.value === 'quick-update');
|
||||||
actionType = hasQuickUpdate ? 'quick-update' : choices[0].value;
|
const needsFullUpdate = !!options.customSource;
|
||||||
|
actionType = hasQuickUpdate && !needsFullUpdate ? 'quick-update' : (choices.find((c) => c.value === 'update') || choices[0]).value;
|
||||||
await prompts.log.info(`Non-interactive mode (--yes): defaulting to ${actionType}`);
|
await prompts.log.info(`Non-interactive mode (--yes): defaulting to ${actionType}`);
|
||||||
} else {
|
} else {
|
||||||
actionType = await prompts.select({
|
actionType = await prompts.select({
|
||||||
|
|
@ -241,8 +244,11 @@ class UI {
|
||||||
.map((m) => m.trim())
|
.map((m) => m.trim())
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
await prompts.log.info(`Using modules from command-line: ${selectedModules.join(', ')}`);
|
await prompts.log.info(`Using modules from command-line: ${selectedModules.join(', ')}`);
|
||||||
} else if (options.customSource) {
|
} else if (options.customSource && !options.yes) {
|
||||||
// Custom source without --modules: start with empty list (core added below)
|
// Custom source without --modules or --yes: start with empty list
|
||||||
|
// (only custom source modules + core will be installed).
|
||||||
|
// When --yes is also set, fall through to the --yes branch so all
|
||||||
|
// installed modules are included alongside the custom source modules.
|
||||||
selectedModules = [];
|
selectedModules = [];
|
||||||
} else if (options.yes) {
|
} else if (options.yes) {
|
||||||
selectedModules = await this.getDefaultModules(installedModuleIds);
|
selectedModules = await this.getDefaultModules(installedModuleIds);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue