aberlaas 2.7.0 → 2.8.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 CHANGED
@@ -161,6 +161,24 @@ what most free CI tier offer). If you have access to higher end machines, you
161
161
  can update this value by passing the `--cpu-count=X` flag to your `aberlaas ci`
162
162
  call.
163
163
 
164
+ ### Auto-Releasing
165
+
166
+ As an optional feature, you can have aberlaas automatically release a new
167
+ version of your module from the CI environment when relevant.
168
+
169
+ The CI will then check all the commits since the last release. If any commit is
170
+ a `feat()` it will release a new minor version; it any commit is a `fix()` it
171
+ will release a new patch version. For major release, you'll have to do it
172
+ manually.
173
+
174
+ This option is not enabled by default. If you need it, you need to follow those
175
+ steps:
176
+
177
+ - Run `aberlaas setup --auto-release`. It will setup the required `ENV` variables
178
+ and ssh keys
179
+ - Update your `aberlaas ci` script to `aberlaas ci --auto-release`
180
+ - Uncomment the `add_ssh_keys` in your `.circleci.yml` file
181
+
164
182
  ## File structure
165
183
 
166
184
  `./lib/configs` contain the default configuration for all the tools. They are
@@ -170,133 +188,10 @@ exported by the package and thus can be `require`d in userland.
170
188
  extends the configuration exported in the previous files. Copying files to
171
189
  userland allows user to change the files if they want to change the behavior.
172
190
 
173
- `.eslintrc.js`, `stylelint.config.js` and `vite.config.js` are local
191
+ `.eslintrc.js`, `.stylelintrc.js` and `jest.config.js` are local
174
192
  configuration files for `aberlaas` itself. They eat their own dog food by
175
193
  referencing the same configs as above.
176
194
 
177
- ## Tools used and their future
178
-
179
- ### ESLint
180
-
181
- ESLint doesn't yet support ESM config files. We'll upgrade to the latest ESLint
182
- when it does. This should also help fix the issue with Yarn PnP (see below).
183
-
184
- ### Yarn
185
-
186
- **tl;dr; We'll move to Yarn PnP once ESLint has support for Flat Configs, and
187
- default `yarn run` doesn't add a ~1s delay overhead**
188
-
189
- #### PnP
190
-
191
-
192
- Aberlaas is using Yarn Berry (v2+) as its main package management tool.
193
-
194
- Yarn Berry comes with a Plug And Play (PnP) feature that replaces the usage of
195
- `node_modules` in favor of a `.pnp.cjs` file. Instead of having a very large
196
- `node_modules` folder, a unique copy of each dependency is stored in the user
197
- home folder and the `.pnp.cjs` file only keeps references to those folder. This
198
- makes installing dependencies faster as it needs way less I/O.
199
-
200
- By ditching the whole `node_modules` principle, it also removes concepts like
201
- hoisting of dependencies in a monorepo. This, unfortunately, breaks ESLint.
202
-
203
- ESLint expect all its plugins to be defined as `peerDependencies` at the root of
204
- a mono-repo, as it will always try to include them from there. It works more or
205
- less correctly at the best of times, and `aberlaas` already has some hacks
206
- (including `resolvePluginsRelativeTo`) to work around that.
207
-
208
- But with PnP, there is no way to make it work correctly, so I will need to wait
209
- for a better compatibility between ESLint and Yarn 2 before using it.
210
-
211
- Sources:
212
- - [#8](https://github.com/yarnpkg/berry/issues/8), the initial case study of Yarn + ESLint
213
- - [GitHub issue that explicitly explain the problem](https://github.com/yarnpkg/berry/discussions/3909)
214
- - [`eslint-patch`, an ESLint plugin that hacks around this issue](https://yarnpkg.com/package?name=@rushstack/eslint-patch)
215
- - [The `resolvePluginsRelativeTo` bandaid from ESLint](https://eslint.org/docs/latest/use/command-line-interface#--resolve-plugins-relative-to)
216
- - [A nice postmortem of moving to Yarn 2](https://www.dolthub.com/blog/2022-03-18-migrating-to-yarn-2/)
217
- - [The Flat Config feature in ESLint that should solve the problem](https://eslint.org/docs/latest/use/configure/configuration-files-new)
218
-
219
- #### Calling binaries from the host
220
-
221
- In yarn v1, if you install `aberlaas` in your project, all of `aberlaas`
222
- dependencies (including binaries) were hoisted to the root. This was a design
223
- flaw, as if several dependencies defined binaries by the same name, they would
224
- fight in a race condition to take the slot in `node_modules/.bin`.
225
-
226
- This has been fixed in Yarn Berry, but it also means it's no longer possible to
227
- call `yarn run eslint` from a repository that includes `aberlaas`, because
228
- `eslint` is not a direct dependency of the repo.
229
-
230
- It might be possible to define proxy binaries inside of `aberlaas`, but those
231
- will incur performance issues as they will need to spawn one more yarn context
232
- (see below).
233
-
234
- #### Calling binaries from aberlaas
235
-
236
- In Yarn V1, I was calling binaries that `aberlaas` depends on (`eslint`, `vitest`,
237
- etc) by calling `yarn run`. This was adding some overhead but was acceptable.
238
- Yarn Berry adds even more overhead and it is becoming noticeable.
239
-
240
- Now, my prefered way it to use the NodeJS API of the dependencies instead of
241
- their CLI, to limit the overhead. I managed to move most tools to this new
242
- approach, but sometimes I still need to use the CLI (`vitest` for example has
243
- awesome live watching and display reloading that I don't think I can easily
244
- replicate through code).
245
-
246
- I ran some performance tests to see what would be the fastest way to call
247
- `vitest` from `aberlaas`
248
-
249
- ```
250
- hyperfine \
251
- "zsh -i -c 'yarn bin vitest && /home/tim/local/www/projects/aberlaas/node_modules/vitest/vitest.mjs --version'" \
252
- "zsh -i -c 'yarn run vitest --version'" \
253
- "/home/tim/local/www/projects/aberlaas/node_modules/vitest/vitest.mjs --version" \
254
- "/home/tim/local/www/projects/aberlaas/node_modules/.bin/vitest --version"
255
- Benchmark 1: zsh -i -c 'yarn run vitest --version'
256
- Time (mean ± σ): 1.945 s ± 0.051 s [User: 1.986 s, System: 0.850 s]
257
- Range (min … max): 1.859 s … 2.018 s 10 runs
258
-
259
- Benchmark 2: zsh -i -c 'yarn bin vitest && /home/tim/local/www/projects/aberlaas/node_modules/vitest/vitest.mjs --version'
260
- Time (mean ± σ): 2.108 s ± 0.150 s [User: 2.108 s, System: 0.843 s]
261
- Range (min … max): 1.930 s … 2.289 s 10 runs
262
-
263
- Benchmark 3: /home/tim/local/www/projects/aberlaas/node_modules/vitest/vitest.m
264
- js --version
265
- Time (mean ± σ): 482.5 ms ± 40.9 ms [User: 448.4 ms, System: 327.2 ms]
266
- Range (min … max): 442.1 ms … 553.3 ms 10 runs
267
-
268
- Benchmark 4: /home/tim/local/www/projects/aberlaas/node_modules/.bin/vitest --version
269
- Time (mean ± σ): 491.9 ms ± 29.6 ms [User: 454.1 ms, System: 331.2 ms]
270
- Range (min … max): 453.8 ms … 535.4 ms 10 runs
271
- ```
272
-
273
- Finding the binary through `yarn bin` then calling it is the slowest, but `yarn
274
- run` isn't much faster. Directly calling the binary is the fastest, but it's
275
- path can't be easily guessed (apart from reading and parsing a `package.json`).
276
- But using the symlinks in `node_modules/.bin` is consistent, barely slower than
277
- calling the binary directly and much faster than using yarn.
278
-
279
- This is what I'll be using. Of course, this will break when I'll move to PnP as
280
- the `node_modules` folder won't be there, but hopefully Yarn will be faster by
281
- then and I can use `yarn run` reliably.
282
-
283
- #### Speed
284
-
285
- With Yarn 2+, calling `yarn run` seem to add ~1s of overhead each time. This is
286
- a known issue (due to the fact Yarn 2 needs to spawn yarn 1, node and a few
287
- other layers).
288
-
289
- 1s is not much in itself, but grows quickly when you have nested `yarn run
290
- aberlaas` calls that call `yarn run eslint`, and even more when you need to deal
291
- with monorepos and multiple packages that each have their own yarn scope.
292
-
293
- There are open issues on the topic, but nothing merged yet:
294
-
295
- - [#3732](https://github.com/yarnpkg/berry/issues/3732), where it is discussed to make yarn run aware that it's running yarn run
296
- and keep the same state without spawning new yarns
297
- - [#2575](https://github.com/yarnpkg/berry/issues/2575), which is the main issue about Yarn performance, with benchmarks against
298
- npm/npx/yarn v1.
299
-
300
195
  ## Where does the name Aberlaas come from?
301
196
 
302
197
  Aberlaas is the base camp from which all great expedition start in the _La Horde
@@ -310,4 +205,4 @@ For your convenience, `aberlass` and `aberlas` are added as aliases by default.
310
205
 
311
206
  ## Documentation
312
207
 
313
- The complete documentation can be found on https://projects.pixelastic.com/aberlaas/
208
+ The complete documentation can be found on https://projects.pixelastic.com/aberlaas/
@@ -0,0 +1,171 @@
1
+ import path from 'path';
2
+ import Gilmore from 'gilmore';
3
+ import { copy, error as firostError, isFile, move, read, write } from 'firost';
4
+ import { _ } from 'golgoth';
5
+ import helper from '../../helper.js';
6
+
7
+ /**
8
+ * This hold functions shared for both the monorepo and simple init scenarios
9
+ **/
10
+ export default {
11
+ /**
12
+ * Return name of the current project, as the name of the current directory
13
+ * @returns {string} Name of the project
14
+ **/
15
+ getProjectName() {
16
+ return path.basename(helper.hostRoot());
17
+ },
18
+
19
+ /**
20
+ * Return the name of the current author based on the GitHub project owner
21
+ * @returns {string} Name of the author, or __placeholder__ if undefined
22
+ **/
23
+ async getProjectAuthor() {
24
+ const repo = this.__getRepo();
25
+ return (await repo.githubRepoOwner()) || '__placeholder__';
26
+ },
27
+
28
+ /**
29
+ * Copy a config template to the host
30
+ * @param {string} source Path to source file, relative to aberlaas
31
+ * @param {string} destination Path to destination file, relative to the host
32
+ * @returns {boolean} False if can't copy file, true otherwise
33
+ **/
34
+ async copyToHost(source, destination) {
35
+ const absoluteSource = helper.aberlaasPath(source);
36
+ const absoluteDestination = helper.hostPath(destination);
37
+
38
+ // Source file does not exist
39
+ if (!(await isFile(absoluteSource))) {
40
+ throw firostError(
41
+ 'ERROR_INIT_COPY_FILE',
42
+ `Unable to locate ${absoluteSource} file`,
43
+ );
44
+ }
45
+ // Destination file already exist
46
+ if (await isFile(absoluteDestination)) {
47
+ // Do nothing if content is already the same
48
+ const sourceContent = await read(absoluteSource);
49
+ const destinationContent = await read(absoluteDestination);
50
+ if (sourceContent === destinationContent) {
51
+ return true;
52
+ }
53
+
54
+ // Otherwise create a backup
55
+ const backupDestination = `${absoluteDestination}.backup`;
56
+ await move(absoluteDestination, backupDestination);
57
+ }
58
+
59
+ await copy(absoluteSource, absoluteDestination);
60
+
61
+ return true;
62
+ },
63
+
64
+ /**
65
+ * Add MIT license file
66
+ * @param {string} hostFilepath Path to the LICENSE file, relative to the host
67
+ **/
68
+ async addLicenseFile(hostFilepath) {
69
+ // Start by adding a template
70
+ await this.copyToHost('templates/LICENSE', hostFilepath);
71
+
72
+ // Replace placeholder with real value
73
+ const licensePath = helper.hostPath(hostFilepath);
74
+ const author = await this.getProjectAuthor();
75
+ const templateContent = await read(licensePath);
76
+ const actualContent = _.replace(templateContent, '{author}', author);
77
+
78
+ // Write it again
79
+ await write(actualContent, licensePath);
80
+ },
81
+
82
+ /**
83
+ * Add default script files
84
+ **/
85
+ async addScripts() {
86
+ // Common
87
+ await this.copyToHost('templates/scripts/ci', 'scripts/ci');
88
+ await this.copyToHost('templates/scripts/compress', 'scripts/compress');
89
+ await this.copyToHost('templates/scripts/lint', 'scripts/lint');
90
+ await this.copyToHost('templates/scripts/lint-fix', 'scripts/lint-fix');
91
+
92
+ // Hooks
93
+ await this.copyToHost(
94
+ './templates/scripts/hooks/pre-commit',
95
+ './scripts/hooks/pre-commit',
96
+ );
97
+
98
+ // Lib
99
+ await this.copyToHost(
100
+ 'templates/scripts/lib/release',
101
+ 'scripts/lib/release',
102
+ );
103
+ await this.copyToHost('templates/scripts/lib/test', 'scripts/lib/test');
104
+ await this.copyToHost(
105
+ 'templates/scripts/lib/test-watch',
106
+ 'scripts/lib/test-watch',
107
+ );
108
+ },
109
+
110
+ /**
111
+ * Add config files to the host. Each config files reference the default
112
+ * aberlaas config for its tool. This pattern allow end-users to use aberlaas
113
+ * default rules and overwrite them as they see fit
114
+ **/
115
+ async addConfigFiles() {
116
+ // Git
117
+ await this.copyToHost('./templates/_gitignore', './.gitignore');
118
+ await this.copyToHost('./templates/_gitattributes', './.gitattributes');
119
+
120
+ // Yarn
121
+ await this.copyToHost('templates/_yarnrc.yml', '.yarnrc.yml');
122
+
123
+ // ESLint
124
+ await this.copyToHost('templates/_eslintrc.cjs', '.eslintrc.cjs');
125
+ await this.copyToHost('templates/_eslintignore.conf', '.eslintignore');
126
+
127
+ // Lint-staged
128
+ await this.copyToHost(
129
+ 'templates/lintstaged.config.js',
130
+ 'lintstaged.config.js',
131
+ );
132
+
133
+ // Vite
134
+ await this.copyToHost('templates/vite.config.js', 'vite.config.js');
135
+
136
+ // Prettier
137
+ await this.copyToHost('templates/prettier.config.js', 'prettier.config.js');
138
+
139
+ // Stylelint
140
+ await this.copyToHost(
141
+ 'templates/stylelint.config.js',
142
+ 'stylelint.config.js',
143
+ );
144
+
145
+ // Renovate
146
+ await this.copyToHost(
147
+ 'templates/_github/renovate.json',
148
+ '.github/renovate.json',
149
+ );
150
+
151
+ // CircleCI
152
+ await this.copyToHost(
153
+ 'templates/_circleci/config.yml',
154
+ '.circleci/config.yml',
155
+ );
156
+ },
157
+
158
+ /**
159
+ * Add default files required to have the minimum lib module
160
+ **/
161
+ async addLibFiles() {
162
+ await this.copyToHost('templates/lib/main.js', 'lib/main.js');
163
+ await this.copyToHost(
164
+ 'templates/lib/__tests__/main.js',
165
+ 'lib/__tests__/main.js',
166
+ );
167
+ },
168
+ __getRepo() {
169
+ return new Gilmore(helper.hostRoot());
170
+ },
171
+ };
@@ -1,21 +1,10 @@
1
- import { _ } from 'golgoth';
2
- import {
3
- consoleInfo,
4
- copy,
5
- firostError,
6
- isFile,
7
- move,
8
- read,
9
- readJson,
10
- run,
11
- spinner,
12
- write,
13
- writeJson,
14
- } from 'firost';
1
+ import { consoleInfo, run, spinner, write } from 'firost';
15
2
 
16
3
  import Gilmore from 'gilmore';
17
4
  import helper from '../../helper.js';
18
5
  import nodeConfig from '../../configs/node.cjs';
6
+ import initMonorepo from './monorepo.js';
7
+ import initModule from './module.js';
19
8
 
20
9
  export default {
21
10
  /**
@@ -33,399 +22,38 @@ export default {
33
22
  await write(nodeConfig.nodeVersion, nvmrcPath);
34
23
  },
35
24
  /**
36
- * Create the top-level monorepo root workspace
25
+ * Run yarn install to install all deps
37
26
  **/
38
- async createRootWorkspace() {
39
- const aberlaasData = await readJson(helper.aberlaasPath('./package.json'));
40
- const sharedProjectData = await this.getSharedProjectData();
41
-
42
- const packageContent = {
43
- // Visibility
44
- private: true,
45
- workspaces: ['docs', 'lib'],
46
-
47
- // Name and version
48
- name: `${sharedProjectData.name}-monorepo`,
49
- version: '0.0.1',
50
-
51
- // Metadata
52
- author: sharedProjectData.author,
53
- description: `${sharedProjectData.name} monorepo`,
54
- repository: sharedProjectData.repository,
55
- homepage: sharedProjectData.homepage,
56
-
57
- // Compatibility
58
- type: 'module',
59
- license: sharedProjectData.license,
60
- packageManager: `yarn@${nodeConfig.yarnVersion}`,
61
-
62
- // Exports
63
-
64
- // Dependencies
65
- dependencies: {},
66
- devDependencies: {
67
- aberlaas: aberlaasData.version,
68
- lerna: nodeConfig.lernaVersion,
69
- },
70
-
71
- // Scripts
72
- scripts: {
73
- // ==> Docs-specific
74
- build: './scripts/docs/build',
75
- 'build:prod': './scripts/docs/build-prod',
76
- cms: './scripts/docs/cms',
77
- serve: './scripts/docs/serve',
78
- // ==> Lib-specific
79
- release: './scripts/lib/release',
80
- test: './scripts/lib/test',
81
- 'test:watch': './scripts/lib/test-watch',
82
- // Common
83
- ci: './scripts/ci',
84
- compress: './scripts/compress',
85
- lint: './scripts/lint',
86
- 'lint:fix': './scripts/lint-fix',
87
-
88
- // Global (called as aliases from any workspace)
89
- // ==> Docs-specific
90
- 'g:build': './scripts/docs/build',
91
- 'g:build:prod': './scripts/docs/build-prod',
92
- 'g:cms': './scripts/docs/cms',
93
- 'g:serve': './scripts/docs/serve',
94
- // ==> Lib-specific
95
- 'g:release': './scripts/lib/release',
96
- 'g:test': './scripts/lib/test',
97
- 'g:test:watch': './scripts/lib/test-watch',
98
- // Common
99
- 'g:compress': './scripts/compress',
100
- 'g:lint': './scripts/lint',
101
- 'g:lint:fix': './scripts/lint-fix',
102
- },
103
- };
104
- await writeJson(packageContent, helper.hostPath('./package.json'), {
105
- sort: false,
106
- });
107
- },
108
- /**
109
- * Create the docs workspace
110
- **/
111
- async createDocsWorkspace() {
112
- const sharedProjectData = await this.getSharedProjectData();
113
-
114
- const packageContent = {
115
- // Visibility
116
- private: true,
117
-
118
- // Name & Version
119
- name: `${sharedProjectData.name}-docs`,
120
- version: '0.0.1',
121
-
122
- // Metadata
123
- author: sharedProjectData.author,
124
- description: `${sharedProjectData.name} docs`,
125
- repository: sharedProjectData.repository,
126
- homepage: sharedProjectData.homepage,
127
-
128
- // Compatibility
129
- license: sharedProjectData.license,
130
-
131
- // Exports
132
-
133
- // Dependencies
134
- dependencies: {
135
- norska: nodeConfig.norskaVersion,
136
- 'norska-theme-docs': nodeConfig.norskaThemeDocsVersion,
137
- },
138
- devDependencies: {},
139
-
140
- // Scripts
141
- scripts: sharedProjectData.scripts,
142
- };
143
- await writeJson(packageContent, helper.hostPath('./docs/package.json'), {
144
- sort: false,
145
- });
146
- },
147
- /**
148
- * Create the lib workspace
149
- **/
150
- async createLibWorkspace() {
151
- const sharedProjectData = await this.getSharedProjectData();
152
-
153
- const packageContent = {
154
- // Visibility
155
- private: false,
156
-
157
- // Name and version
158
- name: sharedProjectData.name,
159
- version: '0.0.1',
160
-
161
- // Metadata
162
- author: sharedProjectData.author,
163
- description: '',
164
- keywords: [],
165
- repository: sharedProjectData.repository,
166
- homepage: sharedProjectData.homepage,
167
-
168
- // Compatibility
169
- type: 'module',
170
- license: sharedProjectData.license,
171
- engines: sharedProjectData.engines,
172
-
173
- // Exports
174
- files: ['*.js'],
175
- exports: {
176
- '.': './main.js',
177
- },
178
- main: './main.js',
179
-
180
- // Dependencies
181
- dependencies: {},
182
- devDependencies: {},
183
-
184
- // Scripts
185
- scripts: sharedProjectData.scripts,
186
- };
187
- await writeJson(packageContent, helper.hostPath('./lib/package.json'), {
188
- sort: false,
189
- });
190
- },
191
- /**
192
- * Add config files to the host. Each config files reference the default
193
- * aberlaas config for its tool. This pattern allow end-users to use aberlaas
194
- * default rules and overwrite them as they see fit
195
- **/
196
- async addConfigFiles() {
197
- // Git
198
- await this.copyToHost('./templates/_gitignore', './.gitignore');
199
- await this.copyToHost('./templates/_gitattributes', './.gitattributes');
200
-
201
- // Yarn
202
- await this.copyToHost('templates/_yarnrc.yml', '.yarnrc.yml');
203
-
204
- // Lerna
205
- await this.copyToHost('templates/lerna.json', 'lerna.json');
206
-
207
- // ESLint
208
- await this.copyToHost('templates/_eslintrc.cjs', '.eslintrc.cjs');
209
- await this.copyToHost('templates/_eslintignore.conf', '.eslintignore');
210
-
211
- // Lint-staged
212
- await this.copyToHost(
213
- 'templates/lintstaged.config.js',
214
- 'lintstaged.config.js',
215
- );
216
-
217
- // Vite
218
- await this.copyToHost('templates/vite.config.js', 'vite.config.js');
219
-
220
- // Prettier
221
- await this.copyToHost('templates/prettier.config.js', 'prettier.config.js');
222
-
223
- // Stylelint
224
- await this.copyToHost(
225
- 'templates/stylelint.config.js',
226
- 'stylelint.config.js',
227
- );
228
-
229
- // Renovate
230
- await this.copyToHost(
231
- 'templates/_github/renovate.json',
232
- '.github/renovate.json',
233
- );
234
-
235
- // CircleCI
236
- await this.copyToHost(
237
- 'templates/_circleci/config.yml',
238
- '.circleci/config.yml',
239
- );
240
- },
241
- /**
242
- * Add default script files
243
- **/
244
- async addScripts() {
245
- // Docs
246
- await this.copyToHost('templates/scripts/docs/build', 'scripts/docs/build');
247
- await this.copyToHost(
248
- 'templates/scripts/docs/build-prod',
249
- 'scripts/docs/build-prod',
250
- );
251
- await this.copyToHost('templates/scripts/docs/cms', 'scripts/docs/cms');
252
- await this.copyToHost('templates/scripts/docs/serve', 'scripts/docs/serve');
253
-
254
- // Hooks
255
- await this.copyToHost(
256
- './templates/scripts/hooks/pre-commit',
257
- './scripts/hooks/pre-commit',
258
- );
259
-
260
- // Lib
261
- await this.copyToHost(
262
- 'templates/scripts/lib/release',
263
- 'scripts/lib/release',
264
- );
265
- await this.copyToHost('templates/scripts/lib/test', 'scripts/lib/test');
266
- await this.copyToHost(
267
- 'templates/scripts/lib/test-watch',
268
- 'scripts/lib/test-watch',
269
- );
270
-
271
- // Common
272
- await this.copyToHost('templates/scripts/ci', 'scripts/ci');
273
- await this.copyToHost('templates/scripts/compress', 'scripts/compress');
274
- await this.copyToHost('templates/scripts/lint', 'scripts/lint');
275
- await this.copyToHost('templates/scripts/lint-fix', 'scripts/lint-fix');
276
- },
277
- /**
278
- * Add MIT license files to the repository
279
- **/
280
- async addLicenseFiles() {
281
- // Add the LICENSE template to the root
282
- await this.copyToHost('templates/LICENSE', 'LICENSE');
283
-
284
- // Replace placeholder with real value
285
- const sharedProjectData = await this.getSharedProjectData();
286
- const licensePath = helper.hostPath('LICENSE');
287
- const templateContent = await read(licensePath);
288
- const actualContent = _.replace(
289
- templateContent,
290
- '{author}',
291
- sharedProjectData.author,
292
- );
293
-
294
- // Write the LICENSE to root and lib
295
- await write(actualContent, licensePath);
296
- await write(actualContent, helper.hostPath('lib/LICENSE'));
297
- },
298
- /**
299
- * Add default files required to have the minimum lib module
300
- **/
301
- async addLibFiles() {
302
- await this.copyToHost('templates/lib/main.js', 'lib/main.js');
303
- await this.copyToHost(
304
- 'templates/lib/__tests__/main.js',
305
- 'lib/__tests__/main.js',
306
- );
307
- },
308
- /**
309
- * Copy a config template to the host
310
- * @param {string} source Path to source file, relative to aberlaas
311
- * @param {string} destination Path to destination file, relative to the host
312
- * @returns {boolean} False if can't copy file, true otherwise
313
- **/
314
- async copyToHost(source, destination) {
315
- const absoluteSource = helper.aberlaasPath(source);
316
- const absoluteDestination = helper.hostPath(destination);
317
-
318
- // Source file does not exist
319
- if (!(await isFile(absoluteSource))) {
320
- throw firostError(
321
- 'ERROR_INIT_COPY_FILE',
322
- `Unable to locate ${absoluteSource} file`,
323
- );
324
- }
325
- // Destination file already exist
326
- if (await isFile(absoluteDestination)) {
327
- // Do nothing if content is already the same
328
- const sourceContent = await read(absoluteSource);
329
- const destinationContent = await read(absoluteDestination);
330
- if (sourceContent === destinationContent) {
331
- return true;
332
- }
333
-
334
- // Otherwise create a backup
335
- const backupDestination = `${absoluteDestination}.backup`;
336
- await move(absoluteDestination, backupDestination);
337
- }
338
-
339
- await copy(absoluteSource, absoluteDestination);
340
-
341
- return true;
342
- },
343
- /**
344
- * Return name of the current project based on the GitHub project name
345
- * @returns {string} Name of the project
346
- **/
347
- async getProjectName() {
348
- const repo = new Gilmore(helper.hostRoot());
349
- return await repo.githubRepoName();
350
- },
351
- /**
352
- * Return the name of the current author based on the GitHub project owner
353
- * @returns {string} Name of the author
354
- **/
355
- async getProjectAuthor() {
356
- const repo = new Gilmore(helper.hostRoot());
357
- return await repo.githubRepoOwner();
358
- },
359
- /**
360
- * Returns shared project data, like name, author, scripts, etc
361
- * @returns {object} Object of common keys
362
- **/
363
- async getSharedProjectData() {
364
- const name = await this.getProjectName();
365
- const author = await this.getProjectAuthor();
366
- const homepage = `https://projects.pixelastic.com/${name}`;
367
- const repository = `${author}/${name}`;
368
- const license = 'MIT';
369
- const engines = {
370
- node: `>=${nodeConfig.nodeVersion}`,
371
- };
372
- const scripts = {
373
- // Docs
374
- build: 'ABERLAAS_CWD=$INIT_CWD yarn g:build',
375
- 'build:prod': 'ABERLAAS_CWD=$INIT_CWD yarn g:build:prod',
376
- cms: 'ABERLAAS_CWD=$INIT_CWD yarn g:cms',
377
- serve: 'ABERLAAS_CWD=$INIT_CWD yarn g:serve',
378
-
379
- // Lib
380
- release: 'ABERLAAS_CWD=$INIT_CWD yarn g:release',
381
- test: 'ABERLAAS_CWD=$INIT_CWD yarn g:test',
382
- 'test:watch': 'ABERLAAS_CWD=$INIT_CWD yarn g:test:watch',
383
-
384
- // Common
385
- compress: 'ABERLAAS_CWD=$INIT_CWD yarn g:compress',
386
- lint: 'ABERLAAS_CWD=$INIT_CWD yarn g:lint',
387
- 'lint:fix': 'ABERLAAS_CWD=$INIT_CWD yarn g:lint:fix',
388
- };
389
- return {
390
- author,
391
- engines,
392
- homepage,
393
- license,
394
- name,
395
- repository,
396
- scripts,
397
- };
27
+ async yarnInstall() {
28
+ await run('yarn install');
398
29
  },
399
30
  /**
400
31
  * Copy all config files and configure the scripts
32
+ * @param {object} args Argument object, as passed by minimist
401
33
  **/
402
- async run() {
403
- const progress = spinner();
34
+ async run(args = {}) {
35
+ const isMonorepo = args.monorepo;
36
+
37
+ const progress = this.__spinner();
404
38
 
405
39
  progress.tick('Configuring Git & Node');
406
40
  await this.configureGit();
407
41
  await this.configureNode();
408
42
 
409
- progress.tick('Configuring workspaces');
410
- await this.createRootWorkspace();
411
- await this.createDocsWorkspace();
412
- await this.createLibWorkspace();
43
+ progress.tick('Adding default files ');
413
44
 
414
- progress.tick('Adding files');
415
- await this.addLicenseFiles();
416
- await this.addConfigFiles();
417
- await this.addScripts();
418
- await this.addLibFiles();
45
+ // Create a different scaffolding based on if creating a monorepo or not
46
+ isMonorepo ? await initMonorepo.run() : await initModule.run();
419
47
 
420
48
  progress.success('aberlaas project initialized');
421
49
 
422
50
  this.__consoleInfo('Synchronizing dependencies');
423
- await run('yarn install');
51
+ await this.yarnInstall();
424
52
 
425
53
  this.__consoleInfo(
426
54
  "Don't forget to run aberlaas setup after pushing your repository",
427
55
  );
428
56
  },
429
- __run: run,
430
57
  __consoleInfo: consoleInfo,
58
+ __spinner: spinner,
431
59
  };
@@ -0,0 +1,111 @@
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 package.json
10
+ **/
11
+ async createPackageJson() {
12
+ // Get language and dependency version
13
+ const { version: aberlaasVersion } = await readJson(
14
+ helper.aberlaasPath('./package.json'),
15
+ );
16
+ const { nodeVersion, yarnVersion } = nodeConfig;
17
+
18
+ const name = await this.__getProjectName();
19
+ const version = '0.0.1';
20
+
21
+ const author = await this.__getProjectAuthor();
22
+ const description = '';
23
+ const keywords = [];
24
+ const repository = `${author}/${name}`;
25
+ const homepage = `https://projects.pixelastic.com/${name}`;
26
+
27
+ const type = 'module';
28
+ const license = 'MIT';
29
+ const engines = {
30
+ node: `>=${nodeVersion}`,
31
+ };
32
+ const packageManager = `yarn@${yarnVersion}`;
33
+
34
+ const files = ['*.js'];
35
+ const exports = {
36
+ '.': './main.js',
37
+ };
38
+ const main = './main.js';
39
+
40
+ const dependencies = {};
41
+ const devDependencies = {
42
+ aberlaas: aberlaasVersion,
43
+ };
44
+
45
+ const scripts = {
46
+ // Docs
47
+ build: './scripts/docs/build',
48
+ 'build:prod': './scripts/docs/build-prod',
49
+ cms: './scripts/docs/cms',
50
+ serve: './scripts/docs/serve',
51
+ // Lib
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
+
62
+ const packageContent = {
63
+ // Name and version
64
+ name,
65
+ version,
66
+
67
+ // Metadata
68
+ author,
69
+ description,
70
+ keywords,
71
+ repository,
72
+ homepage,
73
+
74
+ // Compatibility
75
+ type,
76
+ license,
77
+ engines,
78
+ packageManager,
79
+
80
+ // Exports
81
+ files,
82
+ exports,
83
+ main,
84
+
85
+ // Dependencies
86
+ dependencies,
87
+ devDependencies,
88
+
89
+ // Scripts
90
+ scripts,
91
+ };
92
+
93
+ await writeJson(packageContent, helper.hostPath('./package.json'), {
94
+ sort: false,
95
+ });
96
+ },
97
+
98
+ /**
99
+ * Scaffold a repo for use in a simple module contexte
100
+ **/
101
+ async run() {
102
+ await this.createPackageJson();
103
+
104
+ await initHelper.addLicenseFile('LICENSE');
105
+ await initHelper.addConfigFiles();
106
+ await initHelper.addScripts();
107
+ await initHelper.addLibFiles();
108
+ },
109
+ __getProjectName: initHelper.getProjectName.bind(initHelper),
110
+ __getProjectAuthor: initHelper.getProjectAuthor.bind(initHelper),
111
+ };
@@ -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.8.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": "cf8d18533d7a85069d52bb3d2ba5fe1627bef71b"
81
82
  }