modpack-lock 0.1.0 → 0.1.1
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 +8 -11
- package/index.js +105 -13
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -41,6 +41,13 @@ Navigate to your Minecraft profile directory (the folder containing `mods`, `res
|
|
|
41
41
|
modpack-lock
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
Flags:
|
|
45
|
+
|
|
46
|
+
- `--dry-run` or `-d`: Print the files that would be scanned, but don't actually scan them
|
|
47
|
+
- `--quiet` or `-q`: Print only errors and warnings
|
|
48
|
+
- `--silent` or `-s`: Print nothing
|
|
49
|
+
- `--gitignore` or `-g`: Print the rules to add to your `.gitignore` file
|
|
50
|
+
|
|
44
51
|
The script will:
|
|
45
52
|
|
|
46
53
|
1. Scan the `mods`, `resourcepacks`, `datapacks`, and `shaderpacks` directories for `.jar` and `.zip` files
|
|
@@ -51,6 +58,7 @@ The script will:
|
|
|
51
58
|
Then, commit the `modpack.lock` file to your repository and push it to your remote.
|
|
52
59
|
|
|
53
60
|
> [!TIP]
|
|
61
|
+
>
|
|
54
62
|
> You can run this script as a pre-commit hook to ensure that the modpack lockfile is up to date before committing your changes to your repository.
|
|
55
63
|
>
|
|
56
64
|
> Also, consider adding these rules to your `.gitignore` to ensure you don't commit the modpack contents to your repository, with exceptions for any files that are not Modrinth-hosted:
|
|
@@ -87,17 +95,6 @@ The `modpack.lock` file has the following structure:
|
|
|
87
95
|
}
|
|
88
96
|
```
|
|
89
97
|
|
|
90
|
-
## Future Plans
|
|
91
|
-
|
|
92
|
-
- [ ] Add support for CurseForge
|
|
93
|
-
- [ ] Add support for restoring modpack contents using the lockfile
|
|
94
|
-
- [ ] Add CLI option for dry-run
|
|
95
|
-
- [ ] Add CLI option for verbose output
|
|
96
|
-
- [ ] Add CLI option for quiet output
|
|
97
|
-
- [ ] Add CLI option for printout of rules to add to .gitignore (the files that are not hosted)
|
|
98
|
-
|
|
99
|
-
Feel free to submit a pull request working on any of the above, or open an issue for any feature requests or bug reports.
|
|
100
|
-
|
|
101
98
|
## License
|
|
102
99
|
|
|
103
100
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for more details.
|
package/index.js
CHANGED
|
@@ -12,6 +12,39 @@ const MODRINTH_VERSION_FILES_ENDPOINT = `${MODRINTH_API_BASE}/version_files`;
|
|
|
12
12
|
// Get the workspace root from the current working directory
|
|
13
13
|
const WORKSPACE_ROOT = process.cwd();
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Parse command-line arguments
|
|
17
|
+
*/
|
|
18
|
+
function parseArgs() {
|
|
19
|
+
const args = process.argv.slice(2);
|
|
20
|
+
return {
|
|
21
|
+
dryRun: args.includes('--dry-run') || args.includes('-d'),
|
|
22
|
+
quiet: args.includes('--quiet') || args.includes('-q'),
|
|
23
|
+
silent: args.includes('--silent') || args.includes('-s'),
|
|
24
|
+
gitignore: args.includes('--gitignore') || args.includes('-g'),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Create a logger function that respects quiet mode
|
|
30
|
+
*/
|
|
31
|
+
function createLogger(quiet) {
|
|
32
|
+
if (quiet) {
|
|
33
|
+
return () => {}; // No-op function when quiet
|
|
34
|
+
}
|
|
35
|
+
return (...args) => console.log(...args);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Silence all console.log output
|
|
40
|
+
*/
|
|
41
|
+
function silenceConsole() {
|
|
42
|
+
console.log = () => {};
|
|
43
|
+
console.warn = () => {};
|
|
44
|
+
console.error = () => {};
|
|
45
|
+
console.info = () => {};
|
|
46
|
+
}
|
|
47
|
+
|
|
15
48
|
const DIRECTORIES_TO_SCAN = [
|
|
16
49
|
{ name: 'mods', path: path.join(WORKSPACE_ROOT, 'mods') },
|
|
17
50
|
{ name: 'resourcepacks', path: path.join(WORKSPACE_ROOT, 'resourcepacks') },
|
|
@@ -152,36 +185,85 @@ function createLockfile(fileEntries, versionData) {
|
|
|
152
185
|
/**
|
|
153
186
|
* Write lockfile to disk
|
|
154
187
|
*/
|
|
155
|
-
async function writeLockfile(lockfile, outputPath) {
|
|
188
|
+
async function writeLockfile(lockfile, outputPath, log) {
|
|
156
189
|
const content = JSON.stringify(lockfile, null, 2);
|
|
157
190
|
await fs.writeFile(outputPath, content, 'utf-8');
|
|
158
|
-
|
|
191
|
+
log(`Lockfile written to: ${outputPath}`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Generate .gitignore rules for files not hosted on Modrinth
|
|
196
|
+
*/
|
|
197
|
+
function generateGitignoreRules(lockfile) {
|
|
198
|
+
const rules = [];
|
|
199
|
+
const exceptions = [];
|
|
200
|
+
|
|
201
|
+
// Base ignore patterns for each category
|
|
202
|
+
rules.push('mods/*.jar');
|
|
203
|
+
rules.push('resourcepacks/*.zip');
|
|
204
|
+
rules.push('datapacks/*.zip');
|
|
205
|
+
rules.push('shaderpacks/*.zip');
|
|
206
|
+
rules.push('');
|
|
207
|
+
rules.push('## Exceptions');
|
|
208
|
+
|
|
209
|
+
// Find files not hosted on Modrinth
|
|
210
|
+
for (const [category, entries] of Object.entries(lockfile.dependencies)) {
|
|
211
|
+
for (const entry of entries) {
|
|
212
|
+
if (entry.version === null) {
|
|
213
|
+
exceptions.push(`!${entry.path}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Add exceptions if any
|
|
219
|
+
if (exceptions.length > 0) {
|
|
220
|
+
rules.push(...exceptions);
|
|
221
|
+
} else {
|
|
222
|
+
rules.push('# No exceptions needed - all files are hosted on Modrinth');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return rules.join('\n');
|
|
159
226
|
}
|
|
160
227
|
|
|
161
228
|
/**
|
|
162
229
|
* Main execution function
|
|
163
230
|
*/
|
|
164
231
|
async function main() {
|
|
165
|
-
|
|
232
|
+
const config = parseArgs();
|
|
233
|
+
const log = createLogger(config.quiet);
|
|
234
|
+
|
|
235
|
+
if (config.silent) {
|
|
236
|
+
silenceConsole();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (config.dryRun) {
|
|
240
|
+
log('[DRY RUN] Preview mode - no files will be written');
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
log('Scanning directories for modpack files...');
|
|
166
244
|
|
|
167
245
|
// Scan all directories
|
|
168
246
|
const allFileEntries = [];
|
|
169
247
|
for (const dirInfo of DIRECTORIES_TO_SCAN) {
|
|
170
|
-
|
|
248
|
+
log(`Scanning ${dirInfo.name}...`);
|
|
171
249
|
const fileEntries = await scanDirectory(dirInfo);
|
|
172
|
-
|
|
250
|
+
log(` Found ${fileEntries.length} file(s)`);
|
|
173
251
|
allFileEntries.push(...fileEntries);
|
|
174
252
|
}
|
|
175
253
|
|
|
176
254
|
if (allFileEntries.length === 0) {
|
|
177
|
-
|
|
255
|
+
log('No files found. Creating empty lockfile.');
|
|
178
256
|
const outputPath = path.join(WORKSPACE_ROOT, MODPACK_LOCKFILE_NAME);
|
|
179
|
-
|
|
257
|
+
if (config.dryRun) {
|
|
258
|
+
log(`[DRY RUN] Would write lockfile to: ${outputPath}`);
|
|
259
|
+
} else {
|
|
260
|
+
await writeLockfile(createEmptyLockfile(), outputPath, log);
|
|
261
|
+
}
|
|
180
262
|
return;
|
|
181
263
|
}
|
|
182
264
|
|
|
183
|
-
|
|
184
|
-
|
|
265
|
+
log(`\nTotal files found: ${allFileEntries.length}`);
|
|
266
|
+
log('\nQuerying Modrinth API...');
|
|
185
267
|
|
|
186
268
|
// Extract all hashes
|
|
187
269
|
const hashes = allFileEntries.map(info => info.hash);
|
|
@@ -189,21 +271,31 @@ async function main() {
|
|
|
189
271
|
// Query Modrinth API
|
|
190
272
|
const versionData = await getVersionsFromHashes(hashes);
|
|
191
273
|
|
|
192
|
-
|
|
274
|
+
log(`\nFound version information for ${Object.keys(versionData).length} out of ${hashes.length} files`);
|
|
193
275
|
|
|
194
276
|
// Create lockfile
|
|
195
277
|
const lockfile = createLockfile(allFileEntries, versionData);
|
|
196
278
|
|
|
197
279
|
// Write lockfile
|
|
198
280
|
const outputPath = path.join(WORKSPACE_ROOT, MODPACK_LOCKFILE_NAME);
|
|
199
|
-
|
|
281
|
+
if (config.dryRun) {
|
|
282
|
+
log(`[DRY RUN] Would write lockfile to: ${outputPath}`);
|
|
283
|
+
} else {
|
|
284
|
+
await writeLockfile(lockfile, outputPath, log);
|
|
285
|
+
}
|
|
200
286
|
|
|
201
287
|
// Summary
|
|
202
|
-
|
|
288
|
+
log('\n=== Summary ===');
|
|
203
289
|
for (const [category, entries] of Object.entries(lockfile.dependencies)) {
|
|
204
290
|
const withVersion = entries.filter(e => e.version !== null).length;
|
|
205
291
|
const withoutVersion = entries.length - withVersion;
|
|
206
|
-
|
|
292
|
+
log(`${category}: ${entries.length} file(s) (${withVersion} found on Modrinth, ${withoutVersion} unknown)`);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Generate .gitignore rules if requested
|
|
296
|
+
if (config.gitignore) {
|
|
297
|
+
log('\n=== .gitignore Rules ===');
|
|
298
|
+
log(generateGitignoreRules(lockfile));
|
|
207
299
|
}
|
|
208
300
|
}
|
|
209
301
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "modpack-lock",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Create a modpack lockfile for files hosted on Modrinth (mods, resource packs, shaders and datapacks)",
|
|
5
|
-
"homepage": "https://github.com/nickesc/modpack-lock#readme",
|
|
6
5
|
"bugs": {
|
|
7
6
|
"url": "https://github.com/nickesc/modpack-lock/issues"
|
|
8
7
|
},
|