@loopback/build 2.0.16 → 2.1.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/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [2.1.0](https://github.com/strongloop/loopback-next/compare/@loopback/build@2.0.16...@loopback/build@2.1.0) (2019-11-25)
7
+
8
+
9
+ ### Features
10
+
11
+ * **build:** add an option to control resolution of CLI module from project dependencies ([0715a91](https://github.com/strongloop/loopback-next/commit/0715a91d0eef02c7e259cbd1b62a09010995c796))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [2.0.16](https://github.com/strongloop/loopback-next/compare/@loopback/build@2.0.15...@loopback/build@2.0.16) (2019-11-12)
7
18
 
8
19
  **Note:** Version bump only for package @loopback/build
package/bin/utils.js CHANGED
@@ -56,14 +56,62 @@ function getConfigFile(name, defaultName) {
56
56
 
57
57
  /**
58
58
  * Resolve the path of the cli command
59
- * @param {string} cli
59
+ * @param {string} cli CLI module path
60
+ * @param {object} options Options for module resolution
61
+ * - `resolveFromProjectFirst`: Try to resolve the CLI path from the package
62
+ * dependencies of the current project first instead of `@loopback/build`
60
63
  */
61
- function resolveCLI(cli) {
62
- const modulePath = './node_modules/' + cli;
64
+ function resolveCLI(cli, options = {resolveFromProjectFirst: true}) {
65
+ const {resolveFromProjectFirst = true} = options;
66
+ if (resolveFromProjectFirst === false) {
67
+ return require.resolve(cli);
68
+ }
63
69
  try {
64
- return require.resolve(path.join(getPackageDir(), modulePath));
70
+ const pkgDir = getPackageDir();
71
+ const resolved = resolveCLIFromProject(cli, pkgDir);
72
+ if (resolved != null) return resolved;
65
73
  } catch (e) {
66
- return require.resolve(cli);
74
+ // Ignore errors
75
+ }
76
+ return require.resolve(cli);
77
+ }
78
+
79
+ /**
80
+ * Parse the package name from the cli module path
81
+ * @param {string} cli CLI module path, such as `typescript/lib/tsc`
82
+ */
83
+ function getPackageName(cli) {
84
+ const paths = cli.split('/');
85
+ if (paths[0].startsWith('@')) {
86
+ // The package name is `@<org>/<pkg>`
87
+ return `${paths[0]}/${paths[1]}`;
88
+ } else {
89
+ // The package name is `<pkg>`
90
+ return paths[0];
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Resolve the cli from the current project
96
+ * @param {string} cli CLI module path, such as `typescript/lib/tsc`
97
+ * @param {string} projectRootDir The root directory for the project
98
+ */
99
+ function resolveCLIFromProject(cli, projectRootDir = getPackageDir()) {
100
+ const cliPkg = getPackageName(cli);
101
+ debug(`Trying to resolve CLI module '%s' from %s`, cliPkg, projectRootDir);
102
+ // Try to load `package.json` for the current project
103
+ const pkg = require(path.join(projectRootDir, 'package.json'));
104
+ if (
105
+ (pkg.devDependencies && pkg.devDependencies[cliPkg]) ||
106
+ (pkg.dependencies && pkg.dependencies[cliPkg])
107
+ ) {
108
+ // The cli package is found in the project dependencies
109
+ const modulePath = './node_modules/' + cli;
110
+ const cliModule = require.resolve(path.join(projectRootDir, modulePath));
111
+ debug(`Resolved CLI module '%s': %s`, cliPkg, cliModule);
112
+ return cliModule;
113
+ } else {
114
+ debug(`CLI module '%s' is not found in dependencies`, cliPkg);
67
115
  }
68
116
  }
69
117
 
@@ -77,7 +125,7 @@ function resolveCLI(cli) {
77
125
  * to true, the command itself will be returned without running it
78
126
  */
79
127
  function runCLI(cli, args, options) {
80
- cli = resolveCLI(cli);
128
+ cli = resolveCLI(cli, options && options.resolveFromProjectFirst);
81
129
  args = [cli].concat(args);
82
130
  debug('%s', args.join(' '));
83
131
  // Keep it backward compatible as dryRun
@@ -196,3 +244,5 @@ exports.runCLI = runCLI;
196
244
  exports.runShell = runShell;
197
245
  exports.isOptionSet = isOptionSet;
198
246
  exports.mochaConfiguredForProject = mochaConfiguredForProject;
247
+ exports.resolveCLIFromProject = resolveCLIFromProject;
248
+ exports.getPackageName = getPackageName;
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/strongloop/loopback-next.git",
7
7
  "directory": "packages/build"
8
8
  },
9
- "version": "2.0.16",
9
+ "version": "2.1.0",
10
10
  "engines": {
11
11
  "node": ">=8.9"
12
12
  },
@@ -15,17 +15,17 @@
15
15
  "copyright.owner": "IBM Corp.",
16
16
  "license": "MIT",
17
17
  "dependencies": {
18
- "@loopback/eslint-config": "^4.1.4",
18
+ "@loopback/eslint-config": "^4.1.5",
19
19
  "@types/mocha": "^5.2.7",
20
20
  "@types/node": "^10.17.5",
21
- "@typescript-eslint/eslint-plugin": "^2.7.0",
22
- "@typescript-eslint/parser": "^2.7.0",
21
+ "@typescript-eslint/eslint-plugin": "^2.9.0",
22
+ "@typescript-eslint/parser": "^2.9.0",
23
23
  "cross-spawn": "^7.0.1",
24
24
  "debug": "^4.1.1",
25
- "eslint": "^6.6.0",
26
- "eslint-config-prettier": "^6.5.0",
25
+ "eslint": "^6.7.1",
26
+ "eslint-config-prettier": "^6.7.0",
27
27
  "eslint-plugin-eslint-plugin": "^2.1.0",
28
- "eslint-plugin-mocha": "^6.2.1",
28
+ "eslint-plugin-mocha": "^6.2.2",
29
29
  "fs-extra": "^8.1.0",
30
30
  "glob": "^7.1.6",
31
31
  "mocha": "^6.2.2",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "scripts": {
47
47
  "test": "npm run mocha",
48
- "mocha": "node bin/run-mocha --timeout 30000 \"test/integration/*.js\""
48
+ "mocha": "node bin/run-mocha --timeout 30000 \"test/integration/*.js\" \"test/unit/*.js\""
49
49
  },
50
- "gitHead": "7f0ae6ec124c19357c3016cd11f9bc9c739dffcb"
50
+ "gitHead": "c111543a6139c5a2999930c593aabbbdf10a838e"
51
51
  }
@@ -5,6 +5,9 @@
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
7
7
  },
8
+ "dependencies": {
9
+ "typescript": "*"
10
+ },
8
11
  "author": "IBM Corp.",
9
12
  "license": "MIT"
10
13
  }
@@ -8,6 +8,7 @@
8
8
  const assert = require('assert');
9
9
  const path = require('path');
10
10
  const fs = require('fs-extra');
11
+ const utils = require('../../bin/utils');
11
12
 
12
13
  describe('build', function() {
13
14
  // eslint-disable-next-line no-invalid-this
@@ -194,6 +195,24 @@ describe('build', function() {
194
195
 
195
196
  after(() => delete process.env.LERNA_ROOT_PATH);
196
197
  });
198
+
199
+ describe('resolveCLIFromProject()', () => {
200
+ it('returns undefined if the CLI is not found in project deps', () => {
201
+ assert.equal(
202
+ utils.resolveCLIFromProject('mocha/bin/mocha', projectDir),
203
+ undefined,
204
+ );
205
+ });
206
+
207
+ it('throws error if the CLI cannot be resolved', () => {
208
+ try {
209
+ utils.resolveCLIFromProject('typescript/bin/tsc', projectDir);
210
+ assert.fail('typescript/bin/tsc should not be resolved');
211
+ } catch (err) {
212
+ assert(err.message.match(/Cannot find module/));
213
+ }
214
+ });
215
+ });
197
216
  });
198
217
 
199
218
  describe('mocha', function() {
@@ -0,0 +1,24 @@
1
+ // Copyright IBM Corp. 2018. All Rights Reserved.
2
+ // Node module: @loopback/build
3
+ // This file is licensed under the MIT License.
4
+ // License text available at https://opensource.org/licenses/MIT
5
+
6
+ 'use strict';
7
+
8
+ const assert = require('assert');
9
+ const utils = require('../../bin/utils');
10
+
11
+ describe('Build utils', () => {
12
+ describe('getPackageName()', () => {
13
+ it('supports simple packages', () => {
14
+ assert.equal(utils.getPackageName('typescript/bin/tsc'), 'typescript');
15
+ });
16
+
17
+ it('supports scoped packages', () => {
18
+ assert.equal(
19
+ utils.getPackageName('@loopback/cli/bin/cli-main'),
20
+ '@loopback/cli',
21
+ );
22
+ });
23
+ });
24
+ });