yllaw 1.0.0 → 1.2.0
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/README.md +33 -1
- package/bin/yllaw.js +10 -2
- package/package.json +1 -1
- package/src/installer.js +72 -12
package/README.md
CHANGED
|
@@ -15,10 +15,15 @@ npm install -g yllaw
|
|
|
15
15
|
```bash
|
|
16
16
|
# 安装所有包(Wally + Git)
|
|
17
17
|
yllaw install
|
|
18
|
+
yllaw # install 是默认命令,可省略
|
|
18
19
|
|
|
19
20
|
# 只安装 Git 包,跳过 Wally
|
|
20
|
-
yllaw install --skip-wally
|
|
21
21
|
yllaw install -s
|
|
22
|
+
yllaw -s # 等同于 yllaw install -s
|
|
23
|
+
|
|
24
|
+
# 开发模式:从同级目录安装(用于本地开发测试)
|
|
25
|
+
yllaw install -d
|
|
26
|
+
yllaw -d -s # 等同于 yllaw install -d -s
|
|
22
27
|
|
|
23
28
|
# 强制更新所有 Git 包
|
|
24
29
|
yllaw update
|
|
@@ -30,6 +35,32 @@ yllaw install --config my-wally.toml
|
|
|
30
35
|
yllaw install --output Packages
|
|
31
36
|
```
|
|
32
37
|
|
|
38
|
+
> **提示**: `install` 是默认命令,直接使用 `yllaw -s -d` 等同于 `yllaw install -s -d`
|
|
39
|
+
|
|
40
|
+
## 开发模式 (--dev)
|
|
41
|
+
|
|
42
|
+
当你在本地开发一个包,想要在另一个项目中测试时,使用 `--dev` 模式:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
C:\Workspace\
|
|
46
|
+
├── my-game/ ← 当前项目
|
|
47
|
+
│ └── wally.toml ← MMS = "...mms-matchmaking.git@1.1.0"
|
|
48
|
+
└── mms-matchmaking/ ← 同级目录
|
|
49
|
+
└── MMS/
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cd my-game
|
|
54
|
+
yllaw install -d -s
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
yllaw 会自动检测 `mms-matchmaking` 在同级目录存在,直接从本地复制,而不是从 Git 克隆。
|
|
58
|
+
|
|
59
|
+
这样你可以:
|
|
60
|
+
1. 修改 `mms-matchmaking` 中的代码
|
|
61
|
+
2. 运行 `yllaw install -d -s` 快速同步到测试项目
|
|
62
|
+
3. 无需提交、推送、更新版本号
|
|
63
|
+
|
|
33
64
|
## 配置
|
|
34
65
|
|
|
35
66
|
在项目根目录创建 `wally.toml`:
|
|
@@ -113,6 +144,7 @@ yllaw **补充** Wally,而不是替代:
|
|
|
113
144
|
| 选项 | 说明 | 默认值 |
|
|
114
145
|
|------|------|--------|
|
|
115
146
|
| `-s, --skip-wally` | 跳过 Wally | false |
|
|
147
|
+
| `-d, --dev` | 开发模式:优先从同级目录安装 | false |
|
|
116
148
|
| `-c, --config <path>` | 配置文件路径 | `wally.toml` |
|
|
117
149
|
| `-o, --output <dir>` | 输出目录 | `Packages` |
|
|
118
150
|
|
package/bin/yllaw.js
CHANGED
|
@@ -13,6 +13,7 @@ program
|
|
|
13
13
|
.command('install')
|
|
14
14
|
.description('Install packages from wally.toml')
|
|
15
15
|
.option('-s, --skip-wally', 'Skip wally install, only install git packages')
|
|
16
|
+
.option('-d, --dev', 'Dev mode: install from local sibling directories if available')
|
|
16
17
|
.option('-c, --config <path>', 'Path to wally.toml', 'wally.toml')
|
|
17
18
|
.option('-o, --output <dir>', 'Output directory for packages', 'Packages')
|
|
18
19
|
.action(async (options) => {
|
|
@@ -28,6 +29,7 @@ program
|
|
|
28
29
|
.command('update')
|
|
29
30
|
.description('Update all git packages to latest version (re-clone)')
|
|
30
31
|
.option('-s, --skip-wally', 'Skip wally install')
|
|
32
|
+
.option('-d, --dev', 'Dev mode: install from local sibling directories if available')
|
|
31
33
|
.option('-c, --config <path>', 'Path to wally.toml', 'wally.toml')
|
|
32
34
|
.option('-o, --output <dir>', 'Output directory for packages', 'Packages')
|
|
33
35
|
.action(async (options) => {
|
|
@@ -40,8 +42,14 @@ program
|
|
|
40
42
|
});
|
|
41
43
|
|
|
42
44
|
// Default command: install
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
// If no known command is provided, insert 'install' as the default
|
|
46
|
+
const knownCommands = ['install', 'update', 'help', '-h', '--help', '-V', '--version'];
|
|
47
|
+
const args = process.argv.slice(2);
|
|
48
|
+
const firstNonOption = args.find(arg => !arg.startsWith('-'));
|
|
49
|
+
|
|
50
|
+
if (!firstNonOption || !knownCommands.includes(firstNonOption)) {
|
|
51
|
+
// Insert 'install' after 'node' and 'yllaw'
|
|
52
|
+
process.argv.splice(2, 0, 'install');
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
program.parse();
|
package/package.json
CHANGED
package/src/installer.js
CHANGED
|
@@ -34,20 +34,26 @@ async function runWally() {
|
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Parse git spec: "https://example.com/repo.git@version"
|
|
37
|
-
* @returns {{ url: string, ref: string }}
|
|
37
|
+
* @returns {{ url: string, ref: string, repoName: string }}
|
|
38
38
|
*/
|
|
39
39
|
function parseGitSpec(spec) {
|
|
40
40
|
const gitAtIndex = spec.lastIndexOf('.git@');
|
|
41
|
+
let url, ref;
|
|
42
|
+
|
|
41
43
|
if (gitAtIndex > 0) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
url = spec.substring(0, gitAtIndex + 4);
|
|
45
|
+
ref = spec.substring(gitAtIndex + 5);
|
|
46
|
+
} else {
|
|
47
|
+
url = spec;
|
|
48
|
+
ref = 'main';
|
|
46
49
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
|
|
51
|
+
// Extract repo name from URL
|
|
52
|
+
// e.g., "https://gitlab.example.com/group/mms-matchmaking.git" -> "mms-matchmaking"
|
|
53
|
+
const repoMatch = url.match(/\/([^\/]+)\.git$/);
|
|
54
|
+
const repoName = repoMatch ? repoMatch[1] : null;
|
|
55
|
+
|
|
56
|
+
return { url, ref, repoName };
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
/**
|
|
@@ -83,6 +89,47 @@ async function findModuleDir(searchDir) {
|
|
|
83
89
|
return null;
|
|
84
90
|
}
|
|
85
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Try to install from local sibling directory (dev mode)
|
|
94
|
+
* @returns {boolean} true if installed from local
|
|
95
|
+
*/
|
|
96
|
+
async function tryInstallFromLocal(name, spec, outputDir, parentDir) {
|
|
97
|
+
const { repoName } = parseGitSpec(spec);
|
|
98
|
+
|
|
99
|
+
if (!repoName) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Check if sibling directory exists
|
|
104
|
+
const localRepoDir = path.join(parentDir, repoName);
|
|
105
|
+
|
|
106
|
+
if (!await fs.pathExists(localRepoDir)) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
log.info(`[DEV] Found local: ${localRepoDir}`);
|
|
111
|
+
|
|
112
|
+
// Find module directory in local repo
|
|
113
|
+
const moduleDir = await findModuleDir(localRepoDir);
|
|
114
|
+
|
|
115
|
+
if (!moduleDir) {
|
|
116
|
+
log.warn(`[DEV] No init.luau found in ${localRepoDir}, falling back to git`);
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const target = path.join(outputDir, name);
|
|
121
|
+
|
|
122
|
+
// Copy to output
|
|
123
|
+
await fs.remove(target);
|
|
124
|
+
await fs.copy(moduleDir, target);
|
|
125
|
+
|
|
126
|
+
// Clean up .git if copied
|
|
127
|
+
await fs.remove(path.join(target, '.git'));
|
|
128
|
+
|
|
129
|
+
log.ok(`[DEV] ${name} <- ${moduleDir}`);
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
|
|
86
133
|
/**
|
|
87
134
|
* Install a single git package
|
|
88
135
|
*/
|
|
@@ -136,10 +183,11 @@ async function installGitPackage(name, spec, outputDir, tempDir) {
|
|
|
136
183
|
* Main install function
|
|
137
184
|
*/
|
|
138
185
|
async function install(options) {
|
|
139
|
-
const { config, output, skipWally, force } = options;
|
|
186
|
+
const { config, output, skipWally, force, dev } = options;
|
|
140
187
|
const configPath = path.resolve(config);
|
|
141
188
|
const outputDir = path.resolve(output);
|
|
142
189
|
const tempDir = path.join(process.cwd(), '.yllaw_temp');
|
|
190
|
+
const parentDir = path.dirname(process.cwd()); // Parent directory for dev mode
|
|
143
191
|
|
|
144
192
|
// Check config exists
|
|
145
193
|
if (!await fs.pathExists(configPath)) {
|
|
@@ -181,17 +229,29 @@ async function install(options) {
|
|
|
181
229
|
if (packages.length === 0) {
|
|
182
230
|
log.info('No git dependencies found');
|
|
183
231
|
} else {
|
|
232
|
+
if (dev) {
|
|
233
|
+
log.info(`[DEV MODE] Looking for packages in: ${parentDir}`);
|
|
234
|
+
}
|
|
184
235
|
log.info(`Found ${packages.length} git package(s)`);
|
|
185
236
|
|
|
186
237
|
for (const [name, spec] of packages) {
|
|
187
238
|
const target = path.join(outputDir, name);
|
|
188
239
|
|
|
189
|
-
// Skip if exists and not forcing update
|
|
190
|
-
if (!force && await fs.pathExists(target)) {
|
|
240
|
+
// Skip if exists and not forcing update (unless dev mode, always update in dev)
|
|
241
|
+
if (!force && !dev && await fs.pathExists(target)) {
|
|
191
242
|
log.info(`${name} already exists, skipping (use 'yllaw update' to force)`);
|
|
192
243
|
continue;
|
|
193
244
|
}
|
|
194
245
|
|
|
246
|
+
// Dev mode: try local first
|
|
247
|
+
if (dev) {
|
|
248
|
+
const installedFromLocal = await tryInstallFromLocal(name, spec, outputDir, parentDir);
|
|
249
|
+
if (installedFromLocal) {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
log.info(`[DEV] ${name} not found locally, using git`);
|
|
253
|
+
}
|
|
254
|
+
|
|
195
255
|
await installGitPackage(name, spec, outputDir, tempDir);
|
|
196
256
|
}
|
|
197
257
|
}
|