@vamship/build-utils 1.6.1 → 2.0.0-1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. package/package.json +40 -40
  2. package/src/directory.js +20 -24
  3. package/src/index.js +5 -17
  4. package/src/project.js +160 -433
  5. package/src/schema/project-definition.js +137 -0
  6. package/src/task-builder.js +100 -0
  7. package/src/task-builders/build-js-task-builder.js +57 -0
  8. package/src/task-builders/build-task-builder.js +78 -0
  9. package/src/task-builders/build-ts-task-builder.js +63 -0
  10. package/src/task-builders/build-ui-task-builder.js +45 -0
  11. package/src/task-builders/clean-task-builder.js +39 -0
  12. package/src/task-builders/copy-files-task-builder.js +78 -0
  13. package/src/task-builders/docs-js-task-builder.js +74 -0
  14. package/src/task-builders/docs-task-builder.js +74 -0
  15. package/src/task-builders/docs-ts-task-builder.js +52 -0
  16. package/src/task-builders/format-task-builder.js +61 -0
  17. package/src/task-builders/index.js +21 -17
  18. package/src/task-builders/lint-fix-task-builder.js +61 -0
  19. package/src/task-builders/lint-task-builder.js +56 -0
  20. package/src/task-builders/not-supported-task-builder.js +48 -0
  21. package/src/task-builders/package-aws-task-builder.js +105 -0
  22. package/src/task-builders/package-container-task-builder.js +132 -0
  23. package/src/task-builders/package-npm-task-builder.js +83 -0
  24. package/src/task-builders/package-task-builder.js +101 -0
  25. package/src/task-builders/publish-aws-task-builder.js +111 -0
  26. package/src/task-builders/publish-container-task-builder.js +103 -0
  27. package/src/task-builders/publish-npm-task-builder.js +60 -0
  28. package/src/task-builders/publish-task-builder.js +98 -0
  29. package/src/task-builders/test-task-builder.js +85 -0
  30. package/src/task-builders/test-ui-task-builder.js +65 -0
  31. package/src/task-builders/watch-task-builder.js +109 -0
  32. package/src/task-factories/api-task-factory.js +67 -0
  33. package/src/task-factories/aws-microservice-task-factory.js +53 -0
  34. package/src/task-factories/cli-task-factory.js +68 -0
  35. package/src/task-factories/container-task-factory.js +64 -0
  36. package/src/task-factories/index.js +8 -0
  37. package/src/task-factories/lib-task-factory.js +52 -0
  38. package/src/task-factories/ui-task-factory.js +48 -0
  39. package/src/task-factory.js +52 -0
  40. package/src/utils/semver-utils.js +29 -0
  41. package/src/utils/task-factory-utils.js +70 -0
  42. package/src/task-builders/build/build-js.js +0 -66
  43. package/src/task-builders/build/build-ts.js +0 -70
  44. package/src/task-builders/build/build-types.js +0 -47
  45. package/src/task-builders/build/build-ui.js +0 -67
  46. package/src/task-builders/build/index.js +0 -60
  47. package/src/task-builders/clean.js +0 -57
  48. package/src/task-builders/docs/docs-js.js +0 -41
  49. package/src/task-builders/docs/docs-ts.js +0 -40
  50. package/src/task-builders/docs/index.js +0 -32
  51. package/src/task-builders/format.js +0 -58
  52. package/src/task-builders/lint.js +0 -56
  53. package/src/task-builders/package/index.js +0 -50
  54. package/src/task-builders/package/package-aws.js +0 -58
  55. package/src/task-builders/package/package-docker.js +0 -128
  56. package/src/task-builders/package/package-npm.js +0 -25
  57. package/src/task-builders/package/package-types.js +0 -54
  58. package/src/task-builders/package/utils.js +0 -50
  59. package/src/task-builders/publish/index.js +0 -50
  60. package/src/task-builders/publish/publish-aws.js +0 -62
  61. package/src/task-builders/publish/publish-docker.js +0 -79
  62. package/src/task-builders/publish/publish-npm.js +0 -36
  63. package/src/task-builders/publish/publish-types.js +0 -36
  64. package/src/task-builders/test/index.js +0 -39
  65. package/src/task-builders/test/test-ui.js +0 -39
  66. package/src/task-builders/test/test.js +0 -67
@@ -0,0 +1,83 @@
1
+ 'use strict';
2
+
3
+ import TaskBuilder from '../task-builder.js';
4
+ import { Project } from '../project.js';
5
+ import { execa as _execa } from 'execa';
6
+ import _gulp from 'gulp';
7
+ import _delete from 'delete';
8
+
9
+ /**
10
+ * Builder function that can be used to generate a gulp task to package an
11
+ * project for publishing to an NPM registry.
12
+ */
13
+ export class PackageNpmTaskBuilder extends TaskBuilder {
14
+ /**
15
+ * Creates a new task builder.
16
+ */
17
+ constructor() {
18
+ super('package-npm', `Package a project for publishing to NPM`);
19
+ }
20
+
21
+ /**
22
+ * Generates a gulp task to execute automated tests
23
+ *
24
+ * @protected
25
+ * @param {Object} project Reference to the project for which the task needs
26
+ * to be defined.
27
+ *
28
+ * @returns {Function} A gulp task.
29
+ */
30
+ _createTask(project) {
31
+ if (!(project instanceof Project)) {
32
+ throw new Error('Invalid project (arg #1)');
33
+ }
34
+
35
+ const packageName = `${project.kebabCasedName}-${project.version}.tgz`;
36
+ const jsDir =
37
+ project.language === 'js'
38
+ ? project.rootDir
39
+ : project.rootDir.getChild('working');
40
+ const srcPath = jsDir.getFilePath(packageName);
41
+ const distDir = project.rootDir.getChild('dist');
42
+
43
+ const npmBin = 'npm';
44
+ const packTask = () =>
45
+ _execa(npmBin, ['pack'], {
46
+ stdio: 'inherit',
47
+ cwd: jsDir.absolutePath,
48
+ }).then(undefined, (err) => {
49
+ /*
50
+ * Do nothing. This handler prevents the gulp task from
51
+ * crashing with an unhandled error.
52
+ */
53
+ });
54
+
55
+ const copyTask = () =>
56
+ _gulp.src(srcPath).pipe(_gulp.dest(distDir.absolutePath));
57
+ const deleteTask = () => _delete([srcPath]);
58
+
59
+ const task = _gulp.series([packTask, copyTask, deleteTask]);
60
+ return task;
61
+ }
62
+
63
+ /**
64
+ * @override
65
+ */
66
+ getWatchPaths(project) {
67
+ if (!(project instanceof Project)) {
68
+ throw new Error('Invalid project (arg #1)');
69
+ }
70
+ const dirs = ['src', 'test', 'infra'];
71
+ const exts = ['md', 'html', 'json', 'js', 'jsx', 'ts', 'tsx'];
72
+ const rootDir =
73
+ project.language === 'ts'
74
+ ? project.rootDir.getChild('working')
75
+ : project.rootDir;
76
+
77
+ return dirs
78
+ .map((dir) =>
79
+ exts.map((ext) => rootDir.getChild(dir).getAllFilesGlob(ext)),
80
+ )
81
+ .flat();
82
+ }
83
+ }
@@ -0,0 +1,101 @@
1
+ 'use strict';
2
+
3
+ import _gulp from 'gulp';
4
+ import TaskBuilder from '../task-builder.js';
5
+ import { Project } from '../project.js';
6
+ import { NotSupportedTaskBuilder } from './not-supported-task-builder.js';
7
+ import { PackageAwsTaskBuilder } from './package-aws-task-builder.js';
8
+ import { PackageNpmTaskBuilder } from './package-npm-task-builder.js';
9
+ import { PackageContainerTaskBuilder } from './package-container-task-builder.js';
10
+
11
+ /**
12
+ * General purpose packaging task that configures sub tasks for packaging based
13
+ * on the project. When a project is an API or container and has multiple container
14
+ * targets, this task will package the target named "default". When the project is
15
+ * a CLI and there is a "default" container defined, this task will package that,
16
+ * if there is no container defined, it will package using npm.
17
+ */
18
+ export class PackageTaskBuilder extends TaskBuilder {
19
+ /**
20
+ * Creates a new task builder.
21
+ */
22
+ constructor() {
23
+ super(
24
+ 'package',
25
+ `Packages project build files for publishing to a repository`,
26
+ );
27
+ }
28
+
29
+ /**
30
+ * Generates a gulp task to package a project for packaging a project.
31
+ *
32
+ * @protected
33
+ * @param {Object} project Reference to the project for which the task needs
34
+ * to be defined.
35
+ *
36
+ * @returns {Function} A gulp task.
37
+ */
38
+ _createTask(project) {
39
+ if (!(project instanceof Project)) {
40
+ throw new Error('Invalid project (arg #1)');
41
+ }
42
+
43
+ const builders = this._getSubBuilders(project).map((builder) =>
44
+ builder.buildTask(project),
45
+ );
46
+
47
+ const task = _gulp.series(builders);
48
+ return task;
49
+ }
50
+
51
+ /**
52
+ * Returns a list of sub builders based on the project type and language.
53
+ * @private
54
+ */
55
+ _getSubBuilders(project) {
56
+ const { type } = project;
57
+ const containerTargetList = project.getContainerTargets();
58
+
59
+ // Type lib
60
+ if (type === 'lib') {
61
+ return [new PackageNpmTaskBuilder()];
62
+ }
63
+ // Type aws-microservice
64
+ else if (type === 'aws-microservice') {
65
+ return [new PackageAwsTaskBuilder()];
66
+ }
67
+ // Type container
68
+ else if (type === 'container') {
69
+ return [new PackageContainerTaskBuilder('default')];
70
+ }
71
+ // Type cli
72
+ else if (type === 'cli') {
73
+ if (containerTargetList.length > 0) {
74
+ return [new PackageContainerTaskBuilder('default')];
75
+ } else {
76
+ return [new PackageNpmTaskBuilder()];
77
+ }
78
+ }
79
+ // Type api
80
+ else if (type === 'api') {
81
+ return [new PackageContainerTaskBuilder('default')];
82
+ }
83
+ // Type ui (and potentially others that are not supported)
84
+ else {
85
+ return [new NotSupportedTaskBuilder()];
86
+ }
87
+ }
88
+
89
+ /**
90
+ * @override
91
+ */
92
+ getWatchPaths(project) {
93
+ if (!(project instanceof Project)) {
94
+ throw new Error('Invalid project (arg #1)');
95
+ }
96
+ const paths = this._getSubBuilders(project)
97
+ .map((builder) => builder.getWatchPaths(project))
98
+ .flat();
99
+ return [...new Set(paths)];
100
+ }
101
+ }
@@ -0,0 +1,111 @@
1
+ 'use strict';
2
+
3
+ import TaskBuilder from '../task-builder.js';
4
+ import { Project } from '../project.js';
5
+ import { execa as _execa } from 'execa';
6
+ import { config as _dotenvConfig } from 'dotenv';
7
+ import _dotenvExpand from 'dotenv-expand';
8
+
9
+ /**
10
+ * Builder function that can be used to generate a gulp task to publish a CDK
11
+ * project to AWS.
12
+ */
13
+ export class PublishAwsTaskBuilder extends TaskBuilder {
14
+ /**
15
+ * Creates a new task builder.
16
+ *
17
+ * @param {String} target The name of the CDK stack target
18
+ * @param {String} environment The name of the environment to use for
19
+ * sourcing environment variables.
20
+ * @param {Boolean} requireApproval A flag that indicates whether or not the
21
+ * publish task requires interactive approval from the user.
22
+ */
23
+ constructor(target, environment, requireApproval) {
24
+ if (typeof target !== 'string' || target.length === 0) {
25
+ throw new Error('Invalid target (arg #1)');
26
+ }
27
+ if (typeof environment !== 'string' || environment.length === 0) {
28
+ throw new Error('Invalid environment (arg #2)');
29
+ }
30
+ if (typeof requireApproval !== 'boolean') {
31
+ throw new Error('Invalid requireApproval (arg #3)');
32
+ }
33
+ super('publish-aws', `Publish a CDK project to AWS`);
34
+
35
+ this._target = target;
36
+ this._environment = environment;
37
+ this._requireApproval = requireApproval;
38
+ }
39
+
40
+ /**
41
+ * Generates a gulp task to execute automated tests
42
+ *
43
+ * @protected
44
+ * @param {Object} project Reference to the project for which the task needs
45
+ * to be defined.
46
+ *
47
+ * @returns {Function} A gulp task.
48
+ */
49
+ _createTask(project) {
50
+ if (!(project instanceof Project)) {
51
+ throw new Error('Invalid project (arg #1)');
52
+ }
53
+
54
+ const definition = project.getCdkStackDefinition(this._target);
55
+ const infraDir = project.rootDir.getChild('infra');
56
+ const jsDir =
57
+ project.language === 'js'
58
+ ? project.rootDir
59
+ : project.rootDir.getChild('working');
60
+
61
+ const task = () => {
62
+ [`.env.${this._environment}`, '.env']
63
+ .map((envFile) => infraDir.getFileGlob(envFile))
64
+ .forEach((envFile) => {
65
+ _dotenvExpand(_dotenvConfig(envFile));
66
+ });
67
+
68
+ const undefinedVars = project.getUndefinedEnvironmentVariables();
69
+ if (undefinedVars.length > 0) {
70
+ throw new Error(
71
+ `Missing required environment variables: [${undefinedVars.join(
72
+ ',',
73
+ )}]`,
74
+ );
75
+ }
76
+
77
+ const cdkBin = 'cdk';
78
+ const args = [
79
+ 'deploy',
80
+ definition.name,
81
+ '--app',
82
+ jsDir.getChild('infra').getFilePath('index'),
83
+ ];
84
+
85
+ if (this._requireApproval) {
86
+ args.splice(1, 0, '--require-approval=never');
87
+ }
88
+
89
+ _execa(cdkBin, args, {
90
+ stdio: 'inherit',
91
+ cwd: jsDir.absolutePath,
92
+ }).then(undefined, (err) => {
93
+ /*
94
+ * Do nothing. This handler prevents the gulp task from
95
+ * crashing with an unhandled error.
96
+ */
97
+ });
98
+ };
99
+ return task;
100
+ }
101
+
102
+ /**
103
+ * @override
104
+ */
105
+ getWatchPaths(project) {
106
+ if (!(project instanceof Project)) {
107
+ throw new Error('Invalid project (arg #1)');
108
+ }
109
+ return [];
110
+ }
111
+ }
@@ -0,0 +1,103 @@
1
+ 'use strict';
2
+
3
+ import TaskBuilder from '../task-builder.js';
4
+ import { Project } from '../project.js';
5
+ import { execa as _execa } from 'execa';
6
+ import _gulp from 'gulp';
7
+ import { getSemverComponents } from '../utils/semver-utils.js';
8
+
9
+ /**
10
+ * Builder function that can be used to generate a gulp task to publish a CDK
11
+ * project to CONTAINER.
12
+ */
13
+ export class PublishContainerTaskBuilder extends TaskBuilder {
14
+ /**
15
+ * Creates a new task builder.
16
+ *
17
+ * @param {String} target The name of the CDK stack target
18
+ * @param {String} [tag='latest'] An optional tag to apply to the container
19
+ * image.
20
+ */
21
+ constructor(target, tag = 'latest') {
22
+ if (typeof target !== 'string' || target.length === 0) {
23
+ throw new Error('Invalid target (arg #1)');
24
+ }
25
+ if (
26
+ typeof tag !== 'undefined' &&
27
+ (typeof tag !== 'string' || tag.length === 0)
28
+ ) {
29
+ throw new Error('Invalid tag (arg #2)');
30
+ }
31
+ super(
32
+ // When specifying the container target, if it is not called default, this
33
+ // will create a named task
34
+ `publish-container${target === 'default' ? '' : '-' + target}`,
35
+ `Publish container image for ${target}:${tag}`,
36
+ );
37
+
38
+ this._target = target;
39
+ this._tag = tag;
40
+ }
41
+
42
+ /**
43
+ * Generates a gulp task to execute automated tests
44
+ *
45
+ * @protected
46
+ * @param {Object} project Reference to the project for which the task needs
47
+ * to be defined.
48
+ *
49
+ * @returns {Function} A gulp task.
50
+ */
51
+ _createTask(project) {
52
+ if (!(project instanceof Project)) {
53
+ throw new Error('Invalid project (arg #1)');
54
+ }
55
+
56
+ const definition = project.getContainerDefinition(this._target);
57
+
58
+ const semverComponents = getSemverComponents(this._tag);
59
+ const tagTaskList = semverComponents.map((tag) => {
60
+ const tagTask = () =>
61
+ // Per docker docs `docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]`
62
+ _execa(
63
+ 'docker',
64
+ ['tag', definition.name, `${definition.name}:${tag}`],
65
+ {
66
+ stdio: 'inherit',
67
+ },
68
+ ).then(undefined, (err) => {
69
+ /*
70
+ * Do nothing. This handler prevents the gulp task from
71
+ * crashing with an unhandled error.
72
+ */
73
+ });
74
+ return tagTask;
75
+ });
76
+ const pushTaskList = semverComponents.map((tag) => {
77
+ const pushTask = () =>
78
+ // Per docker docs `docker push [OPTIONS] NAME[:TAG]`
79
+ _execa('docker', ['push', `${definition.name}:${tag}`], {
80
+ stdio: 'inherit',
81
+ }).then(undefined, (err) => {
82
+ /*
83
+ * Do nothing. This handler prevents the gulp task from
84
+ * crashing with an unhandled error.
85
+ */
86
+ });
87
+ return pushTask;
88
+ });
89
+
90
+ const task = _gulp.series([...tagTaskList, ...pushTaskList]);
91
+ return task;
92
+ }
93
+
94
+ /**
95
+ * @override
96
+ */
97
+ getWatchPaths(project) {
98
+ if (!(project instanceof Project)) {
99
+ throw new Error('Invalid project (arg #1)');
100
+ }
101
+ return [];
102
+ }
103
+ }
@@ -0,0 +1,60 @@
1
+ 'use strict';
2
+
3
+ import TaskBuilder from '../task-builder.js';
4
+ import { Project } from '../project.js';
5
+ import { execa as _execa } from 'execa';
6
+
7
+ /**
8
+ * Builder function that can be used to generate a gulp task to publish an
9
+ * already packaged project to an NPM registry.
10
+ */
11
+ export class PublishNpmTaskBuilder extends TaskBuilder {
12
+ /**
13
+ * Creates a new task builder.
14
+ */
15
+ constructor() {
16
+ super('publish-npm', `Publish a project to an NPM registry`);
17
+ }
18
+
19
+ /**
20
+ * Generates a gulp task to execute automated tests
21
+ *
22
+ * @protected
23
+ * @param {Object} project Reference to the project for which the task needs
24
+ * to be defined.
25
+ *
26
+ * @returns {Function} A gulp task.
27
+ */
28
+ _createTask(project) {
29
+ if (!(project instanceof Project)) {
30
+ throw new Error('Invalid project (arg #1)');
31
+ }
32
+
33
+ const packageName = `${project.kebabCasedName}-${project.version}.tgz`;
34
+ const distDir = project.rootDir.getChild('dist');
35
+
36
+ const npmBin = 'npm';
37
+ const task = () =>
38
+ _execa(npmBin, ['publish', packageName], {
39
+ stdio: 'inherit',
40
+ cwd: distDir.absolutePath,
41
+ }).then(undefined, (err) => {
42
+ /*
43
+ * Do nothing. This handler prevents the gulp task from
44
+ * crashing with an unhandled error.
45
+ */
46
+ });
47
+
48
+ return task;
49
+ }
50
+
51
+ /**
52
+ * @override
53
+ */
54
+ getWatchPaths(project) {
55
+ if (!(project instanceof Project)) {
56
+ throw new Error('Invalid project (arg #1)');
57
+ }
58
+ return [];
59
+ }
60
+ }
@@ -0,0 +1,98 @@
1
+ 'use strict';
2
+
3
+ import _gulp from 'gulp';
4
+ import TaskBuilder from '../task-builder.js';
5
+ import { Project } from '../project.js';
6
+ import { NotSupportedTaskBuilder } from './not-supported-task-builder.js';
7
+ import { PublishAwsTaskBuilder } from './publish-aws-task-builder.js';
8
+ import { PublishNpmTaskBuilder } from './publish-npm-task-builder.js';
9
+ import { PublishContainerTaskBuilder } from './publish-container-task-builder.js';
10
+
11
+ /**
12
+ * General purpose publishing task that configures sub tasks for publishing based
13
+ * on the project. When a project is an API or container and has multiple container
14
+ * targets, this task will publish the target named "default". When the project is
15
+ * a CLI and there is a "default" container defined, this task will publish that,
16
+ * if there is no container defined, it will publish using npm.
17
+ */
18
+ export class PublishTaskBuilder extends TaskBuilder {
19
+ /**
20
+ * Creates a new task builder.
21
+ */
22
+ constructor() {
23
+ super('publish', `Publishes project to a repository`);
24
+ }
25
+
26
+ /**
27
+ * Generates a gulp task to publish a project.
28
+ *
29
+ * @protected
30
+ * @param {Object} project Reference to the project for which the task needs
31
+ * to be defined.
32
+ *
33
+ * @returns {Function} A gulp task.
34
+ */
35
+ _createTask(project) {
36
+ if (!(project instanceof Project)) {
37
+ throw new Error('Invalid project (arg #1)');
38
+ }
39
+
40
+ const builders = this._getSubBuilders(project).map((builder) =>
41
+ builder.buildTask(project),
42
+ );
43
+
44
+ const task = _gulp.series(builders);
45
+ return task;
46
+ }
47
+
48
+ /**
49
+ * Returns a list of sub builders based on the project type and language.
50
+ * @private
51
+ */
52
+ _getSubBuilders(project) {
53
+ const { type } = project;
54
+ const containerTargetList = project.getContainerTargets();
55
+
56
+ // Type lib
57
+ if (type === 'lib') {
58
+ return [new PublishNpmTaskBuilder()];
59
+ }
60
+ // Type aws-microservice
61
+ else if (type === 'aws-microservice') {
62
+ return [new PublishAwsTaskBuilder()];
63
+ }
64
+ // Type container
65
+ else if (type === 'container') {
66
+ return [new PublishContainerTaskBuilder('default')];
67
+ }
68
+ // Type cli
69
+ else if (type === 'cli') {
70
+ if (containerTargetList.length > 0) {
71
+ return [new PublishContainerTaskBuilder('default')];
72
+ } else {
73
+ return [new PublishNpmTaskBuilder()];
74
+ }
75
+ }
76
+ // Type api
77
+ else if (type === 'api') {
78
+ return [new PublishContainerTaskBuilder('default')];
79
+ }
80
+ // Type ui (and potentially others that are not supported)
81
+ else {
82
+ return [new NotSupportedTaskBuilder()];
83
+ }
84
+ }
85
+
86
+ /**
87
+ * @override
88
+ */
89
+ getWatchPaths(project) {
90
+ if (!(project instanceof Project)) {
91
+ throw new Error('Invalid project (arg #1)');
92
+ }
93
+ const paths = this._getSubBuilders(project)
94
+ .map((builder) => builder.getWatchPaths(project))
95
+ .flat();
96
+ return [...new Set(paths)];
97
+ }
98
+ }
@@ -0,0 +1,85 @@
1
+ 'use strict';
2
+
3
+ import TaskBuilder from '../task-builder.js';
4
+ import { Project } from '../project.js';
5
+ import { execa as _execa } from 'execa';
6
+
7
+ /**
8
+ * Builder function that can be used to generate a gulp task to execute
9
+ * instrumented unit/api tests.
10
+ */
11
+ export class TestTaskBuilder extends TaskBuilder {
12
+ /**
13
+ * Creates a new task builder.
14
+ *
15
+ * @param {String} testType The type of test to execute. Must be one of
16
+ * "unit" or "api".
17
+ */
18
+ constructor(testType) {
19
+ if (['unit', 'api'].indexOf(testType) < 0) {
20
+ throw new Error('Invalid testType (arg #1)');
21
+ }
22
+ super(`test-${testType}`, `Execute ${testType} tests`);
23
+
24
+ this._testType = testType;
25
+ }
26
+
27
+ /**
28
+ * Generates a gulp task to execute automated tests
29
+ *
30
+ * @protected
31
+ * @param {Object} project Reference to the project for which the task needs
32
+ * to be defined.
33
+ *
34
+ * @returns {Function} A gulp task.
35
+ */
36
+ _createTask(project) {
37
+ if (!(project instanceof Project)) {
38
+ throw new Error('Invalid project (arg #1)');
39
+ }
40
+ const mochaBin = project.rootDir.getFilePath('node_modules/.bin/mocha');
41
+ const c8Bin = project.rootDir.getFilePath('node_modules/.bin/c8');
42
+ const jsRootDir =
43
+ project.language === 'ts'
44
+ ? project.rootDir.getChild('working')
45
+ : project.rootDir;
46
+
47
+ const args = [
48
+ '-x {working/,}test/**',
49
+ mochaBin,
50
+ '--no-config',
51
+ '--loader=esmock',
52
+ jsRootDir.getChild(`test/${this._testType}`).getAllFilesGlob('js'),
53
+ ];
54
+
55
+ const task = () =>
56
+ _execa(c8Bin, args, { stdio: 'inherit' }).then(undefined, () => {
57
+ /*
58
+ * Do nothing. This handler prevents the gulp task from
59
+ * crashing with an unhandled error.
60
+ */
61
+ });
62
+ return task;
63
+ }
64
+
65
+ /**
66
+ * @override
67
+ */
68
+ getWatchPaths(project) {
69
+ if (!(project instanceof Project)) {
70
+ throw new Error('Invalid project (arg #1)');
71
+ }
72
+ const dirs = ['src', 'test', 'infra'];
73
+ const exts = ['md', 'html', 'json', 'js', 'jsx', 'ts', 'tsx'];
74
+ const rootDir =
75
+ project.language === 'ts'
76
+ ? project.rootDir.getChild('working')
77
+ : project.rootDir;
78
+
79
+ return dirs
80
+ .map((dir) =>
81
+ exts.map((ext) => rootDir.getChild(dir).getAllFilesGlob(ext)),
82
+ )
83
+ .flat();
84
+ }
85
+ }