aberlaas 2.0.0 → 2.2.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.
Files changed (81) hide show
  1. package/README.md +126 -4
  2. package/bin/{aberlaas → aberlaas.js} +1 -1
  3. package/commands/ci/autoRelease.js +9 -8
  4. package/commands/ci/index.js +10 -10
  5. package/commands/compress/dummy.js +11 -0
  6. package/commands/compress/index.js +10 -19
  7. package/commands/compress/png.js +22 -13
  8. package/commands/{init.js → init/index.js} +51 -31
  9. package/commands/lint/circleci.js +10 -11
  10. package/commands/lint/css.js +33 -25
  11. package/commands/lint/helpers/prettier.js +57 -0
  12. package/commands/lint/index.js +18 -48
  13. package/commands/lint/js.js +40 -52
  14. package/commands/lint/json.js +14 -12
  15. package/commands/lint/yml.js +16 -13
  16. package/commands/{precommit.js → precommit/index.js} +7 -7
  17. package/commands/readme/index.js +16 -16
  18. package/commands/{release.js → release/index.js} +5 -6
  19. package/commands/setup/autoRelease/envVars.js +9 -8
  20. package/commands/setup/autoRelease/index.js +12 -11
  21. package/commands/setup/autoRelease/privateKey.js +6 -5
  22. package/commands/setup/autoRelease/publicKey.js +8 -7
  23. package/commands/setup/circleci.js +9 -8
  24. package/commands/setup/github.js +6 -5
  25. package/commands/setup/helpers/circleci.js +6 -5
  26. package/commands/setup/helpers/github.js +6 -5
  27. package/commands/setup/helpers/npm.js +1 -1
  28. package/commands/setup/helpers/ssh.js +11 -10
  29. package/commands/setup/index.js +6 -6
  30. package/commands/setup/renovate.js +7 -6
  31. package/commands/test/index.js +83 -0
  32. package/configs/{eslint.js → eslint.cjs} +77 -29
  33. package/configs/{lintstaged.js → lintstaged.cjs} +7 -1
  34. package/configs/node.cjs +5 -0
  35. package/configs/vite/test/setupFiles/captureOutput.js +4 -0
  36. package/configs/vite/test/setupFiles/dedent.js +4 -0
  37. package/configs/vite/test/setupFiles/fit-xit-fdescribe-xdescribe.js +13 -0
  38. package/configs/vite/test/setupFiles/jest-extended.js +10 -0
  39. package/configs/vite/test/setupFiles/testName.js +9 -0
  40. package/configs/vite.js +25 -0
  41. package/helper.js +49 -38
  42. package/main.js +28 -22
  43. package/package.json +30 -23
  44. package/scripts/postinstall +15 -0
  45. package/templates/_circleci/config.yml +1 -1
  46. package/templates/_eslintignore.conf +1 -1
  47. package/templates/_eslintrc.cjs +3 -0
  48. package/templates/_lintstagedrc.cjs +4 -0
  49. package/templates/_prettierrc.cjs +4 -0
  50. package/templates/_stylelintrc.cjs +4 -0
  51. package/templates/_yarnrc.yml +9 -0
  52. package/templates/lib/__tests__/main.js +2 -2
  53. package/templates/lib/main.js +1 -1
  54. package/templates/scripts/{husky-precommit → compress} +1 -1
  55. package/templates/scripts/hooks/pre-commit +11 -0
  56. package/templates/vite.config.js +4 -0
  57. package/commands/test.js +0 -92
  58. package/configs/husky.js +0 -5
  59. package/configs/jest/index.js +0 -49
  60. package/configs/jest/jest-extended.js +0 -3
  61. package/configs/jest/setupFileAfterEnv.js +0 -13
  62. package/configs/jest/sharedState.js +0 -14
  63. package/configs/jest/testEnvironment.js +0 -46
  64. package/configs/jest.js +0 -1
  65. package/configs/node.js +0 -3
  66. package/lib/configs/deprecated.js +0 -17
  67. package/lib/configs/eslint.js +0 -2
  68. package/lib/configs/husky.js +0 -2
  69. package/lib/configs/jest.js +0 -2
  70. package/lib/configs/lintstaged.js +0 -2
  71. package/lib/configs/prettier.js +0 -2
  72. package/lib/configs/stylelint.js +0 -2
  73. package/templates/_eslintrc.js +0 -3
  74. package/templates/_huskyrc.js +0 -4
  75. package/templates/_lintstagedrc.js +0 -4
  76. package/templates/_prettierrc.js +0 -4
  77. package/templates/_stylelintrc.js +0 -4
  78. package/templates/babel.config.js +0 -3
  79. package/templates/jest.config.js +0 -4
  80. /package/configs/{prettier.js → prettier.cjs} +0 -0
  81. /package/configs/{stylelint.js → stylelint.cjs} +0 -0
package/README.md CHANGED
@@ -51,7 +51,6 @@ The following table lists all the scripts added:
51
51
 
52
52
  | Script | Description |
53
53
  | -------------------------- | --------------------------------------------------------- |
54
- | `yarn run husky:precommit` | Run before any commit (through Husky) |
55
54
  | `yarn run test` | Run tests using Jest |
56
55
  | `yarn run test:watch` | Run tests using Jest in watch mode |
57
56
  | `yarn run ci` | Run testing and linting in CI |
@@ -111,7 +110,7 @@ describe('moduleName', () => {
111
110
 
112
111
  ## Precommit hooks
113
112
 
114
- `aberlaas` uses `husky` and `lint-staged` to make sure all committed code
113
+ `aberlaas` uses `lint-staged` to make sure all committed code
115
114
  follows your coding standard.
116
115
 
117
116
  All `css`, `js`, `json` and `yml` files will be checked for parsing errors
@@ -189,10 +188,133 @@ exported by the package and thus can be `require`d in userland.
189
188
  extends the configuration exported in the previous files. Copying files to
190
189
  userland allows user to change the files if they want to change the behavior.
191
190
 
192
- `.eslintrc.js`, `.stylelintrc.js`, `jest.config.js` and `.huskyrc.js` are local
191
+ `.eslintrc.js`, `.stylelintrc.js` and `jest.config.js` are local
193
192
  configuration files for `aberlaas` itself. They eat their own dog food by
194
193
  referencing the same configs as above.
195
194
 
195
+ ## Tools used and their future
196
+
197
+ ### ESLint
198
+
199
+ ESLint doesn't yet support ESM config files. We'll upgrade to the latest ESLint
200
+ when it does. This should also help fix the issue with Yarn PnP (see below).
201
+
202
+ ### Yarn
203
+
204
+ **tl;dr; We'll move to Yarn PnP once ESLint has support for Flat Configs, and
205
+ default `yarn run` doesn't add a ~1s delay overhead**
206
+
207
+ #### PnP
208
+
209
+
210
+ Aberlaas is using Yarn Berry (v2+) as its main package management tool.
211
+
212
+ Yarn Berry comes with a Plug And Play (PnP) feature that replaces the usage of
213
+ `node_modules` in favor of a `.pnp.cjs` file. Instead of having a very large
214
+ `node_modules` folder, a unique copy of each dependency is stored in the user
215
+ home folder and the `.pnp.cjs` file only keeps references to those folder. This
216
+ makes installing dependencies faster as it needs way less I/O.
217
+
218
+ By ditching the whole `node_modules` principle, it also removes concepts like
219
+ hoisting of dependencies in a monorepo. This, unfortunately, breaks ESLint.
220
+
221
+ ESLint expect all its plugins to be defined as `peerDependencies` at the root of
222
+ a mono-repo, as it will always try to include them from there. It works more or
223
+ less correctly at the best of times, and `aberlaas` already has some hacks
224
+ (including `resolvePluginsRelativeTo`) to work around that.
225
+
226
+ But with PnP, there is no way to make it work correctly, so I will need to wait
227
+ for a better compatibility between ESLint and Yarn 2 before using it.
228
+
229
+ Sources:
230
+ - [#8](https://github.com/yarnpkg/berry/issues/8), the initial case study of Yarn + ESLint
231
+ - [GitHub issue that explicitly explain the problem](https://github.com/yarnpkg/berry/discussions/3909)
232
+ - [`eslint-patch`, an ESLint plugin that hacks around this issue](https://yarnpkg.com/package?name=@rushstack/eslint-patch)
233
+ - [The `resolvePluginsRelativeTo` bandaid from ESLint](https://eslint.org/docs/latest/use/command-line-interface#--resolve-plugins-relative-to)
234
+ - [A nice postmortem of moving to Yarn 2](https://www.dolthub.com/blog/2022-03-18-migrating-to-yarn-2/)
235
+ - [The Flat Config feature in ESLint that should solve the problem](https://eslint.org/docs/latest/use/configure/configuration-files-new)
236
+
237
+ #### Calling binaries from the host
238
+
239
+ In yarn v1, if you install `aberlaas` in your project, all of `aberlaas`
240
+ dependencies (including binaries) were hoisted to the root. This was a design
241
+ flaw, as if several dependencies defined binaries by the same name, they would
242
+ fight in a race condition to take the slot in `node_modules/.bin`.
243
+
244
+ This has been fixed in Yarn Berry, but it also means it's no longer possible to
245
+ call `yarn run eslint` from a repository that includes `aberlaas`, because
246
+ `eslint` is not a direct dependency of the repo.
247
+
248
+ It might be possible to define proxy binaries inside of `aberlaas`, but those
249
+ will incur performance issues as they will need to spawn one more yarn context
250
+ (see below).
251
+
252
+ #### Calling binaries from aberlaas
253
+
254
+ In Yarn V1, I was calling binaries that `aberlaas` depends on (`eslint`, `vitest`,
255
+ etc) by calling `yarn run`. This was adding some overhead but was acceptable.
256
+ Yarn Berry adds even more overhead and it is becoming noticeable.
257
+
258
+ Now, my prefered way it to use the NodeJS API of the dependencies instead of
259
+ their CLI, to limit the overhead. I managed to move most tools to this new
260
+ approach, but sometimes I still need to use the CLI (`vitest` for example has
261
+ awesome live watching and display reloading that I don't think I can easily
262
+ replicate through code).
263
+
264
+ I ran some performance tests to see what would be the fastest way to call
265
+ `vitest` from `aberlaas`
266
+
267
+ ```
268
+ hyperfine \
269
+ "zsh -i -c 'yarn bin vitest && /home/tim/local/www/projects/aberlaas/node_modules/vitest/vitest.mjs --version'" \
270
+ "zsh -i -c 'yarn run vitest --version'" \
271
+ "/home/tim/local/www/projects/aberlaas/node_modules/vitest/vitest.mjs --version" \
272
+ "/home/tim/local/www/projects/aberlaas/node_modules/.bin/vitest --version"
273
+ Benchmark 1: zsh -i -c 'yarn run vitest --version'
274
+ Time (mean ± σ): 1.945 s ± 0.051 s [User: 1.986 s, System: 0.850 s]
275
+ Range (min … max): 1.859 s … 2.018 s 10 runs
276
+
277
+ Benchmark 2: zsh -i -c 'yarn bin vitest && /home/tim/local/www/projects/aberlaas/node_modules/vitest/vitest.mjs --version'
278
+ Time (mean ± σ): 2.108 s ± 0.150 s [User: 2.108 s, System: 0.843 s]
279
+ Range (min … max): 1.930 s … 2.289 s 10 runs
280
+
281
+ Benchmark 3: /home/tim/local/www/projects/aberlaas/node_modules/vitest/vitest.m
282
+ js --version
283
+ Time (mean ± σ): 482.5 ms ± 40.9 ms [User: 448.4 ms, System: 327.2 ms]
284
+ Range (min … max): 442.1 ms … 553.3 ms 10 runs
285
+
286
+ Benchmark 4: /home/tim/local/www/projects/aberlaas/node_modules/.bin/vitest --version
287
+ Time (mean ± σ): 491.9 ms ± 29.6 ms [User: 454.1 ms, System: 331.2 ms]
288
+ Range (min … max): 453.8 ms … 535.4 ms 10 runs
289
+ ```
290
+
291
+ Finding the binary through `yarn bin` then calling it is the slowest, but `yarn
292
+ run` isn't much faster. Directly calling the binary is the fastest, but it's
293
+ path can't be easily guessed (apart from reading and parsing a `package.json`).
294
+ But using the symlinks in `node_modules/.bin` is consistent, barely slower than
295
+ calling the binary directly and much faster than using yarn.
296
+
297
+ This is what I'll be using. Of course, this will break when I'll move to PnP as
298
+ the `node_modules` folder won't be there, but hopefully Yarn will be faster by
299
+ then and I can use `yarn run` reliably.
300
+
301
+ #### Speed
302
+
303
+ With Yarn 2+, calling `yarn run` seem to add ~1s of overhead each time. This is
304
+ a known issue (due to the fact Yarn 2 needs to spawn yarn 1, node and a few
305
+ other layers).
306
+
307
+ 1s is not much in itself, but grows quickly when you have nested `yarn run
308
+ aberlaas` calls that call `yarn run eslint`, and even more when you need to deal
309
+ with monorepos and multiple packages that each have their own yarn scope.
310
+
311
+ There are open issues on the topic, but nothing merged yet:
312
+
313
+ - [#3732](https://github.com/yarnpkg/berry/issues/3732), where it is discussed to make yarn run aware that it's running yarn run
314
+ and keep the same state without spawning new yarns
315
+ - [#2575](https://github.com/yarnpkg/berry/issues/2575), which is the main issue about Yarn performance, with benchmarks against
316
+ npm/npx/yarn v1.
317
+
196
318
  ## Where does the name Aberlaas come from?
197
319
 
198
320
  Aberlaas is the base camp from which all great expedition start in the _La Horde
@@ -206,4 +328,4 @@ For your convenience, `aberlass` and `aberlas` are added as aliases by default.
206
328
 
207
329
  ## Documentation
208
330
 
209
- The complete documentation can be found on https://projects.pixelastic.com/aberlaas/
331
+ The complete documentation can be found on https://projects.pixelastic.com/aberlaas/
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const aberlaas = require('../main.js');
2
+ import aberlaas from '../main.js';
3
3
  (async () => {
4
4
  await aberlaas.run(process.argv.slice(2));
5
5
  })();
@@ -1,11 +1,12 @@
1
- const release = require('../release.js');
2
- const consoleInfo = require('firost/consoleInfo');
3
- const _ = require('golgoth/lodash');
4
- const run = require('firost/run');
5
- const write = require('firost/write');
6
- const exists = require('firost/exists');
7
- const helper = require('../../helper.js');
8
- module.exports = {
1
+ import release from '../release/index.js';
2
+ import consoleInfo from 'firost/consoleInfo.js';
3
+ import _ from 'golgoth/lodash.js';
4
+ import run from 'firost/run.js';
5
+ import write from 'firost/write.js';
6
+ import exists from 'firost/exists.js';
7
+ import helper from '../../helper.js';
8
+
9
+ export default {
9
10
  /**
10
11
  * Run a git command in the repo
11
12
  *
@@ -1,13 +1,13 @@
1
- const helper = require('../../helper.js');
2
- const ciInfo = require('ci-info');
3
- const _ = require('golgoth/lodash');
4
- const pMap = require('golgoth/pMap');
5
- const readJson = require('firost/readJson');
6
- const run = require('firost/run');
7
- const consoleInfo = require('firost/consoleInfo');
8
- const autoRelease = require('./autoRelease.js');
1
+ import helper from '../../helper.js';
2
+ import ciInfo from 'ci-info';
3
+ import _ from 'golgoth/lodash.js';
4
+ import pMap from 'golgoth/pMap.js';
5
+ import readJson from 'firost/readJson.js';
6
+ import run from 'firost/run.js';
7
+ import consoleInfo from 'firost/consoleInfo.js';
8
+ import autoRelease from './autoRelease.js';
9
9
 
10
- module.exports = {
10
+ export default {
11
11
  /**
12
12
  * Return the value of an environment variable
13
13
  * @param {string} key Name of the variable
@@ -112,7 +112,7 @@ module.exports = {
112
112
 
113
113
  await helper.yarnRun(command);
114
114
  },
115
- { concurrency: 1 }
115
+ { concurrency: 1 },
116
116
  );
117
117
 
118
118
  // Attempt to release the package if --auto-release is set
@@ -0,0 +1,11 @@
1
+ /**
2
+ * This is a temporary, dummy file to be able to test the top-level
3
+ * compress.run() function. I assume I'll add more compression types in addition
4
+ * to png, so this dummy compress is just to test that all compress are
5
+ * correctly called, but it doesn't do anything
6
+ **/
7
+ export default {
8
+ async run() {
9
+ return true;
10
+ },
11
+ };
@@ -1,12 +1,14 @@
1
- const _ = require('golgoth/lodash');
2
- const pMap = require('golgoth/pMap');
3
- const consoleError = require('firost/consoleError');
4
- const firostError = require('firost/error');
5
- const helper = require('../../helper.js');
1
+ import _ from 'golgoth/lodash.js';
2
+ import pMap from 'golgoth/pMap.js';
3
+ import consoleError from 'firost/consoleError.js';
4
+ import firostError from 'firost/error.js';
5
+ import compressPng from './png.js';
6
+ import compressDummy from './dummy.js';
6
7
 
7
- module.exports = {
8
+ export default {
8
9
  types: {
9
- png: './png.js',
10
+ png: compressPng,
11
+ dummy: compressDummy,
10
12
  },
11
13
  /**
12
14
  * Wrapper to compress all supported formats
@@ -22,7 +24,7 @@ module.exports = {
22
24
  await pMap(typesToCompress, async (type) => {
23
25
  try {
24
26
  const userPatterns = _.get(cliArgs, '_');
25
- const compresser = require(this.types[type]);
27
+ const compresser = this.types[type];
26
28
 
27
29
  await compresser.run(userPatterns);
28
30
  } catch (error) {
@@ -37,16 +39,5 @@ module.exports = {
37
39
 
38
40
  return true;
39
41
  },
40
- /**
41
- * Find all relevant files of the specified extension in the host
42
- * Note: Should be used by child classes
43
- * @param {Array} safeListExtension List of allowed extensions to keep
44
- * @param {Array} userPatterns Patterns to narrow the search down
45
- * @returns {Array} Array of files
46
- **/
47
- async getInputFiles(safeListExtension, userPatterns = []) {
48
- const inputPatterns = _.isEmpty(userPatterns) ? '.' : userPatterns;
49
- return await helper.findHostFiles(inputPatterns, safeListExtension);
50
- },
51
42
  __consoleError: consoleError,
52
43
  };
@@ -1,24 +1,29 @@
1
- const lint = require('./index.js');
2
- const run = require('firost/run');
3
- const which = require('firost/which');
4
- const firostError = require('firost/error');
1
+ import helper from '../../helper.js';
2
+ import _ from 'golgoth/lodash.js';
3
+ import run from 'firost/run.js';
4
+ import which from 'firost/which.js';
5
+ import firostError from 'firost/error.js';
5
6
 
6
- module.exports = {
7
+ export default {
7
8
  /**
8
9
  * Find the png files to compress
9
10
  * @param {Array} userPatterns Patterns to narrow the search down
10
11
  * @returns {Array} Array of files
11
12
  **/
12
13
  async getInputFiles(userPatterns) {
13
- return await lint.getInputFiles(['.png'], userPatterns);
14
+ const filePatterns = _.isEmpty(userPatterns)
15
+ ? ['./**/*.png']
16
+ : userPatterns;
17
+ return await helper.findHostFiles(filePatterns, ['.png']);
14
18
  },
19
+
15
20
  /**
16
- * Check if the binary is available in the $PATH
17
- * @returns {boolean} True if available, false otherwise
21
+
22
+ * Returns path to the binary to execute
23
+ * @returns {string|boolean} Path to the binary, or false if not found
18
24
  **/
19
- async hasBin() {
20
- const binary = await which('pngmin');
21
- return !!binary;
25
+ async getBinaryPath() {
26
+ return await this.__which('pngmin');
22
27
  },
23
28
  /**
24
29
  * Compress files
@@ -27,16 +32,20 @@ module.exports = {
27
32
  **/
28
33
  async run(userPatterns) {
29
34
  // Stop early if no bin
30
- if (!(await this.hasBin())) {
35
+ const binaryPath = await this.getBinaryPath();
36
+ if (!binaryPath) {
31
37
  return true;
32
38
  }
33
39
 
34
40
  try {
35
41
  const files = await this.getInputFiles(userPatterns);
36
- const command = `pngmin ${files.join(' ')}`;
42
+ const command = `${binaryPath} ${files.join(' ')}`;
37
43
  await run(command, { stdout: false });
38
44
  } catch (error) {
39
45
  throw firostError('PngCompressError', error.message);
40
46
  }
47
+
48
+ return true;
41
49
  },
50
+ __which: which,
42
51
  };
@@ -1,19 +1,21 @@
1
- const _ = require('golgoth/lodash');
2
- const pMapSeries = require('golgoth/pMapSeries');
3
- const isFile = require('firost/isFile');
4
- const copy = require('firost/copy');
5
- const readJson = require('firost/readJson');
6
- const writeJson = require('firost/writeJson');
7
- const exists = require('firost/exists');
8
- const read = require('firost/read');
9
- const write = require('firost/write');
10
- const run = require('firost/run');
11
- const spinner = require('firost/spinner');
12
- const helper = require('../helper');
13
- const path = require('path');
14
- const nodeConfig = require('../configs/node');
15
- const consoleInfo = require('firost/consoleInfo');
16
- module.exports = {
1
+ import _ from 'golgoth/lodash.js';
2
+ import pMapSeries from 'golgoth/pMapSeries.js';
3
+ import isFile from 'firost/isFile.js';
4
+ import copy from 'firost/copy.js';
5
+ import readJson from 'firost/readJson.js';
6
+ import writeJson from 'firost/writeJson.js';
7
+ import exists from 'firost/exists.js';
8
+ import read from 'firost/read.js';
9
+ import write from 'firost/write.js';
10
+ import run from 'firost/run.js';
11
+ import spinner from 'firost/spinner.js';
12
+ import helper from '../../helper.js';
13
+ import path from 'path';
14
+ import nodeConfig from '../../configs/node.cjs';
15
+ import consoleInfo from 'firost/consoleInfo.js';
16
+ import Gilmore from 'gilmore';
17
+
18
+ export default {
17
19
  /**
18
20
  * Copy a config template to the host
19
21
  * @param {string} source Path to source file, relative to aberlaas
@@ -43,35 +45,35 @@ module.exports = {
43
45
  * default rules and overwrite them as they see fit
44
46
  **/
45
47
  async addConfigFiles() {
48
+ // Yarn
49
+ await this.copyToHost('templates/_yarnrc.yml', '.yarnrc.yml');
50
+
46
51
  // ESLint
47
- await this.copyToHost('templates/_eslintrc.js', '.eslintrc.js');
52
+ await this.copyToHost('templates/_eslintrc.cjs', '.eslintrc.cjs');
48
53
  await this.copyToHost('templates/_eslintignore.conf', '.eslintignore');
49
54
 
50
- // Husky
51
- await this.copyToHost('templates/_huskyrc.js', '.huskyrc.js');
52
-
53
55
  // Lint-staged
54
- await this.copyToHost('templates/_lintstagedrc.js', '.lintstagedrc.js');
56
+ await this.copyToHost('templates/_lintstagedrc.cjs', '.lintstagedrc.cjs');
55
57
 
56
- // Jest
57
- await this.copyToHost('templates/jest.config.js', 'jest.config.js');
58
+ // Vite
59
+ await this.copyToHost('templates/vite.config.js', 'vite.config.js');
58
60
 
59
61
  // Prettier
60
- await this.copyToHost('templates/_prettierrc.js', '.prettierrc.js');
62
+ await this.copyToHost('templates/_prettierrc.cjs', '.prettierrc.cjs');
61
63
 
62
64
  // Stylelint
63
- await this.copyToHost('templates/_stylelintrc.js', '.stylelintrc.js');
65
+ await this.copyToHost('templates/_stylelintrc.cjs', '.stylelintrc.cjs');
64
66
 
65
67
  // Renovate
66
68
  await this.copyToHost(
67
69
  'templates/_github/renovate.json',
68
- '.github/renovate.json'
70
+ '.github/renovate.json',
69
71
  );
70
72
 
71
73
  // CircleCI
72
74
  await this.copyToHost(
73
75
  'templates/_circleci/config.yml',
74
- '.circleci/config.yml'
76
+ '.circleci/config.yml',
75
77
  );
76
78
  },
77
79
  /**
@@ -95,7 +97,7 @@ module.exports = {
95
97
  const newPackage = _.set(
96
98
  _.clone(currentPackage),
97
99
  `scripts.${scriptName}`,
98
- `./${scriptPath}`
100
+ `./${scriptPath}`,
99
101
  );
100
102
  await writeJson(newPackage, packagePath);
101
103
  return true;
@@ -107,9 +109,9 @@ module.exports = {
107
109
  async addScripts() {
108
110
  const defaultScripts = [
109
111
  { key: 'ci', value: 'scripts/ci' },
112
+ { key: 'compress', value: 'scripts/compress' },
110
113
  { key: 'lint', value: 'scripts/lint' },
111
114
  { key: 'lint:fix', value: 'scripts/lint-fix' },
112
- { key: 'husky:precommit', value: 'scripts/husky-precommit' },
113
115
  { key: 'release', value: 'scripts/release' },
114
116
  { key: 'test', value: 'scripts/test' },
115
117
  { key: 'test:watch', value: 'scripts/test-watch' },
@@ -122,6 +124,7 @@ module.exports = {
122
124
  /**
123
125
  * Update package.json with .main and .files keys to use files in ./lib
124
126
  * directory by default
127
+ * TODO: Update this to use exports instead of main
125
128
  **/
126
129
  async setDefaultReleaseFiles() {
127
130
  const packagePath = helper.hostPath('package.json');
@@ -135,7 +138,7 @@ module.exports = {
135
138
  await this.copyToHost('templates/lib/main.js', 'lib/main.js');
136
139
  await this.copyToHost(
137
140
  'templates/lib/__tests__/main.js',
138
- 'lib/__tests__/main.js'
141
+ 'lib/__tests__/main.js',
139
142
  );
140
143
  }
141
144
 
@@ -251,6 +254,20 @@ module.exports = {
251
254
  // Download latest yarn version
252
255
  await this.__run('yarn set version', { stdout: false });
253
256
  },
257
+ /**
258
+ * Configure git hooks to use scripts/hooks instead of .git/hooks
259
+ **/
260
+ async configureGitHooks() {
261
+ // Copy the scripts into ./scripts/hooks
262
+ await this.copyToHost(
263
+ './templates/scripts/hooks/pre-commit',
264
+ './scripts/hooks/pre-commit',
265
+ );
266
+
267
+ // Configure git to use this directory for hooks
268
+ const repo = new Gilmore(helper.hostRoot());
269
+ await repo.setConfig('core.hooksPath', 'scripts/hooks');
270
+ },
254
271
  /**
255
272
  * Copy all config files and configure the scripts
256
273
  **/
@@ -267,6 +284,9 @@ module.exports = {
267
284
  progress.tick('Adding yarn scripts');
268
285
  await this.addScripts();
269
286
 
287
+ progress.tick('Configuring git hooks');
288
+ await this.configureGitHooks();
289
+
270
290
  progress.tick('Updating LICENSE');
271
291
  await this.addLicenseFile();
272
292
  await this.addLicenseField();
@@ -283,7 +303,7 @@ module.exports = {
283
303
  progress.success('aberlaas project initialized');
284
304
 
285
305
  this.__consoleInfo(
286
- "Don't forget to run aberlaas setup after pushing your repository"
306
+ "Don't forget to run aberlaas setup after pushing your repository",
287
307
  );
288
308
  },
289
309
  __run: run,
@@ -1,20 +1,19 @@
1
- const helper = require('../../helper.js');
2
- const lint = require('./index.js');
3
- const lintYml = require('./yml.js');
4
- const ciInfo = require('ci-info');
5
- const exists = require('firost/exists');
6
- const run = require('firost/run');
7
- const which = require('firost/which');
8
- const firostError = require('firost/error');
1
+ import helper from '../../helper.js';
2
+ import lintYml from './yml.js';
3
+ import ciInfo from 'ci-info';
4
+ import exists from 'firost/exists.js';
5
+ import run from 'firost/run.js';
6
+ import which from 'firost/which.js';
7
+ import firostError from 'firost/error.js';
9
8
 
10
- module.exports = {
9
+ export default {
11
10
  configPath: '.circleci/config.yml',
12
11
  /**
13
- * Find the CircleCI config file
12
+ * Find all relevant files
14
13
  * @returns {Array} Array of files
15
14
  **/
16
15
  async getInputFiles() {
17
- return await lint.getInputFiles(['.yml'], [this.configPath]);
16
+ return await helper.findHostFiles([this.configPath]);
18
17
  },
19
18
  /**
20
19
  * Check if the code is currently running on CircleCI
@@ -1,46 +1,55 @@
1
- const helper = require('../../helper.js');
2
- const lint = require('./index.js');
3
- const _ = require('golgoth/lodash');
4
- const firostError = require('firost/error');
5
- const run = require('firost/run');
6
- module.exports = {
1
+ import helper from '../../helper.js';
2
+ import { fix as prettierFix } from './helpers/prettier.js';
3
+ import stylelint from 'stylelint';
4
+ import _ from 'golgoth/lodash.js';
5
+ import firostError from 'firost/error.js';
6
+
7
+ export default {
7
8
  /**
8
9
  * Find all relevant files
9
10
  * @param {Array} userPatterns Patterns to narrow the search down
10
11
  * @returns {Array} Array of files
11
12
  **/
12
13
  async getInputFiles(userPatterns) {
13
- return await lint.getInputFiles(['.css'], userPatterns);
14
+ const filePatterns = _.isEmpty(userPatterns)
15
+ ? ['./**/*.css']
16
+ : userPatterns;
17
+ return await helper.findHostFiles(filePatterns, ['.css']);
14
18
  },
15
19
  /**
16
20
  * Lint all files and display results.
17
21
  * @param {Array} userPatterns Patterns to narrow the search down
18
22
  * @param {string} userConfigFile Custom config file to use
23
+ * @param {object} userOptions Options to pass to ESLint, including fix
19
24
  * @returns {boolean} True on success
20
25
  **/
21
- async run(userPatterns, userConfigFile) {
26
+ async run(userPatterns, userConfigFile, userOptions = {}) {
27
+ // Options
28
+ const options = { fix: false, ...userOptions };
29
+
30
+ // Files
22
31
  const files = await this.getInputFiles(userPatterns);
23
32
  if (_.isEmpty(files)) {
24
33
  return true;
25
34
  }
26
35
 
36
+ // Config
27
37
  const configFile = await helper.configFile(
28
38
  userConfigFile,
29
- '.stylelintrc.js',
30
- 'configs/stylelint.js'
39
+ '.stylelintrc.cjs',
40
+ 'configs/stylelint.cjs',
31
41
  );
32
- const binary = await helper.which('stylelint');
33
- const options = [...files, '--color', '--config', configFile];
34
- try {
35
- await run(`${binary} ${options.join(' ')}`, { stdout: false });
36
- } catch (error) {
37
- // If it fails because no files passed actually exists, it's not really
38
- // a failure
39
- const errorMessage = error.stdout;
40
- if (_.startsWith(errorMessage, 'Error: No files matching the pattern')) {
41
- return true;
42
- }
43
- throw firostError('ERROR_CSS_LINT', error.stdout);
42
+ const config = await helper.import(configFile);
43
+
44
+ const result = await stylelint.lint({
45
+ config,
46
+ files,
47
+ formatter: 'string',
48
+ ...options,
49
+ });
50
+
51
+ if (result.errored) {
52
+ throw firostError('ERROR_CSS_LINT', result.output);
44
53
  }
45
54
  return true;
46
55
  },
@@ -56,10 +65,9 @@ module.exports = {
56
65
  return true;
57
66
  }
58
67
  // Try to pretiffy as much as we can
59
- await lint.fixWithPrettier(files);
68
+ await prettierFix(files);
60
69
  // Still run a lint on it so it can fail if not everything is fixed
61
- await this.run(userPatterns, userConfigFile);
70
+ await this.run(userPatterns, userConfigFile, { fix: true });
62
71
  return true;
63
72
  },
64
- __run: run,
65
73
  };