pob 14.1.0 → 14.3.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/CHANGELOG.md CHANGED
@@ -3,6 +3,32 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [14.3.0](https://github.com/christophehurpeau/pob/compare/pob@14.2.0...pob@14.3.0) (2023-10-02)
7
+
8
+
9
+ ### Features
10
+
11
+ * rename publish job to Release ([cc6b66b](https://github.com/christophehurpeau/pob/commit/cc6b66b05469720faa6cb0a05d0a29843dd676cb))
12
+
13
+
14
+
15
+ ## [14.2.0](https://github.com/christophehurpeau/pob/compare/pob@14.1.0...pob@14.2.0) (2023-09-30)
16
+
17
+
18
+ ### Features
19
+
20
+ * improve monorepo detection ([c7e43ef](https://github.com/christophehurpeau/pob/commit/c7e43efd767e1cc7d786c22f47796fc5106be84b))
21
+ * **pob:** split yarn workspaces and legacy lerna ; use yarn to build graph ([4f3f77a](https://github.com/christophehurpeau/pob/commit/4f3f77a60a4e755815a836f76d53624573edcff4))
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * **deps:** update @pob/eslint-config to v51.0.2 ([#1718](https://github.com/christophehurpeau/pob/issues/1718)) ([18a8330](https://github.com/christophehurpeau/pob/commit/18a8330c54729273d091cfbe49e387916fbde3ba))
27
+ * **deps:** update dependency yeoman-environment to v4.0.0-beta.5 ([#1785](https://github.com/christophehurpeau/pob/issues/1785)) ([deb0019](https://github.com/christophehurpeau/pob/commit/deb00197a177fdddb1037538969351ed8f2e1925))
28
+ * **deps:** update dependency yeoman-generator to v6.0.0-rc.5 ([#1786](https://github.com/christophehurpeau/pob/issues/1786)) ([6ebbde9](https://github.com/christophehurpeau/pob/commit/6ebbde9db265b44e8807fd4a83526b49984e5d33))
29
+
30
+
31
+
6
32
  ## [14.1.0](https://github.com/christophehurpeau/pob/compare/pob@14.0.1...pob@14.1.0) (2023-09-24)
7
33
 
8
34
 
@@ -42,7 +42,6 @@ export default class CoreGitGenerator extends Generator {
42
42
  originUrl &&
43
43
  typeof originUrl === 'string' &&
44
44
  originUrl.match(
45
- // eslint-disable-next-line unicorn/no-unsafe-regex
46
45
  /^(?:git@|https?:\/\/)(?:([^./:]+)(?:\.com)?[/:])?([^/:]+)\/([^./:]+)(?:.git)?/,
47
46
  );
48
47
  if (!match) return;
@@ -68,7 +68,6 @@ export default class LibReadmeGenerator extends Generator {
68
68
  const match =
69
69
  repository &&
70
70
  repository.match(
71
- // eslint-disable-next-line unicorn/no-unsafe-regex
72
71
  /^(?:git@|https?:\/\/)(?:([^./:]+)(?:\.com)?[/:])?([^/:]+)\/([^./:]+)(?:.git)?/,
73
72
  );
74
73
  const [, gitHost, gitAccount, gitName] = match || [];
@@ -1,13 +1,31 @@
1
1
  import { execSync } from 'node:child_process';
2
2
  import fs from 'node:fs';
3
- import path from 'node:path';
4
3
  import { platform } from 'node:process';
5
- import { PackageGraph } from '@lerna/package-graph';
6
- import { Project as LernaProject } from '@lerna/project';
4
+ import { getPluginConfiguration } from '@yarnpkg/cli';
5
+ import { Configuration, Project } from '@yarnpkg/core';
6
+ import { ppath } from '@yarnpkg/fslib';
7
+ import {
8
+ buildTopologicalOrderBatches,
9
+ buildDependenciesMaps,
10
+ getWorkspaceName,
11
+ } from 'yarn-workspace-utils';
7
12
  import Generator from 'yeoman-generator';
8
13
  import * as packageUtils from '../../utils/package.js';
9
14
  import { copyAndFormatTpl } from '../../utils/writeAndFormat.js';
10
15
 
16
+ export const createYarnProject = async () => {
17
+ const portablePath = ppath.cwd();
18
+
19
+ const configuration = await Configuration.find(
20
+ portablePath,
21
+ // eslint-disable-next-line unicorn/no-array-method-this-argument -- not an array
22
+ getPluginConfiguration(),
23
+ );
24
+ // eslint-disable-next-line unicorn/no-array-method-this-argument -- not an array
25
+ const { project } = await Project.find(configuration, portablePath);
26
+ return project;
27
+ };
28
+
11
29
  const getAppTypes = (configs) => {
12
30
  const appConfigs = configs.filter(
13
31
  (config) => config && config.project && config.project.type === 'app',
@@ -26,9 +44,9 @@ const hasDist = (packages, configs) =>
26
44
  (config, index) =>
27
45
  !!(config && config.project && config.project.type === 'lib') &&
28
46
  !!(
29
- packages[index].get('pob') &&
30
- packages[index].get('pob').babelEnvs &&
31
- packages[index].get('pob').babelEnvs.length > 0
47
+ packages[index].pob &&
48
+ packages[index].pob.babelEnvs &&
49
+ packages[index].pob.babelEnvs.length > 0
32
50
  ),
33
51
  );
34
52
 
@@ -89,43 +107,28 @@ export default class PobMonorepoGenerator extends Generator {
89
107
  }
90
108
 
91
109
  async initializing() {
92
- this.lernaProject = new LernaProject(this.destinationPath());
93
- const packages = await this.lernaProject.getPackages();
94
- const graph = new PackageGraph(packages);
95
- const [cyclePaths] = graph.partitionCycles();
96
-
97
- if (cyclePaths.size > 0) {
98
- const cycleMessage = [
99
- 'Dependency cycles detected, you should fix these!',
100
- ...cyclePaths.map((cycle) => cycle.join(' -> ')),
101
- ].join('\n');
102
-
103
- console.warn(cycleMessage);
104
- }
110
+ const yarnProject = await createYarnProject(this.destinationPath());
111
+ const batches = buildTopologicalOrderBatches(
112
+ yarnProject,
113
+ buildDependenciesMaps(yarnProject),
114
+ );
105
115
 
106
116
  this.packages = [];
107
117
  this.packageLocations = [];
108
118
 
109
- while (graph.size > 0) {
110
- // pick the current set of nodes _without_ localDependencies (aka it is a "source" node)
111
- const batch = [...graph.values()].filter(
112
- (node) => node.localDependencies.size === 0,
113
- );
114
- batch.sort((a, b) => a.name.localeCompare(b.name, 'en'));
115
-
116
- // batches are composed of Package instances, not PackageGraphNodes
117
- this.packages.push(...batch.map((node) => node.pkg));
118
- this.packageLocations.push(
119
- ...batch.map((node) =>
120
- path
121
- .relative(this.destinationPath(), node.location)
122
- // transform windows path to linux
123
- .replace(/\\+/g, '/'),
124
- ),
119
+ for (const batch of batches) {
120
+ // sort by name to ensure consistent ordering
121
+ batch.sort((a, b) =>
122
+ getWorkspaceName(a).localeCompare(getWorkspaceName(b), 'en'),
125
123
  );
126
124
 
127
- // pruning the graph changes the node.localDependencies.size test
128
- graph.prune(...batch);
125
+ batch.forEach((workspace) => {
126
+ if (workspace === yarnProject.topLevelWorkspace) {
127
+ return;
128
+ }
129
+ this.packages.push(workspace.manifest.raw);
130
+ this.packageLocations.push(workspace.relativeCwd.toString());
131
+ });
129
132
  }
130
133
 
131
134
  this.packageNames = this.packages.map((pkg) => pkg.name);
@@ -1,11 +1,7 @@
1
- import { spawnSync } from 'node:child_process';
2
1
  import { readdirSync, existsSync } from 'node:fs';
3
2
  import Generator from 'yeoman-generator';
4
3
  import * as packageUtils from '../../../utils/package.js';
5
- import {
6
- copyAndFormatTpl,
7
- writeAndFormatJson,
8
- } from '../../../utils/writeAndFormat.js';
4
+ import { writeAndFormatJson } from '../../../utils/writeAndFormat.js';
9
5
 
10
6
  export default class MonorepoLernaGenerator extends Generator {
11
7
  constructor(args, opts) {
@@ -31,6 +27,7 @@ export default class MonorepoLernaGenerator extends Generator {
31
27
  });
32
28
  }
33
29
 
30
+ // TODO pass packages as options ?
34
31
  initializing() {
35
32
  const pkg = this.fs.readJSON(this.destinationPath('package.json'), {});
36
33
  const packagesPaths = pkg.workspaces
@@ -128,65 +125,16 @@ export default class MonorepoLernaGenerator extends Generator {
128
125
  // package.json
129
126
  const pkg = this.fs.readJSON(this.destinationPath('package.json'), {});
130
127
  delete pkg.lerna;
131
- packageUtils.removeDependencies(pkg, ['lerna', '@pob/lerna-light']);
128
+ packageUtils.removeDependencies(pkg, ['lerna']);
132
129
  packageUtils.removeDevDependencies(pkg, ['lerna']);
133
130
 
134
131
  if (this.fs.exists(this.destinationPath('lerna-debug.log'))) {
135
132
  this.fs.delete(this.destinationPath('lerna-debug.log'));
136
133
  }
137
- if (this.npm) {
138
- if (!pkg.engines) pkg.engines = {};
139
- pkg.engines.yarn = '< 0.0.0';
140
- pkg.engines.npm = '>= 6.4.0';
141
- } else if (pkg.engines) {
142
- delete pkg.engines.yarn;
143
- }
144
-
145
- if (pkg.name === 'pob-monorepo') {
146
- pkg.devDependencies['@pob/lerna-light'] = 'workspace:*';
147
- } else {
148
- packageUtils.addOrRemoveDevDependencies(
149
- pkg,
150
- pkg.name !== 'pob-monorepo-test-repository' &&
151
- pkg.name !== 'use-react-intl-formatters-monorepo',
152
- // pkg.name !== '@pob/eslint-config-monorepo'
153
- ['@pob/lerna-light'],
154
- );
155
- }
156
134
 
157
135
  // TODO remove lerna completely
158
136
  const isYarnVersionEnabled = !pkg.devDependencies?.['@pob/lerna-light'];
159
137
 
160
- if (pkg.name !== 'pob-monorepo') {
161
- packageUtils.addDevDependencies(pkg, ['repository-check-dirty']);
162
- }
163
-
164
- packageUtils.removeDevDependencies(pkg, ['standard-version']);
165
-
166
- const monorepoConfig = this.config.get('monorepo');
167
- const packageManager = this.npm ? 'npm' : 'yarn';
168
-
169
- packageUtils.addScripts(pkg, {
170
- lint: `${packageManager} run lint:prettier && ${packageManager} run lint:eslint`,
171
- 'lint:prettier': 'pob-root-prettier --check .',
172
- 'lint:prettier:fix': 'pob-root-prettier --write .',
173
- 'lint:eslint':
174
- monorepoConfig &&
175
- monorepoConfig.eslint &&
176
- this.packagesConfig.length < 50
177
- ? `${
178
- this.packagesConfig.length > 15
179
- ? 'NODE_OPTIONS=--max_old_space_size=4096 '
180
- : ''
181
- }eslint --report-unused-disable-directives --resolve-plugins-relative-to . --quiet .`
182
- : // eslint-disable-next-line unicorn/no-nested-ternary
183
- this.options.packageManager === 'yarn'
184
- ? `NODE_OPTIONS=--max_old_space_size=4096 eslint --report-unused-disable-directives --resolve-plugins-relative-to . --quiet . --ignore-pattern ${pkg.workspaces.join(
185
- ',',
186
- )} && yarn workspaces foreach --parallel -Av run lint:eslint`
187
- : 'npm run lint:eslint --workspaces',
188
- });
189
-
190
138
  packageUtils.addOrRemoveScripts(
191
139
  pkg,
192
140
  this.options.packageManager === 'yarn' && !isYarnVersionEnabled,
@@ -196,113 +144,6 @@ export default class MonorepoLernaGenerator extends Generator {
196
144
  },
197
145
  );
198
146
 
199
- // TODO rename release (release = version + publish)
200
- this.fs.copyTpl(
201
- this.templatePath('workflow-publish.yml.ejs'),
202
- this.destinationPath('.github/workflows/publish.yml'),
203
- {
204
- publish: !this.options.isAppProject,
205
- enableYarnVersion: isYarnVersionEnabled,
206
- disableYarnGitCache: this.options.disableYarnGitCache,
207
- isIndependent: lernaConfig.version === 'independent',
208
- },
209
- );
210
-
211
- packageUtils.removeScripts(
212
- pkg,
213
- [pkg.name !== 'pob-dependencies' && 'preversion', 'release'].filter(
214
- Boolean,
215
- ),
216
- );
217
-
218
- packageUtils.addOrRemoveScripts(pkg, withBabel, {
219
- build:
220
- 'yarn workspaces foreach --parallel --topological-dev -Av run build',
221
- watch:
222
- 'yarn workspaces foreach --parallel --jobs unlimited --interlaced --exclude "*-example" -Av run watch',
223
- });
224
-
225
- // packageUtils.addOrRemoveScripts(pkg, withTypescript, {
226
- // 'build:definitions': `${
227
- // useYarnWorkspacesCommand
228
- // ? 'yarn workspaces foreach --parallel --exclude "*-example" -Av run'
229
- // : 'lerna run --stream'
230
- // } build:definitions`,
231
- // });
232
-
233
- // if (withTypescript) {
234
- // pkg.scripts.build += `${packageManager} run build:definitions${
235
- // useYarnWorkspacesCommand ? '' : ' --since'
236
- // }`;
237
- // }
238
-
239
- delete pkg.scripts.postbuild;
240
- delete pkg.scripts.prepublishOnly;
241
-
242
- if (this.npm) {
243
- delete pkg.workspaces;
244
- packageUtils.addScripts(pkg, {
245
- postinstall: 'lerna link',
246
- });
247
- } else if (!pkg.workspaces) {
248
- pkg.workspaces = ['packages/*'];
249
- }
250
-
251
147
  this.fs.writeJSON(this.destinationPath('package.json'), pkg);
252
-
253
- // README.md
254
- const readmePath = this.destinationPath('README.md');
255
-
256
- let content = '';
257
-
258
- if (this.fs.exists(readmePath)) {
259
- const readmeFullContent = this.fs.read(readmePath);
260
- content = readmeFullContent.match(/^<h3[^#*]+([^]+)$/);
261
- if (!content) content = readmeFullContent.match(/^#[^#*]+([^]+)$/);
262
- content = content ? content[1].trim() : readmeFullContent;
263
- }
264
-
265
- copyAndFormatTpl(this.fs, this.templatePath('README.md.ejs'), readmePath, {
266
- projectName: pkg.name,
267
- description: pkg.description,
268
- packages: this.packages,
269
- ci: this.fs.exists(this.destinationPath('.github/workflows/push.yml')),
270
- content,
271
- });
272
- }
273
-
274
- end() {
275
- this.packagePaths.forEach((packagePath) => {
276
- if (
277
- !existsSync(`${packagePath}/.yo-rc.json`) &&
278
- !existsSync(`${packagePath}/.pob.json`)
279
- ) {
280
- return;
281
- }
282
- console.log(`=> update ${packagePath}`);
283
- spawnSync(
284
- process.argv[0],
285
- [
286
- process.argv[1],
287
- 'update',
288
- 'from-pob',
289
- this.options.force ? '--force' : undefined,
290
- ].filter(Boolean),
291
- {
292
- cwd: packagePath,
293
- stdio: 'inherit',
294
- },
295
- );
296
- });
297
-
298
- switch (this.options.packageManager) {
299
- case 'npm':
300
- this.spawnCommandSync('npm', ['install']);
301
- this.spawnCommandSync('npm', ['run', 'preversion']);
302
- break;
303
- case 'yarn':
304
- // see CoreYarnGenerator
305
- break;
306
- }
307
148
  }
308
149
  }
@@ -0,0 +1,236 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { readdirSync, existsSync } from 'node:fs';
3
+ import Generator from 'yeoman-generator';
4
+ import * as packageUtils from '../../../utils/package.js';
5
+ import { copyAndFormatTpl } from '../../../utils/writeAndFormat.js';
6
+
7
+ export default class MonorepoLernaGenerator extends Generator {
8
+ constructor(args, opts) {
9
+ super(args, opts);
10
+
11
+ this.option('isAppProject', {
12
+ type: Boolean,
13
+ default: true,
14
+ desc: 'is app project',
15
+ });
16
+
17
+ this.option('packageManager', {
18
+ type: String,
19
+ default: 'yarn',
20
+ desc: 'yarn or npm',
21
+ });
22
+
23
+ this.option('disableYarnGitCache', {
24
+ type: Boolean,
25
+ required: false,
26
+ default: false,
27
+ desc: 'Disable git cache. See https://yarnpkg.com/features/caching#offline-mirror.',
28
+ });
29
+ }
30
+
31
+ initializing() {
32
+ const pkg = this.fs.readJSON(this.destinationPath('package.json'), {});
33
+ const packagesPaths = pkg.workspaces
34
+ ? pkg.workspaces.map((workspace) => workspace.replace(/\/\*$/, ''))
35
+ : ['packages'];
36
+
37
+ this.packagePaths = packagesPaths.flatMap((packagesPath) =>
38
+ existsSync(`${packagesPath}/`)
39
+ ? readdirSync(`${packagesPath}/`).map(
40
+ (packageName) => `${packagesPath}/${packageName}`,
41
+ )
42
+ : [],
43
+ );
44
+ this.packages = this.packagePaths
45
+ .map((packagePath) =>
46
+ this.fs.readJSON(this.destinationPath(`${packagePath}/package.json`)),
47
+ )
48
+ .filter(Boolean);
49
+ this.packagesConfig = this.packagePaths
50
+ .map((packagePath) =>
51
+ this.fs.readJSON(this.destinationPath(`${packagePath}/.yo-rc.json`)),
52
+ )
53
+ .filter(Boolean);
54
+ }
55
+
56
+ default() {}
57
+
58
+ writing() {
59
+ const getPackagePobConfig = (config) => ({
60
+ babelEnvs: [],
61
+ ...(config && config.pob),
62
+ });
63
+ const withBabel = this.packages.some(
64
+ (config) => getPackagePobConfig(config).babelEnvs.length > 0,
65
+ );
66
+
67
+ // package.json
68
+ const pkg = this.fs.readJSON(this.destinationPath('package.json'), {});
69
+ packageUtils.removeDependencies(pkg, ['@pob/lerna-light']);
70
+
71
+ if (this.npm) {
72
+ if (!pkg.engines) pkg.engines = {};
73
+ pkg.engines.yarn = '< 0.0.0';
74
+ pkg.engines.npm = '>= 6.4.0';
75
+ } else if (pkg.engines) {
76
+ delete pkg.engines.yarn;
77
+ }
78
+
79
+ if (pkg.name === 'pob-monorepo') {
80
+ pkg.devDependencies['@pob/lerna-light'] = 'workspace:*';
81
+ } else {
82
+ packageUtils.addOrRemoveDevDependencies(
83
+ pkg,
84
+ pkg.name !== 'pob-monorepo-test-repository' &&
85
+ pkg.name !== 'use-react-intl-formatters-monorepo',
86
+ // pkg.name !== '@pob/eslint-config-monorepo'
87
+ ['@pob/lerna-light'],
88
+ );
89
+ }
90
+
91
+ const isYarnVersionEnabled = !pkg.devDependencies?.['@pob/lerna-light'];
92
+
93
+ if (pkg.name !== 'pob-monorepo') {
94
+ packageUtils.addDevDependencies(pkg, ['repository-check-dirty']);
95
+ }
96
+
97
+ packageUtils.removeDevDependencies(pkg, ['standard-version']);
98
+
99
+ const monorepoConfig = this.config.get('monorepo');
100
+ const packageManager = this.npm ? 'npm' : 'yarn';
101
+
102
+ packageUtils.addScripts(pkg, {
103
+ lint: `${packageManager} run lint:prettier && ${packageManager} run lint:eslint`,
104
+ 'lint:prettier': 'pob-root-prettier --check .',
105
+ 'lint:prettier:fix': 'pob-root-prettier --write .',
106
+ 'lint:eslint':
107
+ monorepoConfig &&
108
+ monorepoConfig.eslint &&
109
+ this.packagesConfig.length < 50
110
+ ? `${
111
+ this.packagesConfig.length > 15
112
+ ? 'NODE_OPTIONS=--max_old_space_size=4096 '
113
+ : ''
114
+ }eslint --report-unused-disable-directives --resolve-plugins-relative-to . --quiet .`
115
+ : // eslint-disable-next-line unicorn/no-nested-ternary
116
+ this.options.packageManager === 'yarn'
117
+ ? `NODE_OPTIONS=--max_old_space_size=4096 eslint --report-unused-disable-directives --resolve-plugins-relative-to . --quiet . --ignore-pattern ${pkg.workspaces.join(
118
+ ',',
119
+ )} && yarn workspaces foreach --parallel -Av run lint:eslint`
120
+ : 'npm run lint:eslint --workspaces',
121
+ });
122
+
123
+ packageUtils.addOrRemoveScripts(
124
+ pkg,
125
+ this.options.packageManager === 'yarn' && !isYarnVersionEnabled,
126
+ {
127
+ version:
128
+ 'YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn && git add yarn.lock',
129
+ },
130
+ );
131
+
132
+ // TODO rename release (release = version + publish)
133
+ this.fs.copyTpl(
134
+ this.templatePath('workflow-publish.yml.ejs'),
135
+ this.destinationPath('.github/workflows/publish.yml'),
136
+ {
137
+ publish: !this.options.isAppProject,
138
+ enableYarnVersion: isYarnVersionEnabled,
139
+ disableYarnGitCache: this.options.disableYarnGitCache,
140
+ isIndependent: !pkg.version || pkg.version === '0.0.0',
141
+ },
142
+ );
143
+
144
+ packageUtils.removeScripts(
145
+ pkg,
146
+ [pkg.name !== 'pob-dependencies' && 'preversion', 'release'].filter(
147
+ Boolean,
148
+ ),
149
+ );
150
+
151
+ packageUtils.addOrRemoveScripts(pkg, withBabel, {
152
+ build:
153
+ 'yarn workspaces foreach --parallel --topological-dev -Av run build',
154
+ watch:
155
+ 'yarn workspaces foreach --parallel --jobs unlimited --interlaced --exclude "*-example" -Av run watch',
156
+ });
157
+
158
+ // packageUtils.addOrRemoveScripts(pkg, withTypescript, {
159
+ // 'build:definitions': `${
160
+ // useYarnWorkspacesCommand
161
+ // ? 'yarn workspaces foreach --parallel --exclude "*-example" -Av run'
162
+ // : 'lerna run --stream'
163
+ // } build:definitions`,
164
+ // });
165
+
166
+ // if (withTypescript) {
167
+ // pkg.scripts.build += `${packageManager} run build:definitions${
168
+ // useYarnWorkspacesCommand ? '' : ' --since'
169
+ // }`;
170
+ // }
171
+
172
+ delete pkg.scripts.postbuild;
173
+ delete pkg.scripts.prepublishOnly;
174
+
175
+ if (!pkg.workspaces) {
176
+ pkg.workspaces = ['packages/*'];
177
+ }
178
+
179
+ this.fs.writeJSON(this.destinationPath('package.json'), pkg);
180
+
181
+ // README.md
182
+ const readmePath = this.destinationPath('README.md');
183
+
184
+ let content = '';
185
+
186
+ if (this.fs.exists(readmePath)) {
187
+ const readmeFullContent = this.fs.read(readmePath);
188
+ content = readmeFullContent.match(/^<h3[^#*]+([^]+)$/);
189
+ if (!content) content = readmeFullContent.match(/^#[^#*]+([^]+)$/);
190
+ content = content ? content[1].trim() : readmeFullContent;
191
+ }
192
+
193
+ copyAndFormatTpl(this.fs, this.templatePath('README.md.ejs'), readmePath, {
194
+ projectName: pkg.name,
195
+ description: pkg.description,
196
+ packages: this.packages,
197
+ ci: this.fs.exists(this.destinationPath('.github/workflows/push.yml')),
198
+ content,
199
+ });
200
+ }
201
+
202
+ end() {
203
+ this.packagePaths.forEach((packagePath) => {
204
+ if (
205
+ !existsSync(`${packagePath}/.yo-rc.json`) &&
206
+ !existsSync(`${packagePath}/.pob.json`)
207
+ ) {
208
+ return;
209
+ }
210
+ console.log(`=> update ${packagePath}`);
211
+ spawnSync(
212
+ process.argv[0],
213
+ [
214
+ process.argv[1],
215
+ 'update',
216
+ 'from-pob',
217
+ this.options.force ? '--force' : undefined,
218
+ ].filter(Boolean),
219
+ {
220
+ cwd: packagePath,
221
+ stdio: 'inherit',
222
+ },
223
+ );
224
+ });
225
+
226
+ switch (this.options.packageManager) {
227
+ case 'npm':
228
+ this.spawnCommandSync('npm', ['install']);
229
+ this.spawnCommandSync('npm', ['run', 'preversion']);
230
+ break;
231
+ case 'yarn':
232
+ // see CoreYarnGenerator
233
+ break;
234
+ }
235
+ }
236
+ }
@@ -10,7 +10,7 @@
10
10
 
11
11
  <h1>Packages</h1>
12
12
 
13
- This repository is a monorepo that we manage using [Lerna](https://github.com/lerna/lerna).
13
+ This repository is a monorepo that we manage using [Yarn Workspaces](https://yarnpkg.com/features/workspaces).
14
14
 
15
15
  | Package | Version | Description |
16
16
  |---------|---------|-------------|
@@ -1,4 +1,4 @@
1
- name: publish
1
+ name: Release
2
2
  on:
3
3
  workflow_dispatch:
4
4
  inputs:
@@ -20,7 +20,7 @@ on:
20
20
  <% } -%>
21
21
 
22
22
  jobs:
23
- publish:
23
+ release:
24
24
  runs-on: ubuntu-latest
25
25
  steps:
26
26
  - uses: actions/checkout@v4
@@ -136,6 +136,12 @@ export default class PobBaseGenerator extends Generator {
136
136
  });
137
137
 
138
138
  if (this.useLerna) {
139
+ this.composeWith('pob:monorepo:workspaces', {
140
+ force: this.options.force,
141
+ isAppProject: this.projectConfig.type === 'app',
142
+ packageManager: this.projectConfig.packageManager,
143
+ disableYarnGitCache: this.projectConfig.disableYarnGitCache,
144
+ });
139
145
  this.composeWith('pob:monorepo:lerna', {
140
146
  force: this.options.force,
141
147
  isAppProject: this.projectConfig.type === 'app',
package/lib/pob.js CHANGED
@@ -207,6 +207,11 @@ env.registerStub(
207
207
  'pob:lib:readme',
208
208
  `${__dirname}/generators/lib/readme/LibReadmeGenerator.js`,
209
209
  );
210
+ env.registerStub(
211
+ MonorepoLernaGenerator,
212
+ 'pob:monorepo:workspaces',
213
+ `${__dirname}/generators/monorepo/workspaces/MonorepoWorkspacesGenerator.js`,
214
+ );
210
215
  env.registerStub(
211
216
  MonorepoLernaGenerator,
212
217
  'pob:monorepo:lerna',
@@ -315,7 +320,10 @@ if (!existsSync('.yo-rc.json')) {
315
320
  writeFileSync('.yo-rc.json', '{}');
316
321
  }
317
322
 
318
- if (existsSync('lerna.json') || (projectPkg && projectPkg.lerna)) {
323
+ if (
324
+ existsSync('lerna.json') ||
325
+ (projectPkg && (projectPkg.lerna || projectPkg.workspaces))
326
+ ) {
319
327
  monorepo = true;
320
328
  }
321
329
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pob",
3
- "version": "14.1.0",
3
+ "version": "14.3.0",
4
4
  "description": "Pile of bones, library generator with git/babel/typescript/typedoc/readme/jest",
5
5
  "keywords": [
6
6
  "skeleton"
@@ -36,15 +36,16 @@
36
36
  "prettier": "@pob/root/prettier-config",
37
37
  "pob": {},
38
38
  "dependencies": {
39
- "@lerna/package-graph": "5.5.4",
40
- "@lerna/project": "5.5.4",
41
- "@pob/eslint-config": "51.0.0",
42
- "@pob/eslint-config-typescript": "51.0.0",
43
- "@pob/eslint-config-typescript-react": "51.0.0",
39
+ "@pob/eslint-config": "51.0.2",
40
+ "@pob/eslint-config-typescript": "51.0.2",
41
+ "@pob/eslint-config-typescript-react": "51.0.2",
44
42
  "@pob/sort-eslint-config": "5.0.1",
45
43
  "@pob/sort-object": "6.0.1",
46
44
  "@pob/sort-pkg": "6.0.1",
47
45
  "@types/inquirer": "9.0.3",
46
+ "@yarnpkg/cli": "3.6.3",
47
+ "@yarnpkg/core": "3.5.3",
48
+ "@yarnpkg/fslib": "2.10.3",
48
49
  "@yeoman/types": "1.0.1",
49
50
  "eslint": "8.50.0",
50
51
  "findup-sync": "^5.0.0",
@@ -59,13 +60,14 @@
59
60
  "mem-fs-editor": "10.0.2",
60
61
  "minimist": "1.2.8",
61
62
  "parse-author": "2.0.0",
62
- "pob-dependencies": "8.6.0",
63
+ "pob-dependencies": "8.6.1",
63
64
  "prettier": "2.8.8",
64
65
  "semver": "7.5.4",
65
- "yeoman-environment": "4.0.0-beta.4",
66
- "yeoman-generator": "6.0.0-rc.4"
66
+ "yarn-workspace-utils": "1.0.1",
67
+ "yeoman-environment": "4.0.0-beta.5",
68
+ "yeoman-generator": "6.0.0-rc.5"
67
69
  },
68
70
  "devDependencies": {
69
- "@pob/root": "8.3.0"
71
+ "@pob/root": "8.3.2"
70
72
  }
71
73
  }