Skip to content

Commit 3c2a0a8

Browse files
authored
[FEATURE] Prefer local over global CLI version (#59)
When running the global "ui5" command while a local @ui5/cli version is installed for the current project, the local one should be preferred. In this case an information will be logged to the console. This can be disabled by setting an environment variable: `UI5_CLI_NO_LOCAL=true` `ui5 --version` now also displays the CLI location for better troubleshooting. Fixes: #58
1 parent b268ce7 commit 3c2a0a8

File tree

5 files changed

+130
-21
lines changed

5 files changed

+130
-21
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,28 @@ Options:
139139
--loglevel Set the logging level (error|warn|info|verbose|silly). [string] [default: "info"]
140140
```
141141

142+
### Local vs. Global Installation
143+
In general a global installation of the UI5 CLI (`npm install --global @ui5/cli`) is recommended.
144+
145+
However, it makes sense to add the UI5 CLI as a [devDependency](https://docs.npmjs.com/files/package.json#devdependencies) (`npm install --save-dev @ui5/cli`) for a project that is using `ui5`-commands in its build or test scripts or otherwise depends on the UI5 CLI for development workflows (like Continuous Integration).
146+
147+
In case you have both, a local installation in one of your projects as well as a global installation, the UI5 CLI will always try to invoke the local installation. This is in part because [npm scripts](https://docs.npmjs.com/misc/scripts) defined in your `package.json` will also always invoke the local installation.
148+
149+
This behavior can be disabled by setting the environment variable `UI5_CLI_NO_LOCAL`.
150+
151+
**Example**
152+
You have a project located at `/my-application`. The project has a devDependency to `@ui5/cli` and defines a start-script `"ui5 serve"`.
153+
154+
Current Working Directory | Command | Uses globally installed UI5 CLI | Uses locally installed UI5 CLI
155+
--- | --- | :---: | :---:
156+
`/``ui5 --version` | ✔️ |
157+
`/my-application``ui5 --version` | | ✔️
158+
`/my-application``ui5 serve` | | ✔️
159+
`/my-application``npm start` | | ✔️
160+
`/my-application``UI5_CLI_NO_LOCAL=X ui5 serve` | ✔️ |
161+
`/my-application``UI5_CLI_NO_LOCAL=X npm start` | | ✔️
162+
163+
142164
## Contributing
143165
Please check our [Contribution Guidelines](https://github.com/SAP/ui5-tooling/blob/master/CONTRIBUTING.md).
144166

bin/ui5.js

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,50 @@ if (pkg.engines && pkg.engines.node && !semver.satisfies(nodeVersion, pkg.engine
1616
process.exit(1);
1717
}
1818

19-
const updateNotifier = require("update-notifier");
20-
const cli = require("yargs");
19+
// Timeout is required to log info when importing from local installation
20+
setTimeout(() => {
21+
if (!process.env.UI5_CLI_NO_LOCAL) {
22+
const importLocal = require("import-local");
23+
// Prefer a local installation of @ui5/cli.
24+
// This will invoke the local CLI, so no further action required
25+
if (importLocal(__filename)) {
26+
if (process.argv.includes("--verbose")) {
27+
console.info(`INFO: This project contains an individual ${pkg.name} installation which ` +
28+
"will be used over the global one.");
29+
console.info("See https://github.com/SAP/ui5-cli#local-vs-global-installation for details.");
30+
console.info("");
31+
} else {
32+
console.info(`INFO: Using local ${pkg.name} installation`);
33+
console.info("");
34+
}
35+
return;
36+
}
37+
}
2138

22-
updateNotifier({
23-
pkg,
24-
updateCheckInterval: 1000 * 60 * 60 * 24, // 1 day
25-
shouldNotifyInNpmScript: true
26-
}).notify();
39+
const updateNotifier = require("update-notifier");
40+
const cli = require("yargs");
2741

28-
// CLI modules
29-
cli.commandDir("../lib/cli/commands");
42+
updateNotifier({
43+
pkg,
44+
updateCheckInterval: 1000 * 60 * 60 * 24, // 1 day
45+
shouldNotifyInNpmScript: true
46+
}).notify();
3047

31-
// Format terminal output to full available width
32-
cli.wrap(cli.terminalWidth());
48+
// Explicitly set CLI version as the yargs default might
49+
// be wrong in case a local CLI installation is used
50+
// Also add CLI location
51+
cli.version(`${pkg.version} (from ${__filename})`);
3352

34-
// yargs registers a get method on the argv property.
35-
// The property needs to be accessed to initialize everything.
36-
cli.argv;
53+
// Explicitly set script name to prevent windows from displaying "ui5.js"
54+
cli.scriptName("ui5");
55+
56+
// CLI modules
57+
cli.commandDir("../lib/cli/commands");
58+
59+
// Format terminal output to full available width
60+
cli.wrap(cli.terminalWidth());
61+
62+
// yargs registers a get method on the argv property.
63+
// The property needs to be accessed to initialize everything.
64+
cli.argv;
65+
}, 0);

package-lock.json

Lines changed: 62 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
"@ui5/logger": "^0.2.0",
101101
"@ui5/project": "^0.2.0",
102102
"@ui5/server": "^0.2.1",
103+
"import-local": "^2.0.0",
103104
"js-yaml": "^3.10.0",
104105
"opn": "^5.1.0",
105106
"semver": "^5.5.0",

test/lib/cli/commands/base.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ const ui5 = (args, options = {}) => execa(ui5Cli, args, options);
77

88
test("ui5 --version", async (t) => {
99
const {stdout} = await ui5(["--version"]);
10-
t.is(stdout, pkg.version);
10+
t.is(stdout, `${pkg.version} (from ${ui5Cli})`);
1111
});
1212

1313
test("ui5 -v", async (t) => {
1414
const {stdout} = await ui5(["-v"]);
15-
t.is(stdout, pkg.version);
15+
t.is(stdout, `${pkg.version} (from ${ui5Cli})`);
1616
});

0 commit comments

Comments
 (0)