aberlaas 2.7.0 → 2.9.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.
@@ -0,0 +1,261 @@
1
+ import { readJson, writeJson } from 'firost';
2
+
3
+ import helper from '../../helper.js';
4
+ import nodeConfig from '../../configs/node.cjs';
5
+ import initHelper from './helper.js';
6
+
7
+ export default {
8
+ /**
9
+ * Create the top-level monorepo root workspace
10
+ **/
11
+ async createRootWorkspace() {
12
+ const aberlaasData = await readJson(helper.aberlaasPath('./package.json'));
13
+ const sharedProjectData = await this.getSharedProjectData();
14
+
15
+ const packageContent = {
16
+ // Visibility
17
+ private: true,
18
+ workspaces: ['docs', 'lib'],
19
+
20
+ // Name and version
21
+ name: `${sharedProjectData.name}-monorepo`,
22
+ version: '0.0.1',
23
+
24
+ // Metadata
25
+ author: sharedProjectData.author,
26
+ description: `${sharedProjectData.name} monorepo`,
27
+ repository: sharedProjectData.repository,
28
+ homepage: sharedProjectData.homepage,
29
+
30
+ // Compatibility
31
+ type: 'module',
32
+ license: sharedProjectData.license,
33
+ packageManager: `yarn@${nodeConfig.yarnVersion}`,
34
+
35
+ // Exports
36
+
37
+ // Dependencies
38
+ dependencies: {},
39
+ devDependencies: {
40
+ aberlaas: aberlaasData.version,
41
+ lerna: nodeConfig.lernaVersion,
42
+ },
43
+
44
+ // Scripts
45
+ scripts: {
46
+ // ==> Docs-specific
47
+ build: './scripts/docs/build',
48
+ 'build:prod': './scripts/docs/build-prod',
49
+ cms: './scripts/docs/cms',
50
+ serve: './scripts/docs/serve',
51
+ // ==> Lib-specific
52
+ release: './scripts/lib/release',
53
+ test: './scripts/lib/test',
54
+ 'test:watch': './scripts/lib/test-watch',
55
+ // Common
56
+ ci: './scripts/ci',
57
+ compress: './scripts/compress',
58
+ lint: './scripts/lint',
59
+ 'lint:fix': './scripts/lint-fix',
60
+
61
+ // Global (called as aliases from any workspace)
62
+ // ==> Docs-specific
63
+ 'g:build': './scripts/docs/build',
64
+ 'g:build:prod': './scripts/docs/build-prod',
65
+ 'g:cms': './scripts/docs/cms',
66
+ 'g:serve': './scripts/docs/serve',
67
+ // ==> Lib-specific
68
+ 'g:release': './scripts/lib/release',
69
+ 'g:test': './scripts/lib/test',
70
+ 'g:test:watch': './scripts/lib/test-watch',
71
+ // Common
72
+ 'g:compress': './scripts/compress',
73
+ 'g:lint': './scripts/lint',
74
+ 'g:lint:fix': './scripts/lint-fix',
75
+ },
76
+ };
77
+ await writeJson(packageContent, helper.hostPath('./package.json'), {
78
+ sort: false,
79
+ });
80
+ },
81
+ /**
82
+ * Create the docs workspace
83
+ **/
84
+ async createDocsWorkspace() {
85
+ const sharedProjectData = await this.getSharedProjectData();
86
+
87
+ const packageContent = {
88
+ // Visibility
89
+ private: true,
90
+
91
+ // Name & Version
92
+ name: `${sharedProjectData.name}-docs`,
93
+ version: '0.0.1',
94
+
95
+ // Metadata
96
+ author: sharedProjectData.author,
97
+ description: `${sharedProjectData.name} docs`,
98
+ repository: sharedProjectData.repository,
99
+ homepage: sharedProjectData.homepage,
100
+
101
+ // Compatibility
102
+ license: sharedProjectData.license,
103
+
104
+ // Exports
105
+
106
+ // Dependencies
107
+ dependencies: {
108
+ norska: nodeConfig.norskaVersion,
109
+ 'norska-theme-docs': nodeConfig.norskaThemeDocsVersion,
110
+ },
111
+ devDependencies: {},
112
+
113
+ // Scripts
114
+ scripts: sharedProjectData.scripts,
115
+ };
116
+ await writeJson(packageContent, helper.hostPath('./docs/package.json'), {
117
+ sort: false,
118
+ });
119
+ },
120
+ /**
121
+ * Create the lib workspace
122
+ **/
123
+ async createLibWorkspace() {
124
+ const sharedProjectData = await this.getSharedProjectData();
125
+ const engines = {
126
+ node: `>=${nodeConfig.nodeVersion}`,
127
+ };
128
+
129
+ const packageContent = {
130
+ // Visibility
131
+ private: false,
132
+
133
+ // Name and version
134
+ name: sharedProjectData.name,
135
+ version: '0.0.1',
136
+
137
+ // Metadata
138
+ author: sharedProjectData.author,
139
+ description: '',
140
+ keywords: [],
141
+ repository: sharedProjectData.repository,
142
+ homepage: sharedProjectData.homepage,
143
+
144
+ // Compatibility
145
+ type: 'module',
146
+ license: sharedProjectData.license,
147
+ engines,
148
+
149
+ // Exports
150
+ files: ['*.js'],
151
+ exports: {
152
+ '.': './main.js',
153
+ },
154
+ main: './main.js',
155
+
156
+ // Dependencies
157
+ dependencies: {},
158
+ devDependencies: {},
159
+
160
+ // Scripts
161
+ scripts: sharedProjectData.scripts,
162
+ };
163
+ await writeJson(packageContent, helper.hostPath('./lib/package.json'), {
164
+ sort: false,
165
+ });
166
+ },
167
+ /**
168
+ * Add MIT license files to the repository
169
+ **/
170
+ async addLicenseFiles() {
171
+ // One at the repo root, for GitHub
172
+ await initHelper.addLicenseFile('LICENSE');
173
+ // One in ./lib to be released with the module
174
+ await initHelper.addLicenseFile('lib/LICENSE');
175
+ },
176
+ /**
177
+ * Add config files
178
+ **/
179
+ async addConfigFiles() {
180
+ await initHelper.addConfigFiles();
181
+
182
+ // Lerna
183
+ await initHelper.copyToHost('templates/lerna.json', 'lerna.json');
184
+ },
185
+ /**
186
+ * Add scripts to the repo
187
+ **/
188
+ async addScripts() {
189
+ // Common scripts
190
+ await initHelper.addScripts('LICENSE');
191
+
192
+ // Docs scripts
193
+ await initHelper.copyToHost(
194
+ 'templates/scripts/docs/build',
195
+ 'scripts/docs/build',
196
+ );
197
+ await initHelper.copyToHost(
198
+ 'templates/scripts/docs/build-prod',
199
+ 'scripts/docs/build-prod',
200
+ );
201
+ await initHelper.copyToHost(
202
+ 'templates/scripts/docs/cms',
203
+ 'scripts/docs/cms',
204
+ );
205
+ await initHelper.copyToHost(
206
+ 'templates/scripts/docs/serve',
207
+ 'scripts/docs/serve',
208
+ );
209
+ },
210
+ /**
211
+ * Returns shared project data, like name, author, scripts, etc
212
+ * @returns {object} Object of common keys
213
+ **/
214
+ async getSharedProjectData() {
215
+ const name = await this.__getProjectName();
216
+ const author = await this.__getProjectAuthor();
217
+ const homepage = `https://projects.pixelastic.com/${name}`;
218
+ const repository = `${author}/${name}`;
219
+ const license = 'MIT';
220
+ const scripts = {
221
+ // Docs
222
+ build: 'ABERLAAS_CWD=$INIT_CWD yarn g:build',
223
+ 'build:prod': 'ABERLAAS_CWD=$INIT_CWD yarn g:build:prod',
224
+ cms: 'ABERLAAS_CWD=$INIT_CWD yarn g:cms',
225
+ serve: 'ABERLAAS_CWD=$INIT_CWD yarn g:serve',
226
+
227
+ // Lib
228
+ release: 'ABERLAAS_CWD=$INIT_CWD yarn g:release',
229
+ test: 'ABERLAAS_CWD=$INIT_CWD yarn g:test',
230
+ 'test:watch': 'ABERLAAS_CWD=$INIT_CWD yarn g:test:watch',
231
+
232
+ // Common
233
+ compress: 'ABERLAAS_CWD=$INIT_CWD yarn g:compress',
234
+ lint: 'ABERLAAS_CWD=$INIT_CWD yarn g:lint',
235
+ 'lint:fix': 'ABERLAAS_CWD=$INIT_CWD yarn g:lint:fix',
236
+ };
237
+ return {
238
+ author,
239
+ homepage,
240
+ license,
241
+ name,
242
+ repository,
243
+ scripts,
244
+ };
245
+ },
246
+ /**
247
+ * Scaffold a repo for use in a monorepo module contexte
248
+ **/
249
+ async run() {
250
+ await this.createRootWorkspace();
251
+ await this.createDocsWorkspace();
252
+ await this.createLibWorkspace();
253
+
254
+ await this.addLicenseFiles();
255
+ await this.addScripts();
256
+ await this.addConfigFiles();
257
+ await initHelper.addLibFiles();
258
+ },
259
+ __getProjectName: initHelper.getProjectName,
260
+ __getProjectAuthor: initHelper.getProjectAuthor.bind(initHelper),
261
+ };
@@ -15,6 +15,9 @@ export default {
15
15
  try {
16
16
  const result = await lintStaged({
17
17
  config,
18
+ // Allow use extended shell syntax in config, like pipes, redirects or
19
+ // env variables
20
+ shell: true,
18
21
  });
19
22
  // Linting failed
20
23
  if (!result) {
@@ -18,27 +18,45 @@ export default {
18
18
  **/
19
19
  async run(cliArgs = {}) {
20
20
  const options = await this.vitestOptions(cliArgs);
21
- const files = _.isEmpty(cliArgs._) ? [helper.hostPath()] : cliArgs._;
21
+ const isWatchMode = !!options.watch;
22
+ const isRelatedMode = options.related?.length > 0;
23
+ let files = _.isEmpty(cliArgs._) ? [helper.hostPath()] : cliArgs._;
24
+ // If --related is passed, the list of files will already by in the .related
25
+ // key, and need to be removed from the files
26
+ if (isRelatedMode) files = [];
27
+
28
+ // Vitest will change process.exitCode, so we save it to revert it later
29
+ const initialExitCode = process.exitCode;
22
30
 
23
31
  const vitest = await createVitest('test', options);
24
32
 
25
33
  // Enable keyboard interaction in watch mode
26
- if (options.watch) {
34
+ if (isWatchMode) {
27
35
  registerConsoleShortcuts(vitest);
28
36
  }
29
37
 
30
- // Note: vitest sets process.exitCode to 1 if tests fail
31
- const initialExitCode = process.exitCode;
32
- await vitest.start(files);
38
+ try {
39
+ await vitest.start(files);
40
+ } catch (err) {
41
+ // We can safely swallow the VITEST_FILES_NOT_FOUND error. It's ok to
42
+ // continue if no files are found
43
+ if (err.code != 'VITEST_FILES_NOT_FOUND') {
44
+ throw err;
45
+ }
46
+ }
33
47
 
34
- // Close vitest if not watching files
35
- if (!options.watch) {
36
- await vitest.close();
48
+ const testsAreFailing = process.exitCode == 1;
49
+ process.exitCode = initialExitCode;
50
+
51
+ if (isWatchMode) {
52
+ return;
37
53
  }
38
54
 
39
- if (process.exitCode == 1) {
40
- process.exitCode = initialExitCode;
41
- throw firostError('ERROR_TEST', 'Error while testing files');
55
+ // Stop vitest, it doesn't stop itself by default
56
+ await vitest.close();
57
+
58
+ if (testsAreFailing) {
59
+ throw firostError('ERROR_TEST_FAIL', 'Tests are failing');
42
60
  }
43
61
 
44
62
  return true;
@@ -52,7 +70,13 @@ export default {
52
70
  async vitestOptions(cliArgs = {}) {
53
71
  // Options that have special meaning in aberlaas and shouldn't be passed
54
72
  // as-is to vitest
55
- const specialMeaningCliArgs = ['_', 'config', 'failFast', 'related'];
73
+ const specialMeaningCliArgs = [
74
+ '_',
75
+ 'config',
76
+ 'failFast',
77
+ 'related',
78
+ 'exclude',
79
+ ];
56
80
 
57
81
  // Reading base options from the config file
58
82
  const configFile = await helper.configFile(
@@ -73,11 +97,20 @@ export default {
73
97
  optionsFromAberlaas.bail = 1;
74
98
  }
75
99
  // --related runs also related files
76
- // Note (2024-01-19): The related option is not documented, but should
77
- // contain the list of files
100
+ // Note (2024-10-01): The related option is not documented, but should
101
+ // contain the list of files.
78
102
  if (cliArgs.related) {
79
103
  optionsFromAberlaas.related = cliArgs._;
80
104
  }
105
+ // --exclude arguments should be added to the existing list of exclude
106
+ // patterns
107
+ // TODO: Add test for that
108
+ if (cliArgs.exclude) {
109
+ optionsFromAberlaas.exclude = [
110
+ ...optionsFromConfig.exclude,
111
+ cliArgs.exclude,
112
+ ];
113
+ }
81
114
 
82
115
  // Passing other CLI options directly to vitest
83
116
  const optionsFromCli = _.omit(cliArgs, specialMeaningCliArgs);
@@ -134,6 +134,11 @@ module.exports = {
134
134
  { name: 'xit', message: 'No skipped test' },
135
135
  { name: 'xdescribe', message: 'No skipped tests' },
136
136
  ],
137
+ // In tests, we like to have the variable 'current' hold the object
138
+ // under test. The import/no-named-as-default-member would have warned
139
+ // us about using current.foo rather than foo directly, so we disable
140
+ // it.
141
+ 'import/no-named-as-default-member': ['off'],
137
142
  'vitest/consistent-test-it': ['warn', { fn: 'it' }],
138
143
  // Disabling vitest/no-identical-title
139
144
  // It can make eslint crash when used with fit/xit/fdescribe/xdescribe
@@ -12,7 +12,7 @@ export default {
12
12
  '*.js': ['yarn run lint:fix --js'],
13
13
 
14
14
  // Test
15
- './lib/**/*.js': ['yarn run test --failFast --related'],
15
+ './lib/**/*.js': ['FORCE_COLOR=1 yarn run test --failFast --related'],
16
16
 
17
17
  // Compress
18
18
  '*.png': ['yarn run compress --png'],
package/configs/vite.js CHANGED
@@ -1,4 +1,6 @@
1
- import { configDefaults, defineConfig } from 'vitest/config';
1
+ import { defaultExclude, defineConfig } from 'vitest/config';
2
+
3
+ const aberlaasVitestExclude = [...defaultExclude, '**/tmp/**'];
2
4
 
3
5
  const configDir = new URL('./vite/', import.meta.url).pathname;
4
6
 
@@ -14,8 +16,7 @@ export default defineConfig({
14
16
  // Tests should be in a __tests__ folder next to their code
15
17
  include: ['**/__tests__/**/*.js?(x)'],
16
18
  // We ignore temporary folders from the tests
17
- exclude: [...configDefaults.exclude, '**/tmp/**'],
18
- watchExclude: [...configDefaults.watchExclude, '**/tmp/**'],
19
+ exclude: aberlaasVitestExclude,
19
20
  // Restore mocks after each tests
20
21
  restoreMocks: true,
21
22
 
@@ -30,4 +31,12 @@ export default defineConfig({
30
31
  `${configDir}/test/setupFiles/testName.js`,
31
32
  ],
32
33
  },
34
+ server: {
35
+ watch: {
36
+ // Vitest 2.0 uses vite watcher, so files to exclude from watching are at
37
+ // the server level
38
+ // Source: https://vitest.dev/guide/migration.html#removal-of-the-watchexclude-option
39
+ ignored: aberlaasVitestExclude,
40
+ },
41
+ },
33
42
  });
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "aberlaas",
3
3
  "type": "module",
4
4
  "description": "Scaffold your JavaScript projects with tests, lint and release scripts",
5
- "version": "2.7.0",
5
+ "version": "2.9.0",
6
6
  "repository": "pixelastic/aberlaas",
7
7
  "homepage": "https://projects.pixelastic.com/aberlaas/",
8
8
  "author": "Tim Carry (@pixelastic)",
@@ -58,7 +58,7 @@
58
58
  "prettier": "3.2.5",
59
59
  "std-mocks": "1.0.1",
60
60
  "stylelint": "13.13.1",
61
- "vitest": "1.4.0",
61
+ "vitest": "2.1.1",
62
62
  "yaml-lint": "1.7.0"
63
63
  },
64
64
  "engines": {
@@ -72,10 +72,11 @@
72
72
  "release": "ABERLAAS_CWD=$INIT_CWD yarn g:release",
73
73
  "test": "ABERLAAS_CWD=$INIT_CWD yarn g:test",
74
74
  "test:watch": "ABERLAAS_CWD=$INIT_CWD yarn g:test:watch",
75
+ "test:meta": "ABERLAAS_CWD=$INIT_CWD yarn g:test:meta",
75
76
  "compress": "ABERLAAS_CWD=$INIT_CWD yarn g:compress",
76
77
  "lint": "ABERLAAS_CWD=$INIT_CWD yarn g:lint",
77
78
  "lint:fix": "ABERLAAS_CWD=$INIT_CWD yarn g:lint:fix",
78
79
  "postinstall": "./scripts/postinstall"
79
80
  },
80
- "gitHead": "901e0aff17a63a548edcba92d984c8610d6e4362"
81
+ "gitHead": "26cb1b6e33199730ccfb693ef92584f35cfa2aea"
81
82
  }
@@ -3,12 +3,20 @@ version: 2.1
3
3
  aliases:
4
4
  - &defaults
5
5
  docker:
6
- - image: cimg/node:18.18.0
6
+ - image: cimg/node:{nodeVersion}
7
7
  - &restore_cache
8
8
  restore_cache:
9
9
  key: yarn-cache-{{ checksum "yarn.lock" }}
10
- - &yarn_install
11
- run: 'yarn install'
10
+ - &install_yarn
11
+ run:
12
+ name: 'Installing correct yarn version'
13
+ command: |
14
+ corepack enable --install-directory="/home/circleci/bin"
15
+ yarn set version {yarnVersion}
16
+ - &install_dependencies
17
+ run:
18
+ name: 'Installing dependencies'
19
+ command: 'yarn install'
12
20
  - &save_cache
13
21
  save_cache:
14
22
  key: yarn-cache-{{ checksum "yarn.lock" }}
@@ -21,7 +29,8 @@ jobs:
21
29
  steps:
22
30
  - checkout
23
31
  - *restore_cache
24
- - *yarn_install
32
+ - *install_yarn
33
+ - *install_dependencies
25
34
  - *save_cache
26
35
  - run: 'yarn run ci'
27
36