pob 39.1.0 → 39.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.
@@ -1,8 +1,45 @@
1
+ import { execFileSync } from "node:child_process";
1
2
  import sortObject from "@pob/sort-object";
2
- import { FAILSAFE_SCHEMA, dump, loadAll } from "js-yaml";
3
+ import { FAILSAFE_SCHEMA, dump, load, loadAll } from "js-yaml";
4
+ import { satisfies } from "semver";
3
5
  import Generator from "yeoman-generator";
4
6
  import { writeAndFormat } from "../../../utils/writeAndFormat.js";
5
7
 
8
+ const pnpmVersionRange = "^12.0.0";
9
+
10
+ // pnpm 12 writes the pnpm version in a first document of pnpm-lock.yaml when
11
+ // devEngines.packageManager is not ignored. Removes it when it has nothing
12
+ // else (no config dependencies).
13
+ const removePackageManagerLockfileDocument = (lockfile) => {
14
+ if (!lockfile.startsWith("---\n")) return lockfile;
15
+ const end = lockfile.indexOf("\n---\n", 4);
16
+ if (end === -1) return lockfile;
17
+ const envDocument = load(lockfile.slice(4, end), { schema: FAILSAFE_SCHEMA });
18
+ const importer = envDocument?.importers?.["."] ?? {};
19
+ const hasOtherEntries = Object.keys(importer).some(
20
+ (key) =>
21
+ key !== "packageManagerDependencies" && key !== "configDependencies",
22
+ );
23
+ if (
24
+ hasOtherEntries ||
25
+ Object.keys(importer.configDependencies ?? {}).length > 0
26
+ ) {
27
+ return lockfile;
28
+ }
29
+ return lockfile.slice(end + "\n---\n".length);
30
+ };
31
+
32
+ const getRunningPnpmVersion = (cwd) => {
33
+ try {
34
+ return execFileSync("pnpm", ["--version"], {
35
+ cwd,
36
+ encoding: "utf8",
37
+ }).trim();
38
+ } catch {
39
+ return null;
40
+ }
41
+ };
42
+
6
43
  const minimumReleaseAgeExcludePackages = [
7
44
  "@pob/*",
8
45
  "pob",
@@ -38,19 +75,26 @@ export default class CorePnpmGenerator extends Generator {
38
75
  const pkg = this.fs.readJSON(this.destinationPath("package.json"));
39
76
 
40
77
  if (this.options.enable) {
41
- // devEngines.packageManager replaces packageManager: pnpm switches to
42
- // this version on startup (including when pnpm install is run by pob
43
- // with an older pnpm), and pnpm/action-setup reads it.
78
+ // devEngines.packageManager is read by pnpm/action-setup. onFail is
79
+ // "ignore": otherwise pnpm writes its version in pnpm-lock.yaml and it
80
+ // has to be updated manually. The version is checked by engines.pnpm.
44
81
  delete pkg.packageManager;
45
82
  pkg.devEngines = {
46
83
  ...pkg.devEngines,
47
84
  packageManager: {
48
85
  name: "pnpm",
49
- version: "^12.0.0",
50
- onFail: "download",
86
+ version: pnpmVersionRange,
87
+ onFail: "ignore",
51
88
  },
52
89
  };
53
90
 
91
+ const lockfilePath = this.destinationPath("pnpm-lock.yaml");
92
+ if (this.fs.exists(lockfilePath)) {
93
+ const lockfile = this.fs.read(lockfilePath);
94
+ const newLockfile = removePackageManagerLockfileDocument(lockfile);
95
+ if (newLockfile !== lockfile) this.fs.write(lockfilePath, newLockfile);
96
+ }
97
+
54
98
  const configString = this.fs.read(
55
99
  this.destinationPath("pnpm-workspace.yaml"),
56
100
  { defaults: "" },
@@ -118,11 +162,23 @@ export default class CorePnpmGenerator extends Generator {
118
162
  `pnpm-workspace.yaml: set allowBuilds to true or false for ${this.pendingAllowBuilds.join(", ")}`,
119
163
  );
120
164
  }
165
+ // the running pnpm can be older than the version required by pob, for
166
+ // example in the @pob/root renovate workflow after a pnpm major update
167
+ const runningPnpmVersion = getRunningPnpmVersion(this.destinationPath());
168
+ const pnpmArgs =
169
+ runningPnpmVersion && satisfies(runningPnpmVersion, pnpmVersionRange)
170
+ ? []
171
+ : ["with", pnpmVersionRange];
172
+
121
173
  // pob just modified package.json: the lockfile must be allowed to update,
122
174
  // in particular in the automatic update GitHub Actions workflow (CI
123
175
  // defaults to frozen lockfile)
124
- this.spawnSync("pnpm", ["install", "--no-frozen-lockfile"], {});
125
- this.spawnSync("pnpm", ["dedupe"], {});
176
+ this.spawnSync(
177
+ "pnpm",
178
+ [...pnpmArgs, "install", "--no-frozen-lockfile"],
179
+ {},
180
+ );
181
+ this.spawnSync("pnpm", [...pnpmArgs, "dedupe"], {});
126
182
 
127
183
  this.fs.delete("package-lock.json");
128
184
  this.fs.delete("yarn.lock");
@@ -131,11 +187,11 @@ export default class CorePnpmGenerator extends Generator {
131
187
 
132
188
  if (pkg.scripts?.preversion) {
133
189
  try {
134
- this.spawnSync("pnpm", ["run", "preversion"]);
190
+ this.spawnSync("pnpm", [...pnpmArgs, "run", "preversion"]);
135
191
  } catch {}
136
192
  } else if (pkg.scripts?.build) {
137
193
  try {
138
- this.spawnSync("pnpm", ["run", "build"]);
194
+ this.spawnSync("pnpm", [...pnpmArgs, "run", "build"]);
139
195
  } catch {}
140
196
  }
141
197
  }
@@ -85,8 +85,13 @@ export default class MonorepoWorkspacesGenerator extends Generator {
85
85
  if (!pkg.engines) pkg.engines = {};
86
86
  pkg.engines.yarn = "< 0.0.0";
87
87
  pkg.engines.npm = ">= 6.4.0";
88
+ } else if (this.options.packageManager === "pnpm") {
89
+ // checks the version locally: devEngines.packageManager is ignored by
90
+ // pnpm (see pob:core:pnpm)
91
+ if (!pkg.engines) pkg.engines = {};
92
+ pkg.engines.pnpm = ">= 12.0.0";
93
+ delete pkg.engines.yarn;
88
94
  } else if (pkg.engines) {
89
- // the pnpm version is set in devEngines by pob:core:pnpm
90
95
  delete pkg.engines.pnpm;
91
96
  delete pkg.engines.yarn;
92
97
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pob",
3
- "version": "39.1.0",
3
+ "version": "39.1.1",
4
4
  "description": "Pile of bones, library generator with git/babel/typescript/typedoc/readme/vitest",
5
5
  "keywords": [
6
6
  "skeleton"