@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,137 @@
1
+ /**
2
+ * Defines the JSON schema for a project definition.
3
+ */
4
+ export default {
5
+ type: 'object',
6
+ properties: {
7
+ /**
8
+ * Project name
9
+ */
10
+ name: { type: 'string', minLength: 1 },
11
+
12
+ /**
13
+ * Project description
14
+ */
15
+ description: { type: 'string', minLength: 1 },
16
+
17
+ /**
18
+ * Project version
19
+ */
20
+ version: { type: 'string', minLength: 1 },
21
+
22
+ /**
23
+ * Metadata used to configure project builds.
24
+ */
25
+ buildMetadata: {
26
+ type: 'object',
27
+ properties: {
28
+ /**
29
+ * The project type - determines the build tasks that are
30
+ * generated.
31
+ */
32
+ type: {
33
+ enum: [
34
+ 'lib',
35
+ 'api',
36
+ 'cli',
37
+ 'ui',
38
+ 'container',
39
+ 'aws-microservice',
40
+ ],
41
+ },
42
+
43
+ /**
44
+ * The programming language used for the project.
45
+ */
46
+ language: { enum: ['js', 'ts'] },
47
+
48
+ /**
49
+ * AWS configuration - cloud formation stacks, etc.
50
+ */
51
+ aws: {
52
+ type: 'object',
53
+ properties: {
54
+ stacks: {
55
+ type: 'object',
56
+ /**
57
+ * Individual stack names.
58
+ */
59
+ patternProperties: {
60
+ '^[a-zA-Z0-9-_]+$': {
61
+ type: 'string',
62
+ minLength: 1,
63
+ },
64
+ },
65
+ additionalProperties: false,
66
+ },
67
+ },
68
+ additionalProperties: false,
69
+ required: ['stacks'],
70
+ },
71
+
72
+ /**
73
+ * Container configuration - image builds, etc.
74
+ */
75
+ container: {
76
+ type: 'object',
77
+ /**
78
+ * Container build configurations.
79
+ */
80
+ patternProperties: {
81
+ '^[a-zA-Z0-9-_]+$': {
82
+ type: 'object',
83
+ properties: {
84
+ /**
85
+ * Name of the repository that houses the
86
+ * container image.
87
+ */
88
+ repo: { type: 'string', minLength: 1 },
89
+
90
+ /**
91
+ * The file containing build instructions.
92
+ */
93
+ buildFile: { type: 'string', minLength: 1 },
94
+
95
+ /**
96
+ * Collection of arguments passed to the
97
+ * container build.
98
+ */
99
+ buildArgs: {
100
+ type: 'object',
101
+ /**
102
+ * Individual build arguments
103
+ */
104
+ patternProperties: {
105
+ '^[a-zA-Z0-9-_]+$': {
106
+ type: 'string',
107
+ minLength: 1,
108
+ },
109
+ },
110
+ additionalProperties: false,
111
+ },
112
+ },
113
+ required: ['repo'],
114
+ additionalProperties: false,
115
+ },
116
+ },
117
+ required: ['default'],
118
+ additionalProperties: false,
119
+ },
120
+
121
+ /**
122
+ * Any environment variables that have to be defined for the
123
+ * build to succeed.
124
+ */
125
+ requiredEnv: { type: 'array' },
126
+
127
+ /**
128
+ * Any static files that should be copied over during the build
129
+ * process without any compilation/modification.
130
+ */
131
+ staticFilePatterns: { type: 'array' },
132
+ },
133
+ required: ['type', 'language'],
134
+ },
135
+ },
136
+ required: ['name', 'description', 'version', 'buildMetadata'],
137
+ };
@@ -0,0 +1,100 @@
1
+ import { Project } from './project.js';
2
+
3
+ /**
4
+ * Represents a builder class that can construct a Gulp task. This abstract base
5
+ * class must be extended by child classes that provide the required
6
+ * implementation.
7
+ */
8
+ export default class TaskBuilder {
9
+ /**
10
+ * Creates a task builder with the given name and description.
11
+ *
12
+ * @param {string} name The name of the task - this will be the name
13
+ * recognized by gulp, and must be unique.
14
+ * @param {string} description The description of the task - this will be
15
+ * the description shown by gulp.
16
+ */
17
+ constructor(name, description) {
18
+ if (typeof name !== 'string' || name.length <= 0) {
19
+ throw new Error('Invalid name (arg #1)');
20
+ }
21
+ if (typeof description !== 'string' || description.length <= 0) {
22
+ throw new Error('Invalid description (arg #2)');
23
+ }
24
+
25
+ this._name = name;
26
+ this._description = description;
27
+ }
28
+
29
+ /**
30
+ * Creates a new task - needs to be implemented by a child class.
31
+ *
32
+ * @protected
33
+ * @param {Object} project The project for which the task will be created.
34
+ * @returns {Function} A gulp task
35
+ */
36
+ _createTask(project) {
37
+ throw new Error('Not implemented - TaskBuilder._createTask()');
38
+ }
39
+
40
+ /**
41
+ * Gets the name of the task.
42
+ *
43
+ * @returns {String} The task name.
44
+ */
45
+ get name() {
46
+ return this._name;
47
+ }
48
+
49
+ /**
50
+ * Gets the description of the task.
51
+ *
52
+ * @returns {String} The task description.
53
+ */
54
+ get description() {
55
+ return this._description;
56
+ }
57
+
58
+ /**
59
+ * Builds and returns a Gulp task.
60
+ *
61
+ * @param {Object} project The project for which the task will be created.
62
+ * @returns {Function} A gulp task
63
+ */
64
+ buildTask(project) {
65
+ if (!(project instanceof Project)) {
66
+ throw new Error('Invalid project (arg #1)');
67
+ }
68
+ const task = this._createTask(project);
69
+ task.displayName = this._name;
70
+ task.description = this._description;
71
+ return task;
72
+ }
73
+
74
+ /**
75
+ * Returns an array of paths that should be watched for changes when
76
+ * enabling watch (monitor and execute tasks). No watch tasks will be
77
+ * created if this method returns a falsy value or an empty array
78
+ *
79
+ * The default implementation returns an array that watches source files.
80
+ * This implementation can be overridden by child classes to provide
81
+ * specific paths for the task.
82
+ *
83
+ * @param {Object} project The project used to generate watch tasks.
84
+ * @returns {Array} An array of paths to watch.
85
+ */
86
+ getWatchPaths(project) {
87
+ if (!(project instanceof Project)) {
88
+ throw new Error('Invalid project (arg #1)');
89
+ }
90
+ const dirs = ['src', 'test', 'infra'];
91
+ const exts = ['md', 'html', 'json', 'js', 'jsx', 'ts', 'tsx'];
92
+ return dirs
93
+ .map((dir) =>
94
+ exts.map((ext) =>
95
+ project.rootDir.getChild(dir).getAllFilesGlob(ext),
96
+ ),
97
+ )
98
+ .flat();
99
+ }
100
+ }
@@ -0,0 +1,57 @@
1
+ 'use strict';
2
+
3
+ import _gulp from 'gulp';
4
+
5
+ import TaskBuilder from '../task-builder.js';
6
+ import { Project } from '../project.js';
7
+
8
+ /**
9
+ * Builder that can be used to generate a gulp task to copy javascript files
10
+ * from source to build directories.
11
+ */
12
+ export class BuildJsTaskBuilder extends TaskBuilder {
13
+ /**
14
+ * Creates a new task builder.
15
+ */
16
+ constructor() {
17
+ super(
18
+ 'build-js',
19
+ 'Copies javascript files from source to destination directories',
20
+ );
21
+ }
22
+
23
+ /**
24
+ * Generates a gulp task to copy javascript files from source to build
25
+ * directories.
26
+ *
27
+ * @protected
28
+ * @param {Object} project Reference to the project for which the task needs
29
+ * to be defined.
30
+ *
31
+ * @returns {Function} A gulp task.
32
+ */
33
+ _createTask(project) {
34
+ if (!(project instanceof Project)) {
35
+ throw new Error('Invalid project (arg #1)');
36
+ }
37
+
38
+ const { rootDir } = project;
39
+ const dirs = ['src', 'test', 'infra'];
40
+ const extensions = ['js'];
41
+
42
+ const paths = dirs
43
+ .map((dir) => rootDir.getChild(dir))
44
+ .map((dir) => extensions.map((ext) => dir.getAllFilesGlob(ext)))
45
+ .reduce((result, arr) => result.concat(arr), []);
46
+
47
+ const task = () =>
48
+ _gulp
49
+ .src(paths, {
50
+ allowEmpty: true,
51
+ base: rootDir.globPath,
52
+ })
53
+ .pipe(_gulp.dest(rootDir.getChild('working').absolutePath));
54
+
55
+ return task;
56
+ }
57
+ }
@@ -0,0 +1,78 @@
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 { BuildJsTaskBuilder } from './build-js-task-builder.js';
8
+ import { BuildTsTaskBuilder } from './build-ts-task-builder.js';
9
+ import { BuildUiTaskBuilder } from './build-ui-task-builder.js';
10
+ import { CopyFilesTaskBuilder } from './copy-files-task-builder.js';
11
+
12
+ /**
13
+ * General purpose build task that configures sub tasks for build based on the
14
+ * project.
15
+ */
16
+ export class BuildTaskBuilder extends TaskBuilder {
17
+ /**
18
+ * Creates a new task builder.
19
+ */
20
+ constructor() {
21
+ super(
22
+ 'build',
23
+ `Builds the project making it ready for execution/packaging`,
24
+ );
25
+ }
26
+
27
+ /**
28
+ * Generates a gulp task to package a project for building a project.
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
+
41
+ const builders = this._getSubBuilders(project).map((builder) =>
42
+ builder.buildTask(project),
43
+ );
44
+
45
+ const task = _gulp.series(builders);
46
+ return task;
47
+ }
48
+
49
+ /**
50
+ * Returns a list of sub builders based on the project type and language.
51
+ * @private
52
+ */
53
+ _getSubBuilders(project) {
54
+ const { type, language } = project;
55
+ if (type === 'ui') {
56
+ return [new BuildUiTaskBuilder(), new CopyFilesTaskBuilder()];
57
+ } else if (type === 'container') {
58
+ return [new NotSupportedTaskBuilder()];
59
+ } else if (language === 'ts') {
60
+ return [new BuildTsTaskBuilder(), new CopyFilesTaskBuilder()];
61
+ } else {
62
+ return [new BuildJsTaskBuilder(), new CopyFilesTaskBuilder()];
63
+ }
64
+ }
65
+
66
+ /**
67
+ * @override
68
+ */
69
+ getWatchPaths(project) {
70
+ if (!(project instanceof Project)) {
71
+ throw new Error('Invalid project (arg #1)');
72
+ }
73
+ const paths = this._getSubBuilders(project)
74
+ .map((builder) => builder.getWatchPaths(project))
75
+ .flat();
76
+ return [...new Set(paths)];
77
+ }
78
+ }
@@ -0,0 +1,63 @@
1
+ 'use strict';
2
+
3
+ import _gulp from 'gulp';
4
+
5
+ import _typescript from 'gulp-typescript';
6
+ import TaskBuilder from '../task-builder.js';
7
+ import { Project } from '../project.js';
8
+
9
+ /**
10
+ * Builder that can be used to generate a gulp task to compile typescript files.
11
+ */
12
+ export class BuildTsTaskBuilder extends TaskBuilder {
13
+ /**
14
+ * Creates a new task builder.
15
+ */
16
+ constructor() {
17
+ super(
18
+ 'build-ts',
19
+ 'Build typescript files and writes them to the build directory',
20
+ );
21
+ }
22
+
23
+ /**
24
+ * Generates a gulp task to build typescript files.
25
+ *
26
+ * @protected
27
+ * @param {Object} project Reference to the project for which the task needs
28
+ * to be defined.
29
+ *
30
+ * @returns {Function} A gulp task.
31
+ */
32
+ _createTask(project) {
33
+ if (!(project instanceof Project)) {
34
+ throw new Error('Invalid project (arg #1)');
35
+ }
36
+
37
+ const { rootDir } = project;
38
+ const dirs = ['src', 'test', 'infra'];
39
+ const extensions = ['ts'];
40
+
41
+ const paths = dirs
42
+ .map((dir) => rootDir.getChild(dir))
43
+ .map((dir) => extensions.map((ext) => dir.getAllFilesGlob(ext)))
44
+ .reduce((result, arr) => result.concat(arr), []);
45
+
46
+ const task = () =>
47
+ _gulp
48
+ .src(paths, {
49
+ allowEmpty: true,
50
+ base: rootDir.globPath,
51
+ })
52
+ .pipe(_typescript.createProject('tsconfig.json')())
53
+ .on('error', (err) => {
54
+ /*
55
+ * Do nothing. This handler prevents the gulp task from
56
+ * crashing with an unhandled error.
57
+ */
58
+ })
59
+ .pipe(_gulp.dest(rootDir.getChild('working').absolutePath));
60
+
61
+ return task;
62
+ }
63
+ }
@@ -0,0 +1,45 @@
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 that can be used to generate a gulp task to build a web UI project.
9
+ */
10
+ export class BuildUiTaskBuilder extends TaskBuilder {
11
+ /**
12
+ * Creates a new task builder.
13
+ */
14
+ constructor() {
15
+ super('build-ui', 'Build web ui project');
16
+ }
17
+
18
+ /**
19
+ * Generates a gulp task to build a web UI project.
20
+ *
21
+ * @protected
22
+ * @param {Object} project Reference to the project for which the task needs
23
+ * to be defined.
24
+ *
25
+ * @returns {Function} A gulp task.
26
+ */
27
+ _createTask(project) {
28
+ if (!(project instanceof Project)) {
29
+ throw new Error('Invalid project (arg #1)');
30
+ }
31
+
32
+ const viteBin = project.rootDir.getFilePath('node_modules/.bin/vite');
33
+ const task = () =>
34
+ _execa(viteBin, ['build'], { stdio: 'inherit' }).then(
35
+ undefined,
36
+ (err) => {
37
+ /*
38
+ * Do nothing. This handler prevents the gulp task from
39
+ * crashing with an unhandled error.
40
+ */
41
+ },
42
+ );
43
+ return task;
44
+ }
45
+ }
@@ -0,0 +1,39 @@
1
+ import _delete from 'delete';
2
+ import TaskBuilder from '../task-builder.js';
3
+ import { Project } from '../project.js';
4
+
5
+ /**
6
+ * Builder that can be used to generate a gulp task to clean temporary project
7
+ * files.
8
+ */
9
+ export class CleanTaskBuilder extends TaskBuilder {
10
+ /**
11
+ * Creates a new task builder.
12
+ */
13
+ constructor() {
14
+ super(
15
+ 'clean',
16
+ 'Cleans out working, distribution and temporary files and directories',
17
+ );
18
+ }
19
+
20
+ /**
21
+ * Generates a gulp task to clean up temporary project files.
22
+ *
23
+ * @protected
24
+ * @param {Object} project Reference to the project for which the task needs
25
+ * to be defined.
26
+ *
27
+ * @returns {Function} A gulp task.
28
+ */
29
+ _createTask(project) {
30
+ if (!(project instanceof Project)) {
31
+ throw new Error('Invalid project (arg #1)');
32
+ }
33
+ const rootDir = project.rootDir;
34
+ const dirs = ['coverage', 'dist', 'working', '.tscache', 'cdk.out'];
35
+
36
+ const paths = dirs.map((dir) => rootDir.getChild(dir).globPath);
37
+ return () => _delete(paths);
38
+ }
39
+ }
@@ -0,0 +1,78 @@
1
+ 'use strict';
2
+
3
+ import _gulp from 'gulp';
4
+
5
+ import TaskBuilder from '../task-builder.js';
6
+ import { Project } from '../project.js';
7
+
8
+ /**
9
+ * Builder that can be used to generate a gulp task to copy project files from
10
+ * source to build directories.
11
+ */
12
+ export class CopyFilesTaskBuilder extends TaskBuilder {
13
+ /**
14
+ * Creates a new task builder.
15
+ */
16
+ constructor() {
17
+ super(
18
+ 'copy-files',
19
+ 'Copies project files from source to build directories',
20
+ );
21
+ }
22
+
23
+ /**
24
+ * Generates a gulp task to copy common files from source to build
25
+ * directories.
26
+ *
27
+ * @protected
28
+ * @param {Object} project Reference to the project for which the task needs
29
+ * to be defined.
30
+ *
31
+ * @returns {Function} A gulp task.
32
+ */
33
+ _createTask(project) {
34
+ if (!(project instanceof Project)) {
35
+ throw new Error('Invalid project (arg #1)');
36
+ }
37
+
38
+ const { rootDir } = project;
39
+ const dirs = ['src', 'test', 'infra'];
40
+ const extensions = ['json'].concat(project.getStaticFilePatterns());
41
+ const containerBuildFiles = project
42
+ .getContainerTargets()
43
+ .map(
44
+ (target) =>
45
+ project.getContainerDefinition(target).buildFile ||
46
+ 'Dockerfile',
47
+ );
48
+
49
+ const extras = [
50
+ project.configFileName,
51
+ 'package-lock.json',
52
+ 'package.json',
53
+ 'LICENSE',
54
+ 'README.md',
55
+ '_scripts/*',
56
+ 'nginx.conf',
57
+ '.env',
58
+ '.npmignore',
59
+ '.npmrc',
60
+ ].concat(containerBuildFiles);
61
+
62
+ const paths = dirs
63
+ .map((dir) => rootDir.getChild(dir))
64
+ .map((dir) => extensions.map((ext) => dir.getAllFilesGlob(ext)))
65
+ .reduce((result, arr) => result.concat(arr), [])
66
+ .concat(extras.map((item) => rootDir.getFileGlob(item)));
67
+
68
+ const task = () =>
69
+ _gulp
70
+ .src(paths, {
71
+ allowEmpty: true,
72
+ base: rootDir.globPath,
73
+ })
74
+ .pipe(_gulp.dest(rootDir.getChild('working').absolutePath));
75
+
76
+ return task;
77
+ }
78
+ }
@@ -0,0 +1,74 @@
1
+ import _path from 'path';
2
+ import _gulp from 'gulp';
3
+ import _gulpJsdoc from 'gulp-jsdoc3';
4
+
5
+ import TaskBuilder from '../task-builder.js';
6
+ import { Project } from '../project.js';
7
+
8
+ /**
9
+ * Builder that can be used to generate a gulp task to generate documentation
10
+ * from code comments in javascript files.
11
+ */
12
+ export class DocsJsTaskBuilder extends TaskBuilder {
13
+ /**
14
+ * Creates a new task builder.
15
+ */
16
+ constructor() {
17
+ super(
18
+ 'docs-js',
19
+ 'Generates documentation from code comments in javascript files',
20
+ );
21
+ }
22
+
23
+ /**
24
+ * Generates a gulp task to generate documentation from code comments in
25
+ * source code.
26
+ *
27
+ * @protected
28
+ * @param {Object} project Reference to the project for which the task needs
29
+ * to be defined.
30
+ *
31
+ * @returns {Function} A gulp task.
32
+ */
33
+ _createTask(project) {
34
+ if (!(project instanceof Project)) {
35
+ throw new Error('Invalid project (arg #1)');
36
+ }
37
+
38
+ const { rootDir, name, version } = project;
39
+ const docsDir = rootDir.getChild('docs');
40
+
41
+ const dirs = ['src'];
42
+ const extensions = ['js'];
43
+ const options = {
44
+ opts: {
45
+ readme: rootDir.getFilePath('README.md'),
46
+ destination: docsDir.getFilePath(
47
+ `${name}${_path.sep}${version}`,
48
+ ),
49
+ template: _path.join('node_modules', 'docdash'),
50
+ },
51
+ };
52
+
53
+ const paths = dirs
54
+ .map((dir) => project.rootDir.getChild(dir))
55
+ .map((dir) => extensions.map((ext) => dir.getAllFilesGlob(ext)))
56
+ .reduce((result, arr) => result.concat(arr), []);
57
+
58
+ const task = () =>
59
+ _gulp
60
+ .src(paths, {
61
+ allowEmpty: true,
62
+ base: project.rootDir.globPath,
63
+ })
64
+ .pipe(_gulpJsdoc(options))
65
+ .on('error', (err) => {
66
+ /*
67
+ * Do nothing. This handler prevents the gulp task from
68
+ * crashing with an unhandled error.
69
+ */
70
+ console.error(err);
71
+ });
72
+ return task;
73
+ }
74
+ }