@vamship/build-utils 2.0.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vamship/build-utils",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "Utility library for build tooling",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -46,29 +46,29 @@
46
46
  },
47
47
  "homepage": "https://github.com/vamship/build-utils#readme",
48
48
  "devDependencies": {
49
- "c8": "^9.1.0",
49
+ "c8": "^10.1.2",
50
50
  "chai": "^4.4.1",
51
- "dot-prop": "^8.0.2",
51
+ "dot-prop": "^9.0.0",
52
52
  "eslint": "^8.56.0",
53
- "esmock": "^2.6.5",
54
- "gulp-eslint-new": "^2.0.0",
53
+ "esmock": "^2.6.6",
54
+ "gulp-eslint-new": "^2.1.0",
55
55
  "jsdoc": "^4.0.3",
56
- "mocha": "^10.4.0",
57
- "nodemon": "^3.1.0",
58
- "prettier": "^3.2.5",
56
+ "mocha": "^10.5.2",
57
+ "nodemon": "^3.1.4",
58
+ "prettier": "^3.3.2",
59
59
  "rewire": "^7.0.0",
60
- "sinon": "^17.0.2",
60
+ "sinon": "^18.0.0",
61
61
  "sinon-chai": "^3.7.0"
62
62
  },
63
63
  "dependencies": {
64
- "ajv": "^8.13.0",
64
+ "ajv": "^8.16.0",
65
65
  "ansi-colors": "^4.1.3",
66
66
  "change-case": "^5.4.4",
67
67
  "delete": "^1.1.0",
68
68
  "docdash": "^2.0.2",
69
69
  "dotenv": "^16.4.5",
70
70
  "dotenv-expand": "^11.0.6",
71
- "execa": "^9.0.1",
71
+ "execa": "^9.3.0",
72
72
  "fancy-log": ">=2.0.0",
73
73
  "mkdirp": "^3.0.1",
74
74
  "semver": "^7.6.2"
@@ -91,7 +91,7 @@
91
91
  },
92
92
  "optionalDependencies": {
93
93
  "gulp-jsdoc3": "= 3.0.0",
94
- "typedoc": ">=0.25.13",
95
- "typescript": ">=5.4.5"
94
+ "typedoc": ">=0.26.2",
95
+ "typescript": ">=5.5.2"
96
96
  }
97
97
  }
package/src/directory.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import _path from 'path';
2
+ import _fs from 'fs';
2
3
 
3
4
  const _sepRegexp = new RegExp(_path.sep.replace(/\\/g, '\\\\'), 'g');
4
5
 
@@ -120,6 +121,16 @@ export class Directory {
120
121
  return this._globPath;
121
122
  }
122
123
 
124
+ /**
125
+ * Returns a boolean indicating whether the directory exists on the file
126
+ * system.
127
+ *
128
+ * @return {Boolean} True if the directory exists, false otherwise.
129
+ */
130
+ exists() {
131
+ return _fs.existsSync(this.absolutePath);
132
+ }
133
+
123
134
  /**
124
135
  * Adds a child directory object to the current directory.
125
136
  *
package/src/project.js CHANGED
@@ -57,6 +57,12 @@ export class Project {
57
57
  );
58
58
  }
59
59
 
60
+ if (type === 'aws-microservice' && !aws) {
61
+ throw new Error(
62
+ `AWS microservice projects require AWS configuration`,
63
+ );
64
+ }
65
+
60
66
  if (aws && aws.stacks && Object.keys(aws.stacks).length <= 0) {
61
67
  throw new Error(`No AWS stacks defined`);
62
68
  }
@@ -243,6 +249,11 @@ export class Project {
243
249
  * @return {Array} A list of stack keys
244
250
  */
245
251
  getCdkTargets() {
252
+ if (this._type !== 'aws-microservice') {
253
+ throw new Error(
254
+ 'CDK targets are only available for AWS microservices',
255
+ );
256
+ }
246
257
  return Object.keys(this._cdkTargets);
247
258
  }
248
259
 
@@ -36,9 +36,13 @@ export class BuildJsTaskBuilder extends TaskBuilder {
36
36
  }
37
37
 
38
38
  const { rootDir } = project;
39
- const dirs = ['src', 'test', 'infra'];
39
+ const dirs = ['src', 'test'];
40
40
  const extensions = ['js'];
41
41
 
42
+ if (project.type === 'aws-microservice') {
43
+ dirs.push('infra');
44
+ }
45
+
42
46
  const paths = dirs
43
47
  .map((dir) => rootDir.getChild(dir))
44
48
  .map((dir) => extensions.map((ext) => dir.getAllFilesGlob(ext)))
@@ -35,9 +35,13 @@ export class BuildTsTaskBuilder extends TaskBuilder {
35
35
  }
36
36
 
37
37
  const { rootDir } = project;
38
- const dirs = ['src', 'test', 'infra'];
38
+ const dirs = ['src', 'test'];
39
39
  const extensions = ['ts'];
40
40
 
41
+ if (project.type === 'aws-microservice') {
42
+ dirs.push('infra');
43
+ }
44
+
41
45
  const paths = dirs
42
46
  .map((dir) => rootDir.getChild(dir))
43
47
  .map((dir) => extensions.map((ext) => dir.getAllFilesGlob(ext)))
@@ -36,7 +36,7 @@ export class CopyFilesTaskBuilder extends TaskBuilder {
36
36
  }
37
37
 
38
38
  const { rootDir } = project;
39
- const dirs = ['src', 'test', 'infra'];
39
+ const dirs = ['src', 'test'];
40
40
  const extensions = ['json'].concat(project.getStaticFilePatterns());
41
41
  const containerBuildFiles = project
42
42
  .getContainerTargets()
@@ -46,6 +46,10 @@ export class CopyFilesTaskBuilder extends TaskBuilder {
46
46
  'Dockerfile',
47
47
  );
48
48
 
49
+ if (project.type === 'aws-microservice') {
50
+ dirs.push('infra');
51
+ }
52
+
49
53
  const extras = [
50
54
  project.configFileName,
51
55
  'package-lock.json',
@@ -32,10 +32,14 @@ export class FormatTaskBuilder extends TaskBuilder {
32
32
  throw new Error('Invalid project (arg #1)');
33
33
  }
34
34
 
35
- const dirs = ['src', 'test', 'infra', '.gulp'];
35
+ const dirs = ['src', 'test'];
36
36
  const extras = ['Gulpfile.js', 'README.md'];
37
37
  const extensions = ['ts', 'js', 'json', 'py', 'tsx', 'jsx'];
38
38
 
39
+ if (project.type === 'aws-microservice') {
40
+ dirs.push('infra');
41
+ }
42
+
39
43
  const paths = dirs
40
44
  .map((dir) => project.rootDir.getChild(dir))
41
45
  .map((dir) => extensions.map((ext) => dir.getAllFilesGlob(ext)))
@@ -35,10 +35,14 @@ export class LintFixTaskBuilder extends TaskBuilder {
35
35
  throw new Error('Invalid project (arg #1)');
36
36
  }
37
37
 
38
- const dirs = ['src', 'test', 'infra', '.gulp'];
38
+ const dirs = ['src', 'test'];
39
39
  const extras = ['Gulpfile.js'];
40
40
  const extensions = ['ts', 'js', 'tsx', 'jsx'];
41
41
 
42
+ if (project.type === 'aws-microservice') {
43
+ dirs.push('infra');
44
+ }
45
+
42
46
  const paths = dirs
43
47
  .map((dir) => project.rootDir.getChild(dir))
44
48
  .map((dir) => extensions.map((ext) => dir.getAllFilesGlob(ext)))
@@ -31,10 +31,14 @@ export class LintTaskBuilder extends TaskBuilder {
31
31
  throw new Error('Invalid project (arg #1)');
32
32
  }
33
33
 
34
- const dirs = ['src', 'test', 'infra', '.gulp'];
34
+ const dirs = ['src', 'test'];
35
35
  const extras = ['Gulpfile.js'];
36
36
  const extensions = ['ts', 'js', 'tsx', 'jsx'];
37
37
 
38
+ if (project.type === 'aws-microservice') {
39
+ dirs.push('infra');
40
+ }
41
+
38
42
  const paths = dirs
39
43
  .map((dir) => project.rootDir.getChild(dir))
40
44
  .map((dir) => extensions.map((ext) => dir.getAllFilesGlob(ext)))
@@ -12,12 +12,21 @@ import { Project } from '../project.js';
12
12
  export class NotSupportedTaskBuilder extends TaskBuilder {
13
13
  /**
14
14
  * Creates a new task builder.
15
+ *
16
+ * @param {String} [message] An optional message to display when the task is
17
+ * run.
15
18
  */
16
- constructor() {
19
+ constructor(message) {
17
20
  super(
18
21
  'not-supported',
19
22
  `Task that does nothing - used to indicate that a task is not supported for a project type.`,
20
23
  );
24
+
25
+ if (typeof message !== 'string' || message.length <= 0) {
26
+ message = 'Task not defined for project';
27
+ }
28
+
29
+ this._message = message;
21
30
  }
22
31
 
23
32
  /**
@@ -33,7 +42,7 @@ export class NotSupportedTaskBuilder extends TaskBuilder {
33
42
  if (!(project instanceof Project)) {
34
43
  throw new Error('Invalid project (arg #1)');
35
44
  }
36
- return () => _fancyLog.warn('Task not defined for project');
45
+ return async () => _fancyLog.warn(this._message);
37
46
  }
38
47
 
39
48
  /**
@@ -89,13 +89,17 @@ export class PackageAwsTaskBuilder extends TaskBuilder {
89
89
  if (!(project instanceof Project)) {
90
90
  throw new Error('Invalid project (arg #1)');
91
91
  }
92
- const dirs = ['src', 'test', 'infra'];
92
+ const dirs = ['src', 'test'];
93
93
  const exts = ['md', 'html', 'json', 'js', 'jsx', 'ts', 'tsx'];
94
94
  const rootDir =
95
95
  project.language === 'ts'
96
96
  ? project.rootDir.getChild('working')
97
97
  : project.rootDir;
98
98
 
99
+ if (project.type === 'aws-microservice') {
100
+ dirs.push('infra');
101
+ }
102
+
99
103
  return dirs
100
104
  .map((dir) =>
101
105
  exts.map((ext) => rootDir.getChild(dir).getAllFilesGlob(ext)),
@@ -116,13 +116,17 @@ export class PackageContainerTaskBuilder extends TaskBuilder {
116
116
  if (!(project instanceof Project)) {
117
117
  throw new Error('Invalid project (arg #1)');
118
118
  }
119
- const dirs = ['src', 'test', 'infra'];
119
+ const dirs = ['src', 'test'];
120
120
  const exts = ['md', 'html', 'json', 'js', 'jsx', 'ts', 'tsx'];
121
121
  const rootDir =
122
122
  project.language === 'ts'
123
123
  ? project.rootDir.getChild('working')
124
124
  : project.rootDir;
125
125
 
126
+ if (project.type === 'aws-microservice') {
127
+ dirs.push('infra');
128
+ }
129
+
126
130
  return dirs
127
131
  .map((dir) =>
128
132
  exts.map((ext) => rootDir.getChild(dir).getAllFilesGlob(ext)),
@@ -69,13 +69,17 @@ export class PackageNpmTaskBuilder extends TaskBuilder {
69
69
  if (!(project instanceof Project)) {
70
70
  throw new Error('Invalid project (arg #1)');
71
71
  }
72
- const dirs = ['src', 'test', 'infra'];
72
+ const dirs = ['src', 'test'];
73
73
  const exts = ['md', 'html', 'json', 'js', 'jsx', 'ts', 'tsx'];
74
74
  const rootDir =
75
75
  project.language === 'ts'
76
76
  ? project.rootDir.getChild('working')
77
77
  : project.rootDir;
78
78
 
79
+ if (project.type === 'aws-microservice') {
80
+ dirs.push('infra');
81
+ }
82
+
79
83
  return dirs
80
84
  .map((dir) =>
81
85
  exts.map((ext) => rootDir.getChild(dir).getAllFilesGlob(ext)),
@@ -30,7 +30,11 @@ export class PublishAwsTaskBuilder extends TaskBuilder {
30
30
  if (typeof requireApproval !== 'boolean') {
31
31
  throw new Error('Invalid requireApproval (arg #3)');
32
32
  }
33
- super('publish-aws', `Publish a CDK project to AWS`);
33
+
34
+ super(
35
+ `publish-aws-${target}`,
36
+ `Publish a CDK project to AWS: [${target}]`,
37
+ );
34
38
 
35
39
  this._target = target;
36
40
  this._environment = environment;
@@ -59,7 +59,24 @@ export class PublishTaskBuilder extends TaskBuilder {
59
59
  }
60
60
  // Type aws-microservice
61
61
  else if (type === 'aws-microservice') {
62
- return [new PublishAwsTaskBuilder()];
62
+ const stacks = project.getCdkTargets();
63
+ const defaultStack = stacks.find((target) => target === 'default');
64
+
65
+ if (defaultStack) {
66
+ return [
67
+ new PublishAwsTaskBuilder(
68
+ defaultStack,
69
+ process.env.INFRA_ENV,
70
+ process.env.INFRA_NO_PROMPT === 'true',
71
+ ),
72
+ ];
73
+ } else {
74
+ return [
75
+ new NotSupportedTaskBuilder(
76
+ 'No default stack defined for project. Please use an explicitly named publish task.',
77
+ ),
78
+ ];
79
+ }
63
80
  }
64
81
  // Type container
65
82
  else if (type === 'container') {
@@ -69,13 +69,17 @@ export class TestTaskBuilder extends TaskBuilder {
69
69
  if (!(project instanceof Project)) {
70
70
  throw new Error('Invalid project (arg #1)');
71
71
  }
72
- const dirs = ['src', 'test', 'infra'];
72
+ const dirs = ['src', 'test'];
73
73
  const exts = ['md', 'html', 'json', 'js', 'jsx', 'ts', 'tsx'];
74
74
  const rootDir =
75
75
  project.language === 'ts'
76
76
  ? project.rootDir.getChild('working')
77
77
  : project.rootDir;
78
78
 
79
+ if (project.type === 'aws-microservice') {
80
+ dirs.push('infra');
81
+ }
82
+
79
83
  return dirs
80
84
  .map((dir) =>
81
85
  exts.map((ext) => rootDir.getChild(dir).getAllFilesGlob(ext)),
@@ -49,13 +49,17 @@ export class TestUiTaskBuilder extends TaskBuilder {
49
49
  if (!(project instanceof Project)) {
50
50
  throw new Error('Invalid project (arg #1)');
51
51
  }
52
- const dirs = ['src', 'test', 'infra'];
52
+ const dirs = ['src', 'test'];
53
53
  const exts = ['md', 'html', 'json', 'js', 'jsx', 'ts', 'tsx'];
54
54
  const rootDir =
55
55
  project.language === 'ts'
56
56
  ? project.rootDir.getChild('working')
57
57
  : project.rootDir;
58
58
 
59
+ if (project.type === 'aws-microservice') {
60
+ dirs.push('infra');
61
+ }
62
+
59
63
  return dirs
60
64
  .map((dir) =>
61
65
  exts.map((ext) => rootDir.getChild(dir).getAllFilesGlob(ext)),
@@ -9,6 +9,7 @@ import { PackageTaskBuilder } from '../task-builders/package-task-builder.js';
9
9
  import { PublishTaskBuilder } from '../task-builders/publish-task-builder.js';
10
10
  import { DocsTaskBuilder } from '../task-builders/docs-task-builder.js';
11
11
  import { TestTaskBuilder } from '../task-builders/test-task-builder.js';
12
+ import { PublishAwsTaskBuilder } from '../task-builders/publish-aws-task-builder.js';
12
13
 
13
14
  /**
14
15
  * Represents a factory that generates a set of build tasks for a given project
@@ -36,6 +37,18 @@ export class AwsMicroserviceTaskFactory extends TaskFactory {
36
37
  return [];
37
38
  }
38
39
 
40
+ const publishTasks = this._project
41
+ .getCdkTargets()
42
+ .filter((stack) => stack !== 'default')
43
+ .map(
44
+ (stack) =>
45
+ new PublishAwsTaskBuilder(
46
+ stack,
47
+ process.env.INFRA_ENV,
48
+ process.env.INFRA_NO_PROMPT === 'true',
49
+ ),
50
+ );
51
+
39
52
  return [
40
53
  new CleanTaskBuilder(),
41
54
  new FormatTaskBuilder(),
@@ -47,7 +60,7 @@ export class AwsMicroserviceTaskFactory extends TaskFactory {
47
60
  new DocsTaskBuilder(this._project),
48
61
  new BuildTaskBuilder(this._project),
49
62
  new PackageTaskBuilder(this._project),
50
- new PublishTaskBuilder(this._project),
51
- ];
63
+ new PublishTaskBuilder(),
64
+ ].concat(publishTasks);
52
65
  }
53
66
  }