aberlaas 2.3.0 → 2.5.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/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) {author}
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,43 +1,189 @@
1
1
  import _ from 'golgoth/lodash.js';
2
- import pMapSeries from 'golgoth/pMapSeries.js';
3
2
  import isFile from 'firost/isFile.js';
4
3
  import copy from 'firost/copy.js';
4
+ import move from 'firost/move.js';
5
5
  import readJson from 'firost/readJson.js';
6
6
  import writeJson from 'firost/writeJson.js';
7
- import exists from 'firost/exists.js';
7
+ import firostError from 'firost/error.js';
8
8
  import read from 'firost/read.js';
9
9
  import write from 'firost/write.js';
10
10
  import run from 'firost/run.js';
11
11
  import spinner from 'firost/spinner.js';
12
12
  import helper from '../../helper.js';
13
- import path from 'path';
14
13
  import nodeConfig from '../../configs/node.cjs';
15
14
  import consoleInfo from 'firost/consoleInfo.js';
16
15
  import Gilmore from 'gilmore';
17
16
 
18
17
  export default {
19
18
  /**
20
- * Copy a config template to the host
21
- * @param {string} source Path to source file, relative to aberlaas
22
- * @param {string} destination Path to destination file, relative to the host
23
- * @returns {boolean} False if can't copy file, true otherwise
19
+ * Configure git hooks to use scripts/hooks instead of .git/hooks
24
20
  **/
25
- async copyToHost(source, destination) {
26
- const absoluteSource = helper.aberlaasPath(source);
27
- const absoluteDestination = helper.hostPath(destination);
21
+ async configureGit() {
22
+ const repo = new Gilmore(helper.hostRoot());
23
+ await repo.setConfig('core.hooksPath', 'scripts/hooks');
24
+ },
25
+ /**
26
+ * Pin the node version through nvm
27
+ **/
28
+ async configureNode() {
29
+ const nvmrcPath = helper.hostPath('.nvmrc');
30
+ await write(nodeConfig.nodeVersion, nvmrcPath);
31
+ },
32
+ /**
33
+ * Create the top-level monorepo root workspace
34
+ **/
35
+ async createRootWorkspace() {
36
+ const aberlaasData = await readJson(helper.aberlaasPath('./package.json'));
37
+ const sharedProjectData = await this.getSharedProjectData();
28
38
 
29
- // Source file does not exist
30
- if (!(await isFile(absoluteSource))) {
31
- return false;
32
- }
33
- // Destination file already exist
34
- if (await isFile(absoluteDestination)) {
35
- return false;
36
- }
39
+ const packageContent = {
40
+ // Visibility
41
+ private: true,
42
+ workspaces: ['docs', 'lib'],
37
43
 
38
- await copy(absoluteSource, absoluteDestination);
44
+ // Name and version
45
+ name: `${sharedProjectData.name}-monorepo`,
46
+ version: '0.0.1',
39
47
 
40
- return true;
48
+ // Metadata
49
+ author: sharedProjectData.author,
50
+ description: `${sharedProjectData.name} monorepo`,
51
+ repository: sharedProjectData.repository,
52
+ homepage: sharedProjectData.homepage,
53
+
54
+ // Compatibility
55
+ type: 'module',
56
+ license: sharedProjectData.license,
57
+ packageManager: `yarn@${nodeConfig.yarnVersion}`,
58
+
59
+ // Exports
60
+
61
+ // Dependencies
62
+ dependencies: {},
63
+ devDependencies: {
64
+ aberlaas: aberlaasData.version,
65
+ lerna: nodeConfig.lernaVersion,
66
+ },
67
+
68
+ // Scripts
69
+ scripts: {
70
+ // ==> Docs-specific
71
+ build: './scripts/docs/build',
72
+ 'build:prod': './scripts/docs/build-prod',
73
+ cms: './scripts/docs/cms',
74
+ serve: './scripts/docs/serve',
75
+ // ==> Lib-specific
76
+ release: './scripts/lib/release',
77
+ test: './scripts/lib/test',
78
+ 'test:watch': './scripts/lib/test-watch',
79
+ // Common
80
+ ci: './scripts/ci',
81
+ compress: './scripts/compress',
82
+ lint: './scripts/lint',
83
+ 'lint:fix': './scripts/lint-fix',
84
+
85
+ // Global (called as aliases from any workspace)
86
+ // ==> Docs-specific
87
+ 'g:build': './scripts/docs/build',
88
+ 'g:build:prod': './scripts/docs/build-prod',
89
+ 'g:cms': './scripts/docs/cms',
90
+ 'g:serve': './scripts/docs/serve',
91
+ // ==> Lib-specific
92
+ 'g:release': './scripts/lib/release',
93
+ 'g:test': './scripts/lib/test',
94
+ 'g:test:watch': './scripts/lib/test-watch',
95
+ // Common
96
+ 'g:compress': './scripts/compress',
97
+ 'g:lint': './scripts/lint',
98
+ 'g:lint:fix': './scripts/lint-fix',
99
+ },
100
+ };
101
+ await writeJson(packageContent, helper.hostPath('./package.json'), {
102
+ sort: false,
103
+ });
104
+ },
105
+ /**
106
+ * Create the docs workspace
107
+ **/
108
+ async createDocsWorkspace() {
109
+ const sharedProjectData = await this.getSharedProjectData();
110
+
111
+ const packageContent = {
112
+ // Visibility
113
+ private: true,
114
+
115
+ // Name & Version
116
+ name: `${sharedProjectData.name}-docs`,
117
+ version: '0.0.1',
118
+
119
+ // Metadata
120
+ author: sharedProjectData.author,
121
+ description: `${sharedProjectData.name} docs`,
122
+ repository: sharedProjectData.repository,
123
+ homepage: sharedProjectData.homepage,
124
+
125
+ // Compatibility
126
+ license: sharedProjectData.license,
127
+
128
+ // Exports
129
+
130
+ // Dependencies
131
+ dependencies: {
132
+ norska: nodeConfig.norskaVersion,
133
+ 'norska-theme-docs': nodeConfig.norskaThemeDocsVersion,
134
+ },
135
+ devDependencies: {},
136
+
137
+ // Scripts
138
+ scripts: sharedProjectData.scripts,
139
+ };
140
+ await writeJson(packageContent, helper.hostPath('./docs/package.json'), {
141
+ sort: false,
142
+ });
143
+ },
144
+ /**
145
+ * Create the lib workspace
146
+ **/
147
+ async createLibWorkspace() {
148
+ const sharedProjectData = await this.getSharedProjectData();
149
+
150
+ const packageContent = {
151
+ // Visibility
152
+ private: false,
153
+
154
+ // Name and version
155
+ name: sharedProjectData.name,
156
+ version: '0.0.1',
157
+
158
+ // Metadata
159
+ author: sharedProjectData.author,
160
+ description: '',
161
+ keywords: [],
162
+ repository: sharedProjectData.repository,
163
+ homepage: sharedProjectData.homepage,
164
+
165
+ // Compatibility
166
+ type: 'module',
167
+ license: sharedProjectData.license,
168
+ engines: sharedProjectData.engines,
169
+
170
+ // Exports
171
+ files: ['*.js'],
172
+ exports: {
173
+ '.': './main.js',
174
+ },
175
+ main: './main.js',
176
+
177
+ // Dependencies
178
+ dependencies: {},
179
+ devDependencies: {},
180
+
181
+ // Scripts
182
+ scripts: sharedProjectData.scripts,
183
+ };
184
+ await writeJson(packageContent, helper.hostPath('./lib/package.json'), {
185
+ sort: false,
186
+ });
41
187
  },
42
188
  /**
43
189
  * Add config files to the host. Each config files reference the default
@@ -52,6 +198,9 @@ export default {
52
198
  // Yarn
53
199
  await this.copyToHost('templates/_yarnrc.yml', '.yarnrc.yml');
54
200
 
201
+ // Lerna
202
+ await this.copyToHost('templates/lerna.json', 'lerna.json');
203
+
55
204
  // ESLint
56
205
  await this.copyToHost('templates/_eslintrc.cjs', '.eslintrc.cjs');
57
206
  await this.copyToHost('templates/_eslintignore.conf', '.eslintignore');
@@ -87,198 +236,162 @@ export default {
87
236
  );
88
237
  },
89
238
  /**
90
- * Add scripts entry to the host package.json with specified command.
91
- * @param {string} scriptName Script name
92
- * @param {string} scriptPath Path to the script to run, must be a path
93
- * relative to the templates/ directory
94
- * @returns {boolean} False if can't add entry, true otherwise
239
+ * Add default script files
95
240
  **/
96
- async addPackageScript(scriptName, scriptPath) {
97
- const packagePath = helper.hostPath('package.json');
98
- const currentPackage = await readJson(packagePath);
99
- const currentScripts = _.get(currentPackage, 'scripts', {});
100
-
101
- if (currentScripts[scriptName]) {
102
- return false;
103
- }
104
-
105
- await this.copyToHost(`./templates/${scriptPath}`, scriptPath);
241
+ async addScripts() {
242
+ // Docs
243
+ await this.copyToHost('templates/scripts/docs/build', 'scripts/docs/build');
244
+ await this.copyToHost(
245
+ 'templates/scripts/docs/build-prod',
246
+ 'scripts/docs/build-prod',
247
+ );
248
+ await this.copyToHost('templates/scripts/docs/cms', 'scripts/docs/cms');
249
+ await this.copyToHost('templates/scripts/docs/serve', 'scripts/docs/serve');
106
250
 
107
- const newPackage = _.set(
108
- _.clone(currentPackage),
109
- `scripts.${scriptName}`,
110
- `./${scriptPath}`,
251
+ // Hooks
252
+ await this.copyToHost(
253
+ './templates/scripts/hooks/pre-commit',
254
+ './scripts/hooks/pre-commit',
111
255
  );
112
- await writeJson(newPackage, packagePath);
113
- return true;
114
- },
115
- /**
116
- * Add default scripts to the package.json scripts entry and copy scripts to
117
- * ./scripts if needed
118
- **/
119
- async addScripts() {
120
- const defaultScripts = [
121
- { key: 'ci', value: 'scripts/ci' },
122
- { key: 'compress', value: 'scripts/compress' },
123
- { key: 'lint', value: 'scripts/lint' },
124
- { key: 'lint:fix', value: 'scripts/lint-fix' },
125
- { key: 'release', value: 'scripts/release' },
126
- { key: 'test', value: 'scripts/test' },
127
- { key: 'test:watch', value: 'scripts/test-watch' },
128
- ];
129
-
130
- await pMapSeries(defaultScripts, async (script) => {
131
- await this.addPackageScript(script.key, script.value);
132
- });
133
- },
134
- /**
135
- * Update package.json with .main and .files keys to use files in ./lib
136
- * directory by default
137
- * TODO: Update this to use exports instead of main
138
- **/
139
- async setDefaultReleaseFiles() {
140
- const packagePath = helper.hostPath('package.json');
141
- const currentPackage = await readJson(packagePath);
142
-
143
- // Update .main
144
- const currentMain = currentPackage.main;
145
- const currentMainIsDefault = currentMain === 'index.js';
146
- if (!currentMain || currentMainIsDefault) {
147
- currentPackage.main = 'lib/main.js';
148
- await this.copyToHost('templates/lib/main.js', 'lib/main.js');
149
- await this.copyToHost(
150
- 'templates/lib/__tests__/main.js',
151
- 'lib/__tests__/main.js',
152
- );
153
- }
154
256
 
155
- const currentFiles = currentPackage.files;
156
- const currentFilesIsEmpty = _.isEmpty(currentFiles);
157
- if (!currentFiles || currentFilesIsEmpty) {
158
- currentPackage.files = ['lib/*.js'];
159
- }
257
+ // Lib
258
+ await this.copyToHost(
259
+ 'templates/scripts/lib/release',
260
+ 'scripts/lib/release',
261
+ );
262
+ await this.copyToHost('templates/scripts/lib/test', 'scripts/lib/test');
263
+ await this.copyToHost(
264
+ 'templates/scripts/lib/test-watch',
265
+ 'scripts/lib/test-watch',
266
+ );
160
267
 
161
- await writeJson(currentPackage, packagePath);
268
+ // Common
269
+ await this.copyToHost('templates/scripts/ci', 'scripts/ci');
270
+ await this.copyToHost('templates/scripts/compress', 'scripts/compress');
271
+ await this.copyToHost('templates/scripts/lint', 'scripts/lint');
272
+ await this.copyToHost('templates/scripts/lint-fix', 'scripts/lint-fix');
162
273
  },
163
274
  /**
164
- * Add an MIT LICENSE file to the repository
275
+ * Add MIT license files to the repository
165
276
  **/
166
- async addLicenseFile() {
167
- const licensePath = helper.hostPath('LICENSE');
168
-
169
- if (await exists(licensePath)) {
170
- return;
171
- }
172
-
173
- const template = await read(helper.aberlaasPath('./templates/LICENSE'));
174
- const currentPackage = await readJson(helper.hostPath('package.json'));
277
+ async addLicenseFiles() {
278
+ // Add the LICENSE template to the root
279
+ await this.copyToHost('templates/LICENSE', 'LICENSE');
175
280
 
176
- const content = _.replace(template, '{author}', currentPackage.author);
281
+ // Replace placeholder with real value
282
+ const sharedProjectData = await this.getSharedProjectData();
283
+ const licensePath = helper.hostPath('LICENSE');
284
+ const templateContent = await read(licensePath);
285
+ const actualContent = _.replace(
286
+ templateContent,
287
+ '{author}',
288
+ sharedProjectData.author,
289
+ );
177
290
 
178
- await write(content, licensePath);
291
+ // Write the LICENSE to root and lib
292
+ await write(actualContent, licensePath);
293
+ await write(actualContent, helper.hostPath('lib/LICENSE'));
179
294
  },
180
295
  /**
181
- * Sets license to MIT in package.json
296
+ * Add default files required to have the minimum lib module
182
297
  **/
183
- async addLicenseField() {
184
- const packagePath = helper.hostPath('package.json');
185
- const currentPackage = await readJson(packagePath);
186
-
187
- if (currentPackage.license) {
188
- return;
189
- }
190
-
191
- const newPackage = {
192
- ...currentPackage,
193
- license: 'MIT',
194
- };
195
-
196
- await writeJson(newPackage, packagePath);
298
+ async addLibFiles() {
299
+ await this.copyToHost('templates/lib/main.js', 'lib/main.js');
300
+ await this.copyToHost(
301
+ 'templates/lib/__tests__/main.js',
302
+ 'lib/__tests__/main.js',
303
+ );
197
304
  },
198
305
  /**
199
- * Sets a default 0.0.1 version if none is defined
306
+ * Copy a config template to the host
307
+ * @param {string} source Path to source file, relative to aberlaas
308
+ * @param {string} destination Path to destination file, relative to the host
309
+ * @returns {boolean} False if can't copy file, true otherwise
200
310
  **/
201
- async addDefaultVersion() {
202
- const packagePath = helper.hostPath('package.json');
203
- const currentPackage = await readJson(packagePath);
311
+ async copyToHost(source, destination) {
312
+ const absoluteSource = helper.aberlaasPath(source);
313
+ const absoluteDestination = helper.hostPath(destination);
204
314
 
205
- if (currentPackage.version) {
206
- return;
315
+ // Source file does not exist
316
+ if (!(await isFile(absoluteSource))) {
317
+ throw firostError(
318
+ 'ERROR_INIT_COPY_FILE',
319
+ `Unable to locate ${absoluteSource} file`,
320
+ );
207
321
  }
208
-
209
- const newPackage = {
210
- ...currentPackage,
211
- version: '0.0.1',
212
- };
213
-
214
- await writeJson(newPackage, packagePath);
215
- },
216
- /**
217
- * Sets the minimum node version to run this module
218
- * Which is the same version it has been tested on
219
- **/
220
- async addEngineNodeVersion() {
221
- const packagePath = helper.hostPath('package.json');
222
- const currentPackage = await readJson(packagePath);
223
-
224
- if (_.has(currentPackage, 'engines')) {
225
- return;
322
+ // Destination file already exist
323
+ if (await isFile(absoluteDestination)) {
324
+ // Do nothing if content is already the same
325
+ const sourceContent = await read(absoluteSource);
326
+ const destinationContent = await read(absoluteDestination);
327
+ if (sourceContent === destinationContent) {
328
+ return true;
329
+ }
330
+
331
+ // Otherwise create a backup
332
+ const backupDestination = `${absoluteDestination}.backup`;
333
+ await move(absoluteDestination, backupDestination);
226
334
  }
227
335
 
228
- const newPackage = {
229
- ...currentPackage,
230
- engines: {
231
- node: `>=${nodeConfig.nodeVersion}`,
232
- },
233
- };
336
+ await copy(absoluteSource, absoluteDestination);
234
337
 
235
- await writeJson(newPackage, packagePath);
338
+ return true;
236
339
  },
237
340
  /**
238
- * Sets the dirname as package name if none is defined
341
+ * Return name of the current project based on the GitHub project name
342
+ * @returns {string} Name of the project
239
343
  **/
240
- async addDefaultName() {
241
- const packagePath = helper.hostPath('package.json');
242
- const currentPackage = await readJson(packagePath);
243
-
244
- if (currentPackage.name) {
245
- return;
246
- }
247
-
248
- const newPackage = {
249
- ...currentPackage,
250
- name: path.basename(helper.hostPath()),
251
- };
252
-
253
- await writeJson(newPackage, packagePath);
344
+ async getProjectName() {
345
+ const repo = new Gilmore(helper.hostRoot());
346
+ return await repo.githubRepoName();
254
347
  },
255
348
  /**
256
- * Pin the node version through nvm and yarn through yarnrc
257
- * This allows us to run the same version locally as we do in CI
349
+ * Return the name of the current author based on the GitHub project owner
350
+ * @returns {string} Name of the author
258
351
  **/
259
- async pinNodeAndYarn() {
260
- // Set .nvmrc
261
- const nvmrcPath = helper.hostPath('.nvmrc');
262
- await write(nodeConfig.nodeVersion, nvmrcPath);
263
-
264
- // Download latest yarn version
265
- await this.__run(`yarn set version ${nodeConfig.yarnVersion}`, {
266
- stdout: false,
267
- });
352
+ async getProjectAuthor() {
353
+ const repo = new Gilmore(helper.hostRoot());
354
+ return await repo.githubRepoOwner();
268
355
  },
269
356
  /**
270
- * Configure git hooks to use scripts/hooks instead of .git/hooks
357
+ * Returns shared project data, like name, author, scripts, etc
358
+ * @returns {object} Object of common keys
271
359
  **/
272
- async configureGitHooks() {
273
- // Copy the scripts into ./scripts/hooks
274
- await this.copyToHost(
275
- './templates/scripts/hooks/pre-commit',
276
- './scripts/hooks/pre-commit',
277
- );
278
-
279
- // Configure git to use this directory for hooks
280
- const repo = new Gilmore(helper.hostRoot());
281
- await repo.setConfig('core.hooksPath', 'scripts/hooks');
360
+ async getSharedProjectData() {
361
+ const name = await this.getProjectName();
362
+ const author = await this.getProjectAuthor();
363
+ const homepage = `https://projects.pixelastic.com/${name}`;
364
+ const repository = `${author}/${name}`;
365
+ const license = 'MIT';
366
+ const engines = {
367
+ node: `>=${nodeConfig.nodeVersion}`,
368
+ };
369
+ const scripts = {
370
+ // Docs
371
+ build: 'ABERLAAS_CWD=$INIT_CWD yarn g:build',
372
+ 'build:prod': 'ABERLAAS_CWD=$INIT_CWD yarn g:build:prod',
373
+ cms: 'ABERLAAS_CWD=$INIT_CWD yarn g:cms',
374
+ serve: 'ABERLAAS_CWD=$INIT_CWD yarn g:serve',
375
+
376
+ // Lib
377
+ release: 'ABERLAAS_CWD=$INIT_CWD yarn g:release',
378
+ test: 'ABERLAAS_CWD=$INIT_CWD yarn g:test',
379
+ 'test:watch': 'ABERLAAS_CWD=$INIT_CWD yarn g:test:watch',
380
+
381
+ // Common
382
+ compress: 'ABERLAAS_CWD=$INIT_CWD yarn g:compress',
383
+ lint: 'ABERLAAS_CWD=$INIT_CWD yarn g:lint',
384
+ 'lint:fix': 'ABERLAAS_CWD=$INIT_CWD yarn g:lint:fix',
385
+ };
386
+ return {
387
+ author,
388
+ engines,
389
+ homepage,
390
+ license,
391
+ name,
392
+ repository,
393
+ scripts,
394
+ };
282
395
  },
283
396
  /**
284
397
  * Copy all config files and configure the scripts
@@ -286,34 +399,26 @@ export default {
286
399
  async run() {
287
400
  const progress = spinner();
288
401
 
289
- progress.tick('Configuring Git');
402
+ progress.tick('Configuring Git & Node');
290
403
  await this.configureGit();
404
+ await this.configureNode();
291
405
 
292
- progress.tick('Pinning node and yarn versions');
293
- await this.pinNodeAndYarn();
294
- await this.addEngineNodeVersion();
406
+ progress.tick('Configuring workspaces');
407
+ await this.createRootWorkspace();
408
+ await this.createDocsWorkspace();
409
+ await this.createLibWorkspace();
295
410
 
296
- progress.tick('Adding config files');
411
+ progress.tick('Adding files');
412
+ await this.addLicenseFiles();
297
413
  await this.addConfigFiles();
298
-
299
- progress.tick('Adding yarn scripts');
300
414
  await this.addScripts();
301
-
302
- progress.tick('Updating LICENSE');
303
- await this.addLicenseFile();
304
- await this.addLicenseField();
305
-
306
- progress.tick('Setting default version');
307
- await this.addDefaultVersion();
308
-
309
- progress.tick('Setting default name');
310
- await this.addDefaultName();
311
-
312
- progress.tick('Setting default release files');
313
- await this.setDefaultReleaseFiles();
415
+ await this.addLibFiles();
314
416
 
315
417
  progress.success('aberlaas project initialized');
316
418
 
419
+ this.__consoleInfo('Synchronizing dependencies');
420
+ await run('yarn install');
421
+
317
422
  this.__consoleInfo(
318
423
  "Don't forget to run aberlaas setup after pushing your repository",
319
424
  );
@@ -30,9 +30,10 @@ export default {
30
30
  await pMap(typesToLint, async (type) => {
31
31
  const methodName = cliArgs.fix ? 'fix' : 'run';
32
32
  try {
33
+ const linter = this.linters[type];
34
+
33
35
  const configFile = _.get(cliArgs, `config.${type}`);
34
36
  const userPatterns = _.get(cliArgs, '_');
35
- const linter = this.linters[type];
36
37
 
37
38
  await linter[methodName](userPatterns, configFile);
38
39
  } catch (error) {
@@ -1,4 +1,4 @@
1
- import { createVitest } from 'vitest/node';
1
+ import { createVitest, registerConsoleShortcuts } from 'vitest/node';
2
2
  import helper from '../../helper.js';
3
3
  import firostError from 'firost/error.js';
4
4
  import _ from 'golgoth/lodash.js';
@@ -22,10 +22,16 @@ export default {
22
22
 
23
23
  const vitest = await createVitest('test', options);
24
24
 
25
+ // Enable keyboard interaction in watch mode
26
+ if (options.watch) {
27
+ registerConsoleShortcuts(vitest);
28
+ }
29
+
25
30
  // Note: vitest sets process.exitCode to 1 if tests fail
26
31
  const initialExitCode = process.exitCode;
27
32
  await vitest.start(files);
28
33
 
34
+ // Close vitest if not watching files
29
35
  if (!options.watch) {
30
36
  await vitest.close();
31
37
  }
@@ -19,8 +19,8 @@ module.exports = {
19
19
  ],
20
20
  settings: {
21
21
  // eslint-plugin-import doesn't currently support the "exports" syntax in
22
- // package.json. This allow mapping between custom entrypoints and
23
- // files on disk.
22
+ // package.json. This is supposed to allow mapping between custom
23
+ // entrypoints and files on disk.
24
24
  // For example, it doesn't understand "import * from 'vitest/config';" as
25
25
  // "vitest/config/" isn't really an existing filepath, but a mapping defined
26
26
  // in vitest package.json
@@ -61,6 +61,11 @@ module.exports = {
61
61
  property: 'export',
62
62
  message: 'Typo: Use module.exports instead',
63
63
  },
64
+ {
65
+ object: '_',
66
+ property: 'contains',
67
+ message: 'Typo: Use _.includes instead',
68
+ },
64
69
  ],
65
70
  'no-unused-vars': [
66
71
  'error',
package/configs/node.cjs CHANGED
@@ -3,4 +3,7 @@
3
3
  module.exports = {
4
4
  nodeVersion: '18.18.0', // Also see templates/_circleci/config.yml
5
5
  yarnVersion: '4.0.2',
6
+ norskaVersion: '2.9.0',
7
+ norskaThemeDocsVersion: '5.0.3',
8
+ lernaVersion: '4.0.0',
6
9
  };
package/helper.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import path from 'path';
2
2
  import _ from 'golgoth/lodash.js';
3
- import run from 'firost/run.js';
4
3
  import glob from 'firost/glob.js';
5
4
  import exists from 'firost/exists.js';
6
5
  import findUp from 'find-up';
@@ -151,14 +150,6 @@ export default {
151
150
  }
152
151
  return false;
153
152
  },
154
- /**
155
- * Run a specific script through yarn run
156
- * @param {string} scriptName Name of the script to run
157
- * @returns {object} Result of the run, including .sterr and .stdout
158
- **/
159
- async yarnRun(scriptName) {
160
- return await run(`yarn run ${scriptName}`, { cwd: this.hostRoot() });
161
- },
162
153
  /**
163
154
  * Dynamically import a file
164
155
  * This is a wrapper around the default import, but bypasses the cache
package/main.js CHANGED
@@ -1,7 +1,10 @@
1
1
  import minimist from 'minimist';
2
2
  import consoleError from 'firost/consoleError.js';
3
3
  import exit from 'firost/exit.js';
4
+ import env from 'firost/env.js';
5
+ import absolute from 'firost/absolute.js';
4
6
  import _ from 'golgoth/lodash.js';
7
+ import path from 'path';
5
8
  import commandCi from './commands/ci/index.js';
6
9
  import commandCompress from './commands/compress/index.js';
7
10
  import commandInit from './commands/init/index.js';
@@ -28,6 +31,30 @@ export default {
28
31
  test: commandTest,
29
32
  };
30
33
  },
34
+ /**
35
+ * Converts a list of filepaths to absolute filepaths
36
+ * Note: We want to be able to call commands like "aberlaas lint" from the
37
+ * workspace root or any child workspace. We also want to be able to use
38
+ * relative or absolute filepaths as arguments.
39
+ * INIT_CWD is always set to the directory where the command was called, but
40
+ * because scripts in child workspaces are actually calling scripts in the
41
+ * root workspace, that value is overwritten. This is why we save the original
42
+ * calling directory in ABERLAAS_CWD, and use that value if available.
43
+ * @param {Array} filepaths Array of filepaths
44
+ * @returns {Array} Array of absolute filepaths
45
+ **/
46
+ convertFilepathsToAbsolute(filepaths) {
47
+ const callingDirectory =
48
+ this.__env('ABERLAAS_CWD') || this.__env('INIT_CWD');
49
+ return _.map(filepaths, (inputFilepath) => {
50
+ const filepath =
51
+ inputFilepath[0] == '/'
52
+ ? inputFilepath
53
+ : path.resolve(callingDirectory, inputFilepath);
54
+
55
+ return absolute(filepath);
56
+ });
57
+ },
31
58
  /**
32
59
  * Run the command specified on the command-line, along with specific
33
60
  * arguments
@@ -49,6 +76,9 @@ export default {
49
76
  // Remove the initial method from args passed to the command
50
77
  args._ = _.drop(args._, 1);
51
78
 
79
+ // Make all filepaths absolute
80
+ args._ = this.convertFilepathsToAbsolute(args._);
81
+
52
82
  try {
53
83
  await command.run(args);
54
84
  } catch (err) {
@@ -56,6 +86,7 @@ export default {
56
86
  this.__exit(1);
57
87
  }
58
88
  },
89
+ __env: env,
59
90
  __consoleError: consoleError,
60
91
  __exit: exit,
61
92
  };
package/package.json CHANGED
@@ -2,16 +2,13 @@
2
2
  "name": "aberlaas",
3
3
  "type": "module",
4
4
  "description": "Scaffold your JavaScript projects with tests, lint and release scripts",
5
- "version": "2.3.0",
5
+ "version": "2.5.0",
6
6
  "repository": "pixelastic/aberlaas",
7
7
  "homepage": "https://projects.pixelastic.com/aberlaas/",
8
8
  "author": "Tim Carry (@pixelastic)",
9
9
  "license": "MIT",
10
10
  "files": [
11
11
  "bin/",
12
- "lib/",
13
- "scripts/",
14
- "*.js",
15
12
  "commands/ci/*.js",
16
13
  "commands/compress/*.js",
17
14
  "commands/init/*.js",
@@ -19,61 +16,66 @@
19
16
  "commands/lint/helpers/*.js",
20
17
  "commands/precommit/*.js",
21
18
  "commands/readme/*.js",
22
- "commands/release/*.js",
23
19
  "commands/setup/*.js",
24
20
  "commands/setup/helpers/*.js",
25
21
  "commands/test/*.js",
26
22
  "configs/",
27
- "templates/"
23
+ "scripts/",
24
+ "templates/",
25
+ "*.js"
28
26
  ],
29
27
  "exports": {
30
28
  ".": "./main.js",
29
+ "./configs/vite": "./configs/vite.js",
31
30
  "./configs/lintstaged": "./configs/lintstaged.js",
32
31
  "./configs/prettier": "./configs/prettier.js",
33
32
  "./configs/stylelint": "./configs/stylelint.js"
34
33
  },
34
+ "main": "./main.js",
35
35
  "bin": "bin/aberlaas.js",
36
36
  "dependencies": {
37
37
  "@octokit/rest": "18.12.0",
38
38
  "ci-info": "3.9.0",
39
39
  "dedent": "1.5.1",
40
- "eslint": "8.56.0",
41
- "eslint-config-prettier": "9.0.0",
42
- "eslint-plugin-import": "2.29.0",
43
- "eslint-plugin-jsdoc": "46.9.0",
44
- "eslint-plugin-n": "16.3.1",
45
- "eslint-plugin-prettier": "5.0.1",
46
- "eslint-plugin-vitest": "0.3.10",
40
+ "eslint": "8.57.0",
41
+ "eslint-config-prettier": "9.1.0",
42
+ "eslint-plugin-import": "2.29.1",
43
+ "eslint-plugin-jsdoc": "46.10.1",
44
+ "eslint-plugin-n": "16.6.2",
45
+ "eslint-plugin-prettier": "5.1.3",
46
+ "eslint-plugin-vitest": "0.3.22",
47
47
  "eslint-plugin-vitest-globals": "1.4.0",
48
48
  "find-up": "5.0.0",
49
49
  "firost": "3.1.0",
50
50
  "front-matter": "4.0.2",
51
- "gilmore": "0.1.0",
51
+ "gilmore": "0.2.0",
52
52
  "golgoth": "2.1.0",
53
53
  "jest-extended": "4.0.2",
54
54
  "lint-staged": "11.2.6",
55
55
  "minimist": "1.2.8",
56
56
  "np": "7.7.0",
57
57
  "parse-github-repo-url": "1.4.1",
58
- "prettier": "3.1.0",
58
+ "prettier": "3.2.5",
59
59
  "std-mocks": "1.0.1",
60
60
  "stylelint": "13.13.1",
61
- "vitest": "1.0.4",
61
+ "vitest": "1.3.1",
62
62
  "yaml-lint": "1.7.0"
63
63
  },
64
64
  "engines": {
65
65
  "node": ">=18"
66
66
  },
67
67
  "scripts": {
68
- "build": "../scripts/docs/build",
69
- "build:prod": "../scripts/docs/build-prod",
70
- "lint": "../scripts/lib/lint",
71
- "lint:fix": "../scripts/lib/lint-fix",
72
- "release": "../scripts/release",
73
- "serve": "../scripts/docs/serve",
74
- "test": "../scripts/lib/test",
75
- "test:watch": "../scripts/lib/test-watch",
68
+ "build": "ABERLAAS_CWD=$INIT_CWD yarn g:build",
69
+ "build:prod": "ABERLAAS_CWD=$INIT_CWD yarn g:build:prod",
70
+ "cms": "ABERLAAS_CWD=$INIT_CWD yarn g:cms",
71
+ "serve": "ABERLAAS_CWD=$INIT_CWD yarn g:serve",
72
+ "release": "ABERLAAS_CWD=$INIT_CWD yarn g:release",
73
+ "test": "ABERLAAS_CWD=$INIT_CWD yarn g:test",
74
+ "test:watch": "ABERLAAS_CWD=$INIT_CWD yarn g:test:watch",
75
+ "compress": "ABERLAAS_CWD=$INIT_CWD yarn g:compress",
76
+ "lint": "ABERLAAS_CWD=$INIT_CWD yarn g:lint",
77
+ "lint:fix": "ABERLAAS_CWD=$INIT_CWD yarn g:lint:fix",
76
78
  "postinstall": "./scripts/postinstall"
77
79
  },
78
- "gitHead": "cca93623a1219558bd311aefde796d75d6790009"
80
+ "gitHead": "d8c221450f847e80e4b86783b9291f3e02239a45"
79
81
  }
@@ -1,3 +1,4 @@
1
- # Yarn
2
- /.yarn/releases/** binary
3
- /.yarn/plugins/** binary
1
+ /.yarn/** linguist-vendored
2
+ /.yarn/releases/* binary
3
+ /.yarn/plugins/**/* binary
4
+ /.pnp.* binary linguist-generated
@@ -10,6 +10,7 @@ tmp/
10
10
 
11
11
  # Files
12
12
  Thumbs.db
13
+ lerna-debug.log
13
14
  npm-debug.log
14
15
  yarn-error.log
15
16
  *~
@@ -4,6 +4,12 @@ defaultSemverRangePrefix: ''
4
4
 
5
5
  enableGlobalCache: true
6
6
 
7
+ # Keep old-school saving of dependencies in node_modules
8
+ # This makes debugging imported modules so much easier
9
+ nodeLinker: node-modules
10
+
11
+ # Use hardlinks to a global cache
7
12
  nmMode: hardlinks-local
8
13
 
9
- nodeLinker: node-modules
14
+ # Make sure each workspace has its own local node_modules
15
+ nmHoistingLimits: workspaces
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": "0.0.1",
3
+ "useWorkspaces": true,
4
+ "packages": ["lib", "docs"],
5
+ "npmClient": "yarn"
6
+ }
@@ -1,11 +1,13 @@
1
1
  import current from '../main.js';
2
2
 
3
- describe('current', () => {
4
- it('should do something', async () => {
5
- const input = 'foo';
3
+ describe('main', () => {
4
+ describe('run', () => {
5
+ it('should pass', async () => {
6
+ const input = 'something';
6
7
 
7
- const actual = current.run(input);
8
+ const actual = current.run(input);
8
9
 
9
- expect(actual).toBe(true);
10
+ expect(actual).toBe('something');
11
+ });
10
12
  });
11
13
  });
@@ -1,5 +1,5 @@
1
1
  export default {
2
- run() {
3
- return true;
2
+ run(input) {
3
+ return input;
4
4
  },
5
5
  };
@@ -1,4 +1,6 @@
1
- #!/usr/bin/env sh
1
+ #!/usr/bin/env bash
2
2
  set -e
3
3
 
4
+ echo "node $(node --version), yarn $(yarn --version)"
5
+
4
6
  aberlaas ci "$@"
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env sh
1
+ #!/usr/bin/env bash
2
2
  set -e
3
3
 
4
- aberlaas compress "$@"
4
+ aberlaas compress "${@:-$INIT_CWD}"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ echo "TODO: Set a default script"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ echo "TODO: Set a default script"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ echo "TODO: Set a default script"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ echo "TODO: Set a default script"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ yarn run test
5
+ lerna publish --yes "$@"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ aberlaas test "${@:-./lib}"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ aberlaas test --watch "${@:-./lib}"
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env sh
1
+ #!/usr/bin/env bash
2
2
  set -e
3
3
 
4
- aberlaas lint "$@"
4
+ aberlaas lint "${@:-$INIT_CWD}"
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env sh
1
+ #!/usr/bin/env bash
2
2
  set -e
3
3
 
4
- aberlaas lint "$@" --fix
4
+ aberlaas lint --fix "${@:-$INIT_CWD}"
@@ -1,4 +1,4 @@
1
- import viteConfig from 'aberlaas/configs/vite.js';
1
+ import config from 'aberlaas/configs/vite';
2
2
  export default {
3
- ...viteConfig,
3
+ ...config,
4
4
  };
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env sh
2
- set -e
3
-
4
- aberlaas release "$@"
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env sh
2
- set -e
3
-
4
- aberlaas test "$@"
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env sh
2
- set -e
3
-
4
- aberlaas test "$@" --watch