aberlaas 2.9.0 → 2.11.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/bin/aberlaas.js +1 -1
- package/configs/eslint.js +3 -0
- package/configs/lintstaged.js +2 -24
- package/configs/prettier.js +3 -4
- package/configs/stylelint.js +3 -41
- package/configs/vite.js +2 -41
- package/{main.js → lib/main.js} +26 -30
- package/package.json +37 -45
- package/commands/ci/index.js +0 -47
- package/commands/compress/dummy.js +0 -11
- package/commands/compress/index.js +0 -41
- package/commands/compress/png.js +0 -49
- package/commands/init/helper.js +0 -192
- package/commands/init/index.js +0 -59
- package/commands/init/module.js +0 -111
- package/commands/init/monorepo.js +0 -261
- package/commands/lint/circleci.js +0 -81
- package/commands/lint/css.js +0 -73
- package/commands/lint/helpers/prettier.js +0 -54
- package/commands/lint/index.js +0 -50
- package/commands/lint/js.js +0 -73
- package/commands/lint/json.js +0 -60
- package/commands/lint/yml.js +0 -62
- package/commands/precommit/index.js +0 -33
- package/commands/readme/index.js +0 -181
- package/commands/setup/circleci.js +0 -60
- package/commands/setup/github.js +0 -42
- package/commands/setup/helpers/circleci.js +0 -43
- package/commands/setup/helpers/github.js +0 -72
- package/commands/setup/helpers/npm.js +0 -16
- package/commands/setup/helpers/ssh.js +0 -77
- package/commands/setup/index.js +0 -52
- package/commands/setup/renovate.js +0 -54
- package/commands/test/index.js +0 -124
- package/configs/eslint.cjs +0 -154
- package/configs/node.cjs +0 -9
- package/configs/vite/test/setupFiles/captureOutput.js +0 -4
- package/configs/vite/test/setupFiles/dedent.js +0 -4
- package/configs/vite/test/setupFiles/fit-xit-fdescribe-xdescribe.js +0 -13
- package/configs/vite/test/setupFiles/jest-extended.js +0 -10
- package/configs/vite/test/setupFiles/testName.js +0 -9
- package/helper.js +0 -115
- package/templates/LICENSE +0 -9
- package/templates/_circleci/config.yml +0 -42
- package/templates/_eslintignore.conf +0 -12
- package/templates/_eslintrc.cjs +0 -3
- package/templates/_gitattributes +0 -4
- package/templates/_github/README.template.md +0 -7
- package/templates/_github/renovate.json +0 -3
- package/templates/_gitignore +0 -29
- package/templates/_yarnrc.yml +0 -15
- package/templates/lerna.json +0 -6
- package/templates/lib/__tests__/main.js +0 -13
- package/templates/lib/main.js +0 -5
- package/templates/lintstaged.config.js +0 -5
- package/templates/prettier.config.js +0 -5
- package/templates/scripts/ci +0 -6
- package/templates/scripts/compress +0 -4
- package/templates/scripts/docs/build +0 -4
- package/templates/scripts/docs/build-prod +0 -4
- package/templates/scripts/docs/cms +0 -4
- package/templates/scripts/docs/serve +0 -4
- package/templates/scripts/hooks/pre-commit +0 -11
- package/templates/scripts/lib/release +0 -5
- package/templates/scripts/lib/test +0 -5
- package/templates/scripts/lib/test-watch +0 -5
- package/templates/scripts/lint +0 -4
- package/templates/scripts/lint-fix +0 -4
- package/templates/stylelint.config.js +0 -5
- package/templates/vite.config.js +0 -5
package/commands/lint/css.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import stylelint from 'stylelint';
|
|
2
|
-
import { _ } from 'golgoth';
|
|
3
|
-
import { firostError, firostImport } from 'firost';
|
|
4
|
-
import helper from '../../helper.js';
|
|
5
|
-
import { fix as prettierFix } from './helpers/prettier.js';
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
/**
|
|
9
|
-
* Find all relevant files
|
|
10
|
-
* @param {Array} userPatterns Patterns to narrow the search down
|
|
11
|
-
* @returns {Array} Array of files
|
|
12
|
-
**/
|
|
13
|
-
async getInputFiles(userPatterns) {
|
|
14
|
-
const filePatterns = _.isEmpty(userPatterns)
|
|
15
|
-
? ['./**/*.css']
|
|
16
|
-
: userPatterns;
|
|
17
|
-
return await helper.findHostFiles(filePatterns, ['.css']);
|
|
18
|
-
},
|
|
19
|
-
/**
|
|
20
|
-
* Lint all files and display results.
|
|
21
|
-
* @param {Array} userPatterns Patterns to narrow the search down
|
|
22
|
-
* @param {string} userConfigFile Custom config file to use
|
|
23
|
-
* @param {object} userOptions Options to pass to ESLint, including fix
|
|
24
|
-
* @returns {boolean} True on success
|
|
25
|
-
**/
|
|
26
|
-
async run(userPatterns, userConfigFile, userOptions = {}) {
|
|
27
|
-
// Options
|
|
28
|
-
const options = { fix: false, ...userOptions };
|
|
29
|
-
|
|
30
|
-
// Files
|
|
31
|
-
const files = await this.getInputFiles(userPatterns);
|
|
32
|
-
if (_.isEmpty(files)) {
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Config
|
|
37
|
-
const configFile = await helper.configFile(
|
|
38
|
-
userConfigFile,
|
|
39
|
-
'stylelint.config.js',
|
|
40
|
-
'configs/stylelint.js',
|
|
41
|
-
);
|
|
42
|
-
const config = await firostImport(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);
|
|
53
|
-
}
|
|
54
|
-
return true;
|
|
55
|
-
},
|
|
56
|
-
/**
|
|
57
|
-
* Autofix files in place
|
|
58
|
-
* @param {Array} userPatterns Patterns to narrow the search down
|
|
59
|
-
* @param {string} userConfigFile Custom config file to use
|
|
60
|
-
* @returns {boolean} True on success
|
|
61
|
-
**/
|
|
62
|
-
async fix(userPatterns, userConfigFile) {
|
|
63
|
-
const files = await this.getInputFiles(userPatterns);
|
|
64
|
-
if (_.isEmpty(files)) {
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
// Try to pretiffy as much as we can
|
|
68
|
-
await prettierFix(files);
|
|
69
|
-
// Still run a lint on it so it can fail if not everything is fixed
|
|
70
|
-
await this.run(userPatterns, userConfigFile, { fix: true });
|
|
71
|
-
return true;
|
|
72
|
-
},
|
|
73
|
-
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import * as prettier from 'prettier';
|
|
2
|
-
import { firostError, read, write } from 'firost';
|
|
3
|
-
import { _, pMap } from 'golgoth';
|
|
4
|
-
import helper from '../../../helper.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Fix all files using prettier
|
|
8
|
-
* @param {Array} inputFiles Files to auto-fix
|
|
9
|
-
**/
|
|
10
|
-
export async function fix(inputFiles) {
|
|
11
|
-
// Config file
|
|
12
|
-
const configFile = await helper.configFile(
|
|
13
|
-
null,
|
|
14
|
-
'prettier.config.js',
|
|
15
|
-
'configs/prettier.js',
|
|
16
|
-
);
|
|
17
|
-
const config = await prettier.resolveConfig(configFile);
|
|
18
|
-
|
|
19
|
-
const errors = [];
|
|
20
|
-
|
|
21
|
-
// Read all files, run them through the formatter and save them back to disk
|
|
22
|
-
// If any emits error, store the errors and display them all in one output
|
|
23
|
-
await pMap(
|
|
24
|
-
inputFiles,
|
|
25
|
-
async (filepath) => {
|
|
26
|
-
try {
|
|
27
|
-
const content = await read(filepath);
|
|
28
|
-
const options = { ...config, filepath };
|
|
29
|
-
const result = await prettier.format(content, options);
|
|
30
|
-
await write(result, filepath);
|
|
31
|
-
} catch (error) {
|
|
32
|
-
const message = error.toString();
|
|
33
|
-
errors.push({ filepath, message });
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
{ concurrency: 10 },
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
if (!_.isEmpty(errors)) {
|
|
40
|
-
let formattedErrors = '';
|
|
41
|
-
_.each(errors, (error) => {
|
|
42
|
-
formattedErrors = `${formattedErrors}${error.filepath}\n\n${error.message}\n\n`;
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
throw firostError(
|
|
46
|
-
'LINT_ERROR_FIX_PRETTIER',
|
|
47
|
-
`Some files could not be automatically fixed:\n\n${formattedErrors}`,
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export default {
|
|
53
|
-
fix,
|
|
54
|
-
};
|
package/commands/lint/index.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { _, pMap } from 'golgoth';
|
|
2
|
-
import { consoleError, firostError } from 'firost';
|
|
3
|
-
import linterCircleCI from './circleci.js';
|
|
4
|
-
import linterCss from './css.js';
|
|
5
|
-
import linterJson from './json.js';
|
|
6
|
-
import linterJs from './js.js';
|
|
7
|
-
import linterYml from './yml.js';
|
|
8
|
-
|
|
9
|
-
export default {
|
|
10
|
-
linters: {
|
|
11
|
-
circleci: linterCircleCI,
|
|
12
|
-
css: linterCss,
|
|
13
|
-
json: linterJson,
|
|
14
|
-
js: linterJs,
|
|
15
|
-
yml: linterYml,
|
|
16
|
-
},
|
|
17
|
-
/**
|
|
18
|
-
* Wrapper to lint all supported formats
|
|
19
|
-
* @param {object} cliArgs CLI Argument object, as created by minimist
|
|
20
|
-
* @returns {boolean} True on success
|
|
21
|
-
**/
|
|
22
|
-
async run(cliArgs = {}) {
|
|
23
|
-
const allTypesKeys = _.keys(this.linters);
|
|
24
|
-
const userTypes = _.intersection(_.keys(cliArgs), allTypesKeys);
|
|
25
|
-
const typesToLint = _.isEmpty(userTypes) ? allTypesKeys : userTypes;
|
|
26
|
-
|
|
27
|
-
let hasErrors = false;
|
|
28
|
-
await pMap(typesToLint, async (type) => {
|
|
29
|
-
const methodName = cliArgs.fix ? 'fix' : 'run';
|
|
30
|
-
try {
|
|
31
|
-
const linter = this.linters[type];
|
|
32
|
-
|
|
33
|
-
const configFile = _.get(cliArgs, `config.${type}`);
|
|
34
|
-
const userPatterns = _.get(cliArgs, '_');
|
|
35
|
-
|
|
36
|
-
await linter[methodName](userPatterns, configFile);
|
|
37
|
-
} catch (error) {
|
|
38
|
-
this.__consoleError(error.message);
|
|
39
|
-
hasErrors = true;
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
if (hasErrors) {
|
|
44
|
-
throw firostError('ERROR_LINT', 'Error while linting files');
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return true;
|
|
48
|
-
},
|
|
49
|
-
__consoleError: consoleError,
|
|
50
|
-
};
|
package/commands/lint/js.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { _ } from 'golgoth';
|
|
2
|
-
import { firostError } from 'firost';
|
|
3
|
-
import { ESLint } from 'eslint';
|
|
4
|
-
import helper from '../../helper.js';
|
|
5
|
-
|
|
6
|
-
export default {
|
|
7
|
-
/**
|
|
8
|
-
* Find all relevant files
|
|
9
|
-
* @param {Array} userPatterns Patterns to narrow the search down
|
|
10
|
-
* @returns {Array} Array of files
|
|
11
|
-
**/
|
|
12
|
-
async getInputFiles(userPatterns) {
|
|
13
|
-
const filePatterns = _.isEmpty(userPatterns) ? ['./**/*.js'] : userPatterns;
|
|
14
|
-
return await helper.findHostFiles(filePatterns, ['.js']);
|
|
15
|
-
},
|
|
16
|
-
/**
|
|
17
|
-
* Lint all files and display results.
|
|
18
|
-
* @param {Array} userPatterns Patterns to narrow the search down
|
|
19
|
-
* @param {string} userConfigFile Custom config file to use
|
|
20
|
-
* @param {object} userOptions Options to pass to ESLint, including fix
|
|
21
|
-
* @returns {boolean} True on success
|
|
22
|
-
**/
|
|
23
|
-
async run(userPatterns, userConfigFile, userOptions = {}) {
|
|
24
|
-
// Options
|
|
25
|
-
const options = { fix: false, ...userOptions };
|
|
26
|
-
|
|
27
|
-
// Files to lint
|
|
28
|
-
const files = await this.getInputFiles(userPatterns);
|
|
29
|
-
if (_.isEmpty(files)) {
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Config file
|
|
34
|
-
const configFile = await helper.configFile(
|
|
35
|
-
userConfigFile,
|
|
36
|
-
'.eslintrc.cjs',
|
|
37
|
-
'configs/eslint.cjs',
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
// Run the actual lint
|
|
41
|
-
const eslint = new ESLint({
|
|
42
|
-
overrideConfigFile: configFile,
|
|
43
|
-
resolvePluginsRelativeTo: helper.aberlaasRoot(),
|
|
44
|
-
...options,
|
|
45
|
-
});
|
|
46
|
-
const results = await eslint.lintFiles(files);
|
|
47
|
-
|
|
48
|
-
// Fix
|
|
49
|
-
if (options.fix) {
|
|
50
|
-
await ESLint.outputFixes(results);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// All good, we can stop
|
|
54
|
-
const errorCount = _.chain(results).map('errorCount').sum().value();
|
|
55
|
-
if (errorCount == 0) {
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Format errors
|
|
60
|
-
const formatter = await eslint.loadFormatter('stylish');
|
|
61
|
-
const errorText = formatter.format(results);
|
|
62
|
-
throw firostError('JavaScriptLintError', errorText);
|
|
63
|
-
},
|
|
64
|
-
/**
|
|
65
|
-
* Autofix files in place
|
|
66
|
-
* @param {Array} userPatterns Patterns to narrow the search down
|
|
67
|
-
* @param {string} userConfigFile Custom config file to use
|
|
68
|
-
* @returns {boolean} True on success
|
|
69
|
-
**/
|
|
70
|
-
async fix(userPatterns, userConfigFile) {
|
|
71
|
-
return await this.run(userPatterns, userConfigFile, { fix: true });
|
|
72
|
-
},
|
|
73
|
-
};
|
package/commands/lint/json.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import { _, pMap } from 'golgoth';
|
|
3
|
-
import { firostError, read } from 'firost';
|
|
4
|
-
import helper from '../../helper.js';
|
|
5
|
-
import { fix as prettierFix } from './helpers/prettier.js';
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
/**
|
|
9
|
-
* Find all relevant files
|
|
10
|
-
* @param {Array} userPatterns Patterns to narrow the search down
|
|
11
|
-
* @returns {Array} Array of files
|
|
12
|
-
**/
|
|
13
|
-
async getInputFiles(userPatterns) {
|
|
14
|
-
const filePatterns = _.isEmpty(userPatterns)
|
|
15
|
-
? ['./**/*.json']
|
|
16
|
-
: userPatterns;
|
|
17
|
-
return await helper.findHostFiles(filePatterns, ['.json']);
|
|
18
|
-
},
|
|
19
|
-
/**
|
|
20
|
-
* Lint all files and display results.
|
|
21
|
-
* @param {Array} userPatterns Patterns to narrow the search down
|
|
22
|
-
* @returns {boolean} True on success
|
|
23
|
-
**/
|
|
24
|
-
async run(userPatterns) {
|
|
25
|
-
const files = await this.getInputFiles(userPatterns);
|
|
26
|
-
if (_.isEmpty(files)) {
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
let hasErrors = false;
|
|
31
|
-
const errorMessages = [];
|
|
32
|
-
await pMap(files, async (filepath) => {
|
|
33
|
-
try {
|
|
34
|
-
JSON.parse(await read(filepath));
|
|
35
|
-
} catch (error) {
|
|
36
|
-
hasErrors = true;
|
|
37
|
-
const relativePath = path.relative(helper.hostRoot(), filepath);
|
|
38
|
-
errorMessages.push(`Invalid JSON: ${relativePath}`);
|
|
39
|
-
errorMessages.push(error.message);
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
if (hasErrors) {
|
|
44
|
-
throw firostError('JsonLintError', errorMessages.join('\n'));
|
|
45
|
-
}
|
|
46
|
-
return true;
|
|
47
|
-
},
|
|
48
|
-
/**
|
|
49
|
-
* Autofix files in place
|
|
50
|
-
* @param {Array} userPatterns Patterns to narrow the search down
|
|
51
|
-
* @returns {boolean} True on success
|
|
52
|
-
**/
|
|
53
|
-
async fix(userPatterns) {
|
|
54
|
-
const files = await this.getInputFiles(userPatterns);
|
|
55
|
-
if (_.isEmpty(files)) {
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
await prettierFix(files);
|
|
59
|
-
},
|
|
60
|
-
};
|
package/commands/lint/yml.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import { firostError, read } from 'firost';
|
|
3
|
-
import { _, pMap } from 'golgoth';
|
|
4
|
-
import yamlLint from 'yaml-lint';
|
|
5
|
-
import helper from '../../helper.js';
|
|
6
|
-
import { fix as prettierFix } from './helpers/prettier.js';
|
|
7
|
-
|
|
8
|
-
export default {
|
|
9
|
-
/**
|
|
10
|
-
* Find all relevant files
|
|
11
|
-
* @param {Array} userPatterns Patterns to narrow the search down
|
|
12
|
-
* @returns {Array} Array of files
|
|
13
|
-
**/
|
|
14
|
-
async getInputFiles(userPatterns) {
|
|
15
|
-
const filePatterns = _.isEmpty(userPatterns)
|
|
16
|
-
? ['./**/*.yml', './**/*.yaml']
|
|
17
|
-
: userPatterns;
|
|
18
|
-
return await helper.findHostFiles(filePatterns, ['.yml', '.yaml']);
|
|
19
|
-
},
|
|
20
|
-
/**
|
|
21
|
-
* Lint all files and display results.
|
|
22
|
-
* @param {Array} userPatterns Patterns to narrow the search down
|
|
23
|
-
* @returns {boolean} True on success
|
|
24
|
-
**/
|
|
25
|
-
async run(userPatterns) {
|
|
26
|
-
const files = await this.getInputFiles(userPatterns);
|
|
27
|
-
if (_.isEmpty(files)) {
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
let hasErrors = false;
|
|
32
|
-
const errorMessages = [];
|
|
33
|
-
await pMap(files, async (filepath) => {
|
|
34
|
-
const input = await read(filepath);
|
|
35
|
-
try {
|
|
36
|
-
await yamlLint.lint(input);
|
|
37
|
-
} catch (error) {
|
|
38
|
-
hasErrors = true;
|
|
39
|
-
const relativePath = path.relative(helper.hostRoot(), filepath);
|
|
40
|
-
errorMessages.push(`Invalid YAML: ${relativePath}`);
|
|
41
|
-
errorMessages.push(error.message);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
if (hasErrors) {
|
|
46
|
-
throw firostError('YamlLintError', errorMessages.join('\n'));
|
|
47
|
-
}
|
|
48
|
-
return true;
|
|
49
|
-
},
|
|
50
|
-
/**
|
|
51
|
-
* Autofix files in place
|
|
52
|
-
* @param {Array} userPatterns Patterns to narrow the search down
|
|
53
|
-
* @returns {boolean} True on success
|
|
54
|
-
**/
|
|
55
|
-
async fix(userPatterns) {
|
|
56
|
-
const files = await this.getInputFiles(userPatterns);
|
|
57
|
-
if (_.isEmpty(files)) {
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
await prettierFix(files);
|
|
61
|
-
},
|
|
62
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import lintStaged from 'lint-staged';
|
|
2
|
-
import { firostError, firostImport } from 'firost';
|
|
3
|
-
import helper from '../../helper.js';
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
async run(cliArgs) {
|
|
7
|
-
// Config
|
|
8
|
-
const configPath = await helper.configFile(
|
|
9
|
-
cliArgs.config,
|
|
10
|
-
'lintstaged.config.js',
|
|
11
|
-
'configs/lintstaged.js',
|
|
12
|
-
);
|
|
13
|
-
const config = await firostImport(configPath);
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
const result = await lintStaged({
|
|
17
|
-
config,
|
|
18
|
-
// Allow use extended shell syntax in config, like pipes, redirects or
|
|
19
|
-
// env variables
|
|
20
|
-
shell: true,
|
|
21
|
-
});
|
|
22
|
-
// Linting failed
|
|
23
|
-
if (!result) {
|
|
24
|
-
throw firostError(
|
|
25
|
-
'ERROR_PRECOMMIT_LINT_FAILED',
|
|
26
|
-
'Precommit linting failed',
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
} catch (error) {
|
|
30
|
-
throw firostError('ERROR_PRECOMMIT', 'Precommit failed');
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
};
|
package/commands/readme/index.js
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import { _, dedent, pMap } from 'golgoth';
|
|
3
|
-
import { exists, glob, read, readJson, write } from 'firost';
|
|
4
|
-
import frontMatter from 'front-matter';
|
|
5
|
-
import helper from '../../helper.js';
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
/**
|
|
9
|
-
* Update the main README.md based on the template and the documentation
|
|
10
|
-
* @param {object} cliArgs CLI Argument object, as created by minimist
|
|
11
|
-
* @param {string} cliArgs.template Path to the template (default to
|
|
12
|
-
* .github/README.template.md
|
|
13
|
-
* @param {string} cliArgs.docs Path to the documentation folder
|
|
14
|
-
* @param {string} cliArgs.lib Path to the library folder
|
|
15
|
-
* @param {string} cliArgs.output List of files to output. Default to
|
|
16
|
-
* README at the root, and next to package.json
|
|
17
|
-
**/
|
|
18
|
-
async run(cliArgs) {
|
|
19
|
-
const template = await this.getTemplate(cliArgs);
|
|
20
|
-
|
|
21
|
-
const packageData = await this.getPackageData(cliArgs);
|
|
22
|
-
const docsData = await this.getDocsData(cliArgs);
|
|
23
|
-
const data = { package: packageData, ...docsData };
|
|
24
|
-
|
|
25
|
-
const output = await this.getReadmes(cliArgs);
|
|
26
|
-
|
|
27
|
-
const content = await this.convert(template, data);
|
|
28
|
-
// console.info({ template, data, docsData });
|
|
29
|
-
|
|
30
|
-
await pMap(output, async (filepath) => {
|
|
31
|
-
await write(content, filepath);
|
|
32
|
-
});
|
|
33
|
-
},
|
|
34
|
-
/**
|
|
35
|
-
* Returns the content of the template
|
|
36
|
-
* @param {object} cliArgs CLI Argument object, as created by minimist
|
|
37
|
-
* @param {string} cliArgs.template Path to the template
|
|
38
|
-
* Will default to .github/README.template.md in the host, or fallback to
|
|
39
|
-
* a default value in aberllas
|
|
40
|
-
* @returns {string} Template content
|
|
41
|
-
**/
|
|
42
|
-
async getTemplate(cliArgs = {}) {
|
|
43
|
-
if (cliArgs.template) {
|
|
44
|
-
const customTemplate = helper.hostPath(cliArgs.template);
|
|
45
|
-
if (await exists(customTemplate)) {
|
|
46
|
-
return await read(customTemplate);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const hostDefaultTemplate = helper.hostPath('.github/README.template.md');
|
|
51
|
-
if (await exists(hostDefaultTemplate)) {
|
|
52
|
-
return await read(hostDefaultTemplate);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const aberlaasDefaultTemplate = helper.aberlaasPath(
|
|
56
|
-
'templates/_github/README.template.md',
|
|
57
|
-
);
|
|
58
|
-
return await read(aberlaasDefaultTemplate);
|
|
59
|
-
},
|
|
60
|
-
/**
|
|
61
|
-
* Returns the content of the library package.json
|
|
62
|
-
* @param {object} cliArgs CLI Argument object, as created by minimist
|
|
63
|
-
* Will default search in cliArgs.lib, ./lib, or the root
|
|
64
|
-
* @returns {object} package.json content
|
|
65
|
-
**/
|
|
66
|
-
async getPackageData(cliArgs = {}) {
|
|
67
|
-
const packagePath = await this.getPackagePath(cliArgs);
|
|
68
|
-
return await readJson(packagePath);
|
|
69
|
-
},
|
|
70
|
-
/**
|
|
71
|
-
* Returns the path to the package.json
|
|
72
|
-
* @param {object} cliArgs CLI Argument object, as created by minimist
|
|
73
|
-
* Will default search in cliArgs.lib, ./lib, or the root
|
|
74
|
-
* @returns {object} package.json content
|
|
75
|
-
**/
|
|
76
|
-
async getPackagePath(cliArgs = {}) {
|
|
77
|
-
const libFolder = helper.hostPath(cliArgs.lib || './lib');
|
|
78
|
-
let packagePath = path.resolve(libFolder, 'package.json');
|
|
79
|
-
|
|
80
|
-
if (await exists(packagePath)) {
|
|
81
|
-
return packagePath;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return helper.hostPath('package.json');
|
|
85
|
-
},
|
|
86
|
-
/**
|
|
87
|
-
* Returns all documentation as an object
|
|
88
|
-
* @param {object} cliArgs CLI Argument object, as created by minimist
|
|
89
|
-
* @param {string} cliArgs.docs Path to the documentation directory
|
|
90
|
-
* Will default to ./docs/src
|
|
91
|
-
* @returns {object} Documentation content
|
|
92
|
-
**/
|
|
93
|
-
async getDocsData(cliArgs = {}) {
|
|
94
|
-
const docsPath = helper.hostPath(cliArgs.docs || './docs/src');
|
|
95
|
-
const mdFiles = await glob(`${docsPath}/**/*.md`);
|
|
96
|
-
const docsData = {};
|
|
97
|
-
await pMap(mdFiles, async (filepath) => {
|
|
98
|
-
// Convert filepath to a (nested) dot key
|
|
99
|
-
const key = _.chain(path.relative(docsPath, filepath))
|
|
100
|
-
.replace(/\.md$/, '')
|
|
101
|
-
.replace(/\//g, '.')
|
|
102
|
-
.value();
|
|
103
|
-
|
|
104
|
-
// Grab the content, excluding front-matter
|
|
105
|
-
const rawContent = await read(filepath);
|
|
106
|
-
const { body } = frontMatter(rawContent);
|
|
107
|
-
_.set(docsData, key, body);
|
|
108
|
-
});
|
|
109
|
-
return docsData;
|
|
110
|
-
},
|
|
111
|
-
/**
|
|
112
|
-
* Returns path to all README.md to write
|
|
113
|
-
* @param {object} cliArgs CLI Argument object, as created by minimist
|
|
114
|
-
* @param {string} cliArgs.output Comma-separated list of output path
|
|
115
|
-
* Will default to a README.md at the git root, and one in the module code
|
|
116
|
-
* (./lib by default)
|
|
117
|
-
* @returns {Array} List of paths to write the READMEs
|
|
118
|
-
**/
|
|
119
|
-
async getReadmes(cliArgs = {}) {
|
|
120
|
-
// Custom --output passed as a comma-separated list
|
|
121
|
-
if (cliArgs.output) {
|
|
122
|
-
return _.chain(cliArgs.output)
|
|
123
|
-
.split(',')
|
|
124
|
-
.map((filepath) => {
|
|
125
|
-
return helper.hostPath(filepath);
|
|
126
|
-
})
|
|
127
|
-
.sort()
|
|
128
|
-
.value();
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// README.md at the git root for GitHub
|
|
132
|
-
const hostReadmePath = helper.hostPath('README.md');
|
|
133
|
-
|
|
134
|
-
// README.md in the module folder for npm/yarn
|
|
135
|
-
const packagePath = await this.getPackagePath(cliArgs);
|
|
136
|
-
const moduleReadmePath = path.resolve(
|
|
137
|
-
path.dirname(packagePath),
|
|
138
|
-
'README.md',
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
const readmes = _.uniq([hostReadmePath, moduleReadmePath]);
|
|
142
|
-
return readmes;
|
|
143
|
-
},
|
|
144
|
-
/**
|
|
145
|
-
* Convert a source string by replace {key} with the matching keys of data
|
|
146
|
-
* @param {string} source The source string
|
|
147
|
-
* @param {object} data The data object to use to compile
|
|
148
|
-
* @returns {string} The converted string
|
|
149
|
-
**/
|
|
150
|
-
convert(source, data) {
|
|
151
|
-
const regexp = /{(?<key>.*?)}/gm;
|
|
152
|
-
const matches = Array.from(source.matchAll(regexp));
|
|
153
|
-
|
|
154
|
-
let convertedSource = dedent`
|
|
155
|
-
<!--
|
|
156
|
-
This page was automatically generated by aberlaas readme.
|
|
157
|
-
DO NOT EDIT IT MANUALLY.
|
|
158
|
-
-->
|
|
159
|
-
|
|
160
|
-
${source}`;
|
|
161
|
-
|
|
162
|
-
_.each(matches, (match) => {
|
|
163
|
-
const key = match.groups.key;
|
|
164
|
-
convertedSource = convertedSource.replace(
|
|
165
|
-
`{${key}}`,
|
|
166
|
-
_.get(data, key, ''),
|
|
167
|
-
);
|
|
168
|
-
});
|
|
169
|
-
return convertedSource;
|
|
170
|
-
},
|
|
171
|
-
/**
|
|
172
|
-
* Read a file from disk, removing its front-matter if it has one
|
|
173
|
-
* @param {string} filepath Path to the file
|
|
174
|
-
* @returns {string} File content, stripped of front-matter
|
|
175
|
-
**/
|
|
176
|
-
async read(filepath) {
|
|
177
|
-
const source = await this.__read(filepath);
|
|
178
|
-
const { body } = frontMatter(source);
|
|
179
|
-
return body;
|
|
180
|
-
},
|
|
181
|
-
};
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { _ } from 'golgoth';
|
|
2
|
-
import { consoleError, consoleInfo, consoleSuccess } from 'firost';
|
|
3
|
-
import circleCiHelper from './helpers/circleci.js';
|
|
4
|
-
import githubHelper from './helpers/github.js';
|
|
5
|
-
|
|
6
|
-
export default {
|
|
7
|
-
/**
|
|
8
|
-
* Attempt to automatically follow the repo in CircleCI if possible, otherwise
|
|
9
|
-
* display the link to follow it manually
|
|
10
|
-
* @returns {boolean} True if enabled, false otherwise
|
|
11
|
-
**/
|
|
12
|
-
async enable() {
|
|
13
|
-
const { username, repo } = await githubHelper.repoData();
|
|
14
|
-
const projectUrl = `https://app.circleci.com/pipelines/github/${username}/${repo}`;
|
|
15
|
-
const followUrl = `https://app.circleci.com/projects/project-setup/github/${username}/${repo}`;
|
|
16
|
-
|
|
17
|
-
// Fail early if no token available
|
|
18
|
-
if (!circleCiHelper.hasToken()) {
|
|
19
|
-
this.__consoleError(
|
|
20
|
-
`[circleci]: No CIRCLECI_TOKEN found, please visit ${followUrl} to enable manually.`,
|
|
21
|
-
);
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Do nothing if already enabled
|
|
26
|
-
if (await this.isEnabled()) {
|
|
27
|
-
this.__consoleInfo(`CircleCI already enabled: ${projectUrl}`);
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Follow the repo
|
|
32
|
-
await this.followRepo();
|
|
33
|
-
this.__consoleSuccess(`CircleCI enabled: ${projectUrl}`);
|
|
34
|
-
return true;
|
|
35
|
-
},
|
|
36
|
-
/**
|
|
37
|
-
* Check if CircleCI is already enabled for this project
|
|
38
|
-
* @returns {boolean} True if already enabled, false otherwise
|
|
39
|
-
**/
|
|
40
|
-
async isEnabled() {
|
|
41
|
-
// There is no endpoint to check if a project is followed or not, so we get
|
|
42
|
-
// the list of all followed projects and check if the current one is in it
|
|
43
|
-
const allProjects = await circleCiHelper.api('projects');
|
|
44
|
-
const { username, repo } = await githubHelper.repoData();
|
|
45
|
-
const thisProject = _.find(allProjects, { username, reponame: repo });
|
|
46
|
-
return !!thisProject;
|
|
47
|
-
},
|
|
48
|
-
/**
|
|
49
|
-
* Automatically follow the repo on CircleCI.
|
|
50
|
-
**/
|
|
51
|
-
async followRepo() {
|
|
52
|
-
const { username, repo } = await githubHelper.repoData();
|
|
53
|
-
await circleCiHelper.api(`project/github/${username}/${repo}/follow`, {
|
|
54
|
-
method: 'post',
|
|
55
|
-
});
|
|
56
|
-
},
|
|
57
|
-
__consoleInfo: consoleInfo,
|
|
58
|
-
__consoleSuccess: consoleSuccess,
|
|
59
|
-
__consoleError: consoleError,
|
|
60
|
-
};
|
package/commands/setup/github.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { consoleError, consoleSuccess } from 'firost';
|
|
2
|
-
import githubHelper from './helpers/github.js';
|
|
3
|
-
|
|
4
|
-
export default {
|
|
5
|
-
/**
|
|
6
|
-
* Configure the GitHub repo with default settings:
|
|
7
|
-
* - Do not enable merge commits on PR
|
|
8
|
-
* - Automatically delete branches after PR merge
|
|
9
|
-
* @returns {boolean} True if enabled, false otherwise
|
|
10
|
-
**/
|
|
11
|
-
async enable() {
|
|
12
|
-
const { username, repo } = await githubHelper.repoData();
|
|
13
|
-
const repoUrl = `https://github.com/${username}/${repo}`;
|
|
14
|
-
const manualUrl = `${repoUrl}/settings`;
|
|
15
|
-
|
|
16
|
-
// Fail early if no token available
|
|
17
|
-
if (!githubHelper.hasToken()) {
|
|
18
|
-
this.__consoleError(
|
|
19
|
-
`[github]: No GITHUB_TOKEN found, please visit ${manualUrl} to configure manually.`,
|
|
20
|
-
);
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const settings = {
|
|
25
|
-
allow_merge_commit: false,
|
|
26
|
-
allow_rebase_merge: true,
|
|
27
|
-
allow_squash_merge: true,
|
|
28
|
-
delete_branch_on_merge: true,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
await githubHelper.octokit('repos.update', {
|
|
32
|
-
owner: username,
|
|
33
|
-
repo,
|
|
34
|
-
...settings,
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
this.__consoleSuccess(`GitHub repo configured: ${repoUrl}`);
|
|
38
|
-
return true;
|
|
39
|
-
},
|
|
40
|
-
__consoleSuccess: consoleSuccess,
|
|
41
|
-
__consoleError: consoleError,
|
|
42
|
-
};
|