@meistrari/mise-en-place 2.15.2 → 2.16.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 +23 -0
- package/dist/cli/cli.mjs +87 -45
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,6 +35,29 @@ By adding the `postinstall` script to run `mise-en-place postinstall`, every tim
|
|
|
35
35
|
|
|
36
36
|
This process will add a leading caret (`^`) to the version range if it is not already present. Which means that it will update to the latest minor and patch versions automatically but never the major version.
|
|
37
37
|
|
|
38
|
+
### Configuration
|
|
39
|
+
|
|
40
|
+
You can customize the update behaviour through a `miseEnPlace.updateMeistrariLibraries` object in your `package.json`:
|
|
41
|
+
|
|
42
|
+
```jsonc
|
|
43
|
+
{
|
|
44
|
+
"miseEnPlace": {
|
|
45
|
+
"updateMeistrariLibraries": {
|
|
46
|
+
"enabled": true, // defaults to true. when false, the update is skipped
|
|
47
|
+
"exact": false, // defaults to false. when true, versions are written exact, without a range operator (^/~)
|
|
48
|
+
"packages": { // defaults to {}. unlisted @meistrari/* packages use "minor"
|
|
49
|
+
"@meistrari/package-1": "skip", // never touch this package's version
|
|
50
|
+
"@meistrari/package-2": "patch", // pin major and minor, update patch (~)
|
|
51
|
+
"@meistrari/package-3": "minor", // pin major, update minor and patch (^)
|
|
52
|
+
"@meistrari/package-4": "major" // update to the latest version, even across a major bump
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
When `exact` is `true`, every updated package is written as an exact version: each package is still updated as far as its strategy allows, but the resulting version is written without a `^` or `~`.
|
|
60
|
+
|
|
38
61
|
## Makefile
|
|
39
62
|
The postinstall script does not create a `Makefile` automatically. To use the shared Makefile commands, create a `Makefile` and include this package's `Makefile`.
|
|
40
63
|
|
package/dist/cli/cli.mjs
CHANGED
|
@@ -40,11 +40,36 @@ function getMeistrariLibs(packageJson) {
|
|
|
40
40
|
}
|
|
41
41
|
return Array.from(libs).sort();
|
|
42
42
|
}
|
|
43
|
-
const
|
|
44
|
-
function
|
|
45
|
-
|
|
43
|
+
const versionWithOperatorPattern = /^[\^~]?(\d+\.\d+\.\d+(?:-[0-9a-z-.]+)?(?:\+[0-9a-z-.]+)?)$/i;
|
|
44
|
+
function setVersionOperator(value, operator) {
|
|
45
|
+
const match = versionWithOperatorPattern.exec(value);
|
|
46
|
+
if (!match) {
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
return `${operator}${match[1]}`;
|
|
50
|
+
}
|
|
51
|
+
function preUpdateOperator(strategy) {
|
|
52
|
+
if (strategy === "skip") {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
if (strategy === "patch") {
|
|
56
|
+
return "~";
|
|
57
|
+
}
|
|
58
|
+
return "^";
|
|
46
59
|
}
|
|
47
|
-
function
|
|
60
|
+
function postUpdateOperator(strategy, exact) {
|
|
61
|
+
if (strategy === "skip") {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
if (exact) {
|
|
65
|
+
return "";
|
|
66
|
+
}
|
|
67
|
+
if (strategy === "patch") {
|
|
68
|
+
return "~";
|
|
69
|
+
}
|
|
70
|
+
return "^";
|
|
71
|
+
}
|
|
72
|
+
function applyMeistrariRanges(deps, operatorFor) {
|
|
48
73
|
if (!deps)
|
|
49
74
|
return deps;
|
|
50
75
|
const result = { ...deps };
|
|
@@ -52,10 +77,11 @@ function addCaretToMeistrariDeps(deps) {
|
|
|
52
77
|
if (!key.startsWith("@meistrari/")) {
|
|
53
78
|
continue;
|
|
54
79
|
}
|
|
55
|
-
|
|
80
|
+
const operator = operatorFor(key);
|
|
81
|
+
if (operator === null) {
|
|
56
82
|
continue;
|
|
57
83
|
}
|
|
58
|
-
result[key] =
|
|
84
|
+
result[key] = setVersionOperator(value, operator);
|
|
59
85
|
}
|
|
60
86
|
return result;
|
|
61
87
|
}
|
|
@@ -82,13 +108,6 @@ function detectPackageManager() {
|
|
|
82
108
|
file: "bun.lockb"
|
|
83
109
|
});
|
|
84
110
|
}
|
|
85
|
-
const yarnLockExists = existsSync("yarn.lock");
|
|
86
|
-
if (yarnLockExists) {
|
|
87
|
-
detected.push({
|
|
88
|
-
packageManager: "yarn",
|
|
89
|
-
file: "yarn.lock"
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
111
|
const npmLockExists = existsSync("package-lock.json");
|
|
93
112
|
if (npmLockExists) {
|
|
94
113
|
detected.push({
|
|
@@ -122,7 +141,7 @@ function getWorkspaces(packageManager) {
|
|
|
122
141
|
const rootPackageJson = readPackageJson("package.json");
|
|
123
142
|
return rootPackageJson.workspaces || [];
|
|
124
143
|
}
|
|
125
|
-
function updateLibraries(packageManager, libs, cwd) {
|
|
144
|
+
function updateLibraries(packageManager, libs, { cwd, latest = false } = {}) {
|
|
126
145
|
const libsStr = libs.join(" ");
|
|
127
146
|
const options = {
|
|
128
147
|
stdio: "inherit",
|
|
@@ -130,16 +149,16 @@ function updateLibraries(packageManager, libs, cwd) {
|
|
|
130
149
|
};
|
|
131
150
|
switch (packageManager) {
|
|
132
151
|
case "pnpm":
|
|
133
|
-
execSync(`pnpm update ${libsStr} --ignore-scripts -r`, options);
|
|
152
|
+
execSync(`pnpm update ${latest ? "--latest " : ""}${libsStr} --ignore-scripts -r`, options);
|
|
134
153
|
break;
|
|
135
154
|
case "bun":
|
|
136
|
-
execSync(`bun update --silent ${libsStr} --ignore-scripts`, options);
|
|
137
|
-
break;
|
|
138
|
-
case "yarn":
|
|
139
|
-
execSync(`yarn up ${libsStr} --ignore-scripts -r`, options);
|
|
155
|
+
execSync(`bun update --silent ${latest ? "--latest " : ""}${libsStr} --ignore-scripts`, options);
|
|
140
156
|
break;
|
|
141
157
|
case "npm":
|
|
142
|
-
execSync(
|
|
158
|
+
execSync(
|
|
159
|
+
latest ? `npm install ${libs.map((lib) => `${lib}@latest`).join(" ")} --ignore-scripts` : `npm update ${libsStr} --ignore-scripts`,
|
|
160
|
+
options
|
|
161
|
+
);
|
|
143
162
|
break;
|
|
144
163
|
}
|
|
145
164
|
}
|
|
@@ -148,6 +167,15 @@ function updateMeistrariLibraries(args) {
|
|
|
148
167
|
console.log("No package.json found. Skipping @meistrari/* updates.");
|
|
149
168
|
return;
|
|
150
169
|
}
|
|
170
|
+
const config = readPackageJson("package.json").miseEnPlace?.updateMeistrariLibraries ?? {};
|
|
171
|
+
const enabled = config.enabled ?? true;
|
|
172
|
+
const exact = config.exact ?? false;
|
|
173
|
+
const strategies = config.packages ?? {};
|
|
174
|
+
const strategyFor = (lib) => strategies[lib] ?? "minor";
|
|
175
|
+
if (!enabled) {
|
|
176
|
+
console.log("miseEnPlace.updateMeistrariLibraries.enabled is false. Skipping @meistrari/* updates.");
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
151
179
|
const { packageManager: packageManagerOverride } = args;
|
|
152
180
|
const selectPackageManager = () => {
|
|
153
181
|
if (packageManagerOverride) {
|
|
@@ -156,7 +184,7 @@ function updateMeistrariLibraries(args) {
|
|
|
156
184
|
}
|
|
157
185
|
const detectedPackageManagers = detectPackageManager();
|
|
158
186
|
if (!detectedPackageManagers) {
|
|
159
|
-
console.log("No recognized lock file found (pnpm-lock.yaml,
|
|
187
|
+
console.log("No recognized lock file found (pnpm-lock.yaml, bun.lock, package-lock.json)");
|
|
160
188
|
process.exit(1);
|
|
161
189
|
}
|
|
162
190
|
detectedPackageManagers.forEach(({ packageManager, file }) => {
|
|
@@ -185,23 +213,27 @@ function updateMeistrariLibraries(args) {
|
|
|
185
213
|
console.log("No @meistrari/* libraries found in dependencies. Skipping update.");
|
|
186
214
|
return;
|
|
187
215
|
}
|
|
216
|
+
const libsList = Array.from(allMeistrariLibs).sort();
|
|
217
|
+
const updatableLibs = libsList.filter((lib) => strategyFor(lib) !== "skip");
|
|
218
|
+
const skippedLibs = libsList.filter((lib) => strategyFor(lib) === "skip");
|
|
219
|
+
if (skippedLibs.length > 0) {
|
|
220
|
+
console.log(`Skipping (config) ${skippedLibs.length} @meistrari/* libraries:`);
|
|
221
|
+
console.log(skippedLibs.join("\n"));
|
|
222
|
+
}
|
|
223
|
+
if (updatableLibs.length === 0) {
|
|
224
|
+
console.log("All @meistrari/* libraries are configured to be skipped. Nothing to update.");
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
188
227
|
for (const pkgJsonPath of packageJsonPaths) {
|
|
189
228
|
if (!existsSync(pkgJsonPath))
|
|
190
229
|
continue;
|
|
191
230
|
const pkgJson = readPackageJson(pkgJsonPath);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
pkgJson.dependencies = updated;
|
|
195
|
-
}
|
|
196
|
-
if (pkgJson.devDependencies) {
|
|
197
|
-
const updated = addCaretToMeistrariDeps(pkgJson.devDependencies);
|
|
198
|
-
pkgJson.devDependencies = updated;
|
|
199
|
-
}
|
|
231
|
+
pkgJson.dependencies = applyMeistrariRanges(pkgJson.dependencies, (lib) => preUpdateOperator(strategyFor(lib)));
|
|
232
|
+
pkgJson.devDependencies = applyMeistrariRanges(pkgJson.devDependencies, (lib) => preUpdateOperator(strategyFor(lib)));
|
|
200
233
|
writePackageJson(pkgJsonPath, pkgJson);
|
|
201
234
|
}
|
|
202
|
-
|
|
203
|
-
console.log(
|
|
204
|
-
console.log(libsList.join("\n"));
|
|
235
|
+
console.log(`Found ${updatableLibs.length} @meistrari/* libraries to update:`);
|
|
236
|
+
console.log(updatableLibs.join("\n"));
|
|
205
237
|
for (const packageManager of packageManagers) {
|
|
206
238
|
if (packageManager === "bun") {
|
|
207
239
|
for (const pkgJsonPath of packageJsonPaths) {
|
|
@@ -209,30 +241,40 @@ function updateMeistrariLibraries(args) {
|
|
|
209
241
|
continue;
|
|
210
242
|
const pkgJsonDir = dirname(pkgJsonPath);
|
|
211
243
|
const pkgJson = readPackageJson(pkgJsonPath);
|
|
212
|
-
const localLibs = getMeistrariLibs(pkgJson);
|
|
244
|
+
const localLibs = getMeistrariLibs(pkgJson).filter((lib) => strategyFor(lib) !== "skip");
|
|
213
245
|
if (localLibs.length === 0) {
|
|
214
|
-
console.log(`No @meistrari/* libraries found in ${pkgJsonDir}. Skipping.`);
|
|
246
|
+
console.log(`No updatable @meistrari/* libraries found in ${pkgJsonDir}. Skipping.`);
|
|
215
247
|
continue;
|
|
216
248
|
}
|
|
217
|
-
|
|
218
|
-
|
|
249
|
+
const cwd = pkgJsonDir === "." ? void 0 : pkgJsonDir;
|
|
250
|
+
const rangedLibs = localLibs.filter((lib) => strategyFor(lib) !== "major");
|
|
251
|
+
const majorLibs = localLibs.filter((lib) => strategyFor(lib) === "major");
|
|
252
|
+
if (rangedLibs.length > 0) {
|
|
253
|
+
console.log(`Updating ${rangedLibs.join(" ")} libraries in ${pkgJsonDir}`);
|
|
254
|
+
updateLibraries(packageManager, rangedLibs, { cwd });
|
|
255
|
+
}
|
|
256
|
+
if (majorLibs.length > 0) {
|
|
257
|
+
console.log(`Updating ${majorLibs.join(" ")} libraries to latest in ${pkgJsonDir}`);
|
|
258
|
+
updateLibraries(packageManager, majorLibs, { cwd, latest: true });
|
|
259
|
+
}
|
|
219
260
|
}
|
|
220
261
|
} else {
|
|
221
|
-
|
|
262
|
+
const rangedLibs = updatableLibs.filter((lib) => strategyFor(lib) !== "major");
|
|
263
|
+
const majorLibs = updatableLibs.filter((lib) => strategyFor(lib) === "major");
|
|
264
|
+
if (rangedLibs.length > 0) {
|
|
265
|
+
updateLibraries(packageManager, rangedLibs);
|
|
266
|
+
}
|
|
267
|
+
if (majorLibs.length > 0) {
|
|
268
|
+
updateLibraries(packageManager, majorLibs, { latest: true });
|
|
269
|
+
}
|
|
222
270
|
}
|
|
223
271
|
}
|
|
224
272
|
for (const pkgJsonPath of packageJsonPaths) {
|
|
225
273
|
if (!existsSync(pkgJsonPath))
|
|
226
274
|
continue;
|
|
227
275
|
const pkgJson = readPackageJson(pkgJsonPath);
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
pkgJson.dependencies = updated;
|
|
231
|
-
}
|
|
232
|
-
if (pkgJson.devDependencies) {
|
|
233
|
-
const updated = addCaretToMeistrariDeps(pkgJson.devDependencies);
|
|
234
|
-
pkgJson.devDependencies = updated;
|
|
235
|
-
}
|
|
276
|
+
pkgJson.dependencies = applyMeistrariRanges(pkgJson.dependencies, (lib) => postUpdateOperator(strategyFor(lib), exact));
|
|
277
|
+
pkgJson.devDependencies = applyMeistrariRanges(pkgJson.devDependencies, (lib) => postUpdateOperator(strategyFor(lib), exact));
|
|
236
278
|
writePackageJson(pkgJsonPath, pkgJson);
|
|
237
279
|
}
|
|
238
280
|
}
|