@localctl/cli 0.4.1 โ 0.4.2
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/README.md +47 -17
- package/package.json +1 -1
- package/src/lib/hostsFile.js +21 -2
package/README.md
CHANGED
|
@@ -75,17 +75,19 @@ JSON file per app.
|
|
|
75
75
|
|---|---|
|
|
76
76
|
| **macOS** or **Windows** | Windows commands run in PowerShell. |
|
|
77
77
|
| **Node.js 18+** | Needed to install the CLI from npm. |
|
|
78
|
-
| **Container engine** | [Podman Desktop](https://podman-desktop.io/), running. See [supported container engines](#supported-container-engines). |
|
|
78
|
+
| **Container engine** | [Podman Desktop](https://podman-desktop.io/) (or Docker Desktop / Rancher Desktop), running. See [supported container engines](#supported-container-engines). |
|
|
79
79
|
| **Homebrew** or **winget** | Used once by `localctl setup` to install missing tools. |
|
|
80
80
|
|
|
81
81
|
`localctl setup` installs `k3d`, `kubectl`, `tilt`, `mkcert` and `helm` for you if they're missing.
|
|
82
|
+
On Windows, Tilt isn't on winget, so it's downloaded from its GitHub release into
|
|
83
|
+
`~.localctl ools` and added to your user PATH.
|
|
82
84
|
|
|
83
85
|
### Supported container engines
|
|
84
86
|
|
|
85
87
|
| Engine | Status |
|
|
86
88
|
|---|---|
|
|
87
89
|
| [Podman Desktop](https://podman-desktop.io/) | โ
Tested |
|
|
88
|
-
| [Docker Desktop](https://www.docker.com/products/docker-desktop/) | ๐งช Experimental โ
|
|
90
|
+
| [Docker Desktop](https://www.docker.com/products/docker-desktop/) | ๐งช Experimental โ setup and app deploy verified on Windows |
|
|
89
91
|
| [Rancher Desktop](https://rancherdesktop.io/) | ๐งช Experimental โ not yet tested |
|
|
90
92
|
|
|
91
93
|
Experimental engines are detected and should work, since k3d only needs a Docker-compatible API,
|
|
@@ -106,7 +108,9 @@ the local image registry, trusts the `*.local.test` certificate, and updates you
|
|
|
106
108
|
is idempotent: run it again any time to repair your environment.
|
|
107
109
|
|
|
108
110
|
You'll see up to two one-time prompts during setup: **mkcert** asking to trust its local
|
|
109
|
-
certificate authority, and **
|
|
111
|
+
certificate authority, and **admin rights** to write the `*.local.test` hosts entries (your
|
|
112
|
+
`sudo` password on macOS, a UAC prompt on Windows). Approve both: without the hosts entries, apps
|
|
113
|
+
run but their addresses don't resolve.
|
|
110
114
|
|
|
111
115
|
**Pre-releases** are published under the `beta` tag: `npm install -g @localctl/cli@beta`.
|
|
112
116
|
|
|
@@ -120,7 +124,8 @@ Update available: 0.2.0 -> 0.3.0
|
|
|
120
124
|
Run npm install -g @localctl/cli to update.
|
|
121
125
|
```
|
|
122
126
|
|
|
123
|
-
Update with `npm install -g @localctl/cli`.
|
|
127
|
+
Update with `npm install -g @localctl/cli`. On a pre-release you're also told about newer
|
|
128
|
+
versions on your own channel (e.g. `beta`). The check never slows a command down, is skipped in
|
|
124
129
|
CI, and can be turned off with `LOCALCTL_NO_UPDATE_CHECK=1`.
|
|
125
130
|
|
|
126
131
|
<details>
|
|
@@ -204,6 +209,16 @@ localctl app down
|
|
|
204
209
|
|
|
205
210
|
This removes only that app. The shared cluster keeps running for everything else.
|
|
206
211
|
|
|
212
|
+
<details>
|
|
213
|
+
<summary><b>App is ready but <code>https://<app>.local.test</code> doesn't open?</b></summary>
|
|
214
|
+
|
|
215
|
+
If `localctl app status` shows `1/1` but the browser can't reach the address, the hosts file
|
|
216
|
+
entry is missing: the `sudo` or UAC prompt was declined or missed. Run `localctl hosts sync` and
|
|
217
|
+
approve the prompt. More cases, with cause and fix:
|
|
218
|
+
[**Troubleshooting**](https://psilvmoreira.github.io/localctl/troubleshooting/).
|
|
219
|
+
|
|
220
|
+
</details>
|
|
221
|
+
|
|
207
222
|
> **Tip:** no app of your own yet? Clone the repo and try a ready-made example:
|
|
208
223
|
> [`node-app`](https://github.com/psilvmoreira/localctl/tree/master/examples/node-app) (Node.js + Postgres),
|
|
209
224
|
> [`python-app`](https://github.com/psilvmoreira/localctl/tree/master/examples/python-app) (Python + Redis), or
|
|
@@ -211,7 +226,8 @@ This removes only that app. The shared cluster keeps running for everything else
|
|
|
211
226
|
|
|
212
227
|
## Commands
|
|
213
228
|
|
|
214
|
-
Run `localctl <command> --help` for every option
|
|
229
|
+
Run `localctl <command> --help` for every option, or see the full
|
|
230
|
+
[**CLI reference**](https://psilvmoreira.github.io/localctl/cli-reference/).
|
|
215
231
|
|
|
216
232
|
<details open>
|
|
217
233
|
<summary><b>Machine setup</b></summary>
|
|
@@ -220,7 +236,7 @@ Run `localctl <command> --help` for every option.
|
|
|
220
236
|
|---|---|
|
|
221
237
|
| `localctl setup` | Install or repair the infrastructure: container engine, cluster, TLS, hosts. Idempotent. |
|
|
222
238
|
| `localctl doctor` | Health check of the active project's environment. |
|
|
223
|
-
| `localctl hosts sync` / `list` |
|
|
239
|
+
| `localctl hosts sync` / `list` | Write or list the `*.local.test` entries in your hosts file. Asks for admin rights when needed. |
|
|
224
240
|
| `localctl uninstall [-y]` | Remove every cluster, registry, hosts entry, certificate and state file `localctl` created. |
|
|
225
241
|
|
|
226
242
|
</details>
|
|
@@ -235,7 +251,7 @@ Run `localctl <command> --help` for every option.
|
|
|
235
251
|
| `localctl app down` | Stop the dev loop and remove the app. Keeps its data. |
|
|
236
252
|
| `localctl app reload [-a <name>]` | Force a rebuild and redeploy without waiting for a file change. |
|
|
237
253
|
| `localctl app status [-a <name>] [-A]` | One app's detail inside its repository, or a table of every app. |
|
|
238
|
-
| `localctl app logs
|
|
254
|
+
| `localctl app logs [name] [-f]` | Show or follow an app's logs. Inside its repository the name is optional. |
|
|
239
255
|
| `localctl app exec [cmd...]` | Open a shell (default `sh`) in the app's pod. |
|
|
240
256
|
| `localctl app prune [-y]` | Delete leftover data (volumes, secrets) of apps already taken down. |
|
|
241
257
|
| `localctl app secrets set <KEY> [value]` | Store a secret as a Kubernetes Secret, never in `config.json`. |
|
|
@@ -324,6 +340,7 @@ The full documentation lives at **[psilvmoreira.github.io/localctl](https://psil
|
|
|
324
340
|
| [Adding tools](https://psilvmoreira.github.io/localctl/adding-tools/) | Write your own per-app or cluster-wide addon |
|
|
325
341
|
| [Troubleshooting](https://psilvmoreira.github.io/localctl/troubleshooting/) | Known issues, with cause and fix |
|
|
326
342
|
| [Uninstalling](https://psilvmoreira.github.io/localctl/uninstalling/) | Full teardown reference |
|
|
343
|
+
| [Contributing](https://psilvmoreira.github.io/localctl/contributing/) | Local setup, tests, pull requests, dependency policy, docs site |
|
|
327
344
|
| [Releasing](https://psilvmoreira.github.io/localctl/releasing/) | How versions are cut and published |
|
|
328
345
|
|
|
329
346
|
## Releases and versioning
|
|
@@ -334,16 +351,21 @@ The full documentation lives at **[psilvmoreira.github.io/localctl](https://psil
|
|
|
334
351
|
with notes and the package tarball.
|
|
335
352
|
- Versions follow [Semantic Versioning](https://semver.org). Before `1.0.0`, minor versions may
|
|
336
353
|
contain breaking changes.
|
|
337
|
-
-
|
|
354
|
+
- Every pull request shows a **release preview**: the version that merging it would publish,
|
|
355
|
+
including any unreleased commits already on `master`.
|
|
356
|
+
- npm releases are published from GitHub Actions through
|
|
357
|
+
[trusted publishing](https://docs.npmjs.com/trusted-publishers) (no npm tokens) with
|
|
338
358
|
[provenance](https://docs.npmjs.com/generating-provenance-statements). The npm package page links
|
|
339
359
|
each version to the exact commit and workflow run that built it.
|
|
360
|
+
- Dependencies and GitHub Actions are kept up to date by Dependabot, with every action pinned to a
|
|
361
|
+
commit SHA.
|
|
340
362
|
|
|
341
363
|
## Contributing
|
|
342
364
|
|
|
343
365
|
Issues and pull requests are welcome. The full guide (constraints, dependency policy, working on
|
|
344
366
|
the docs site) is in [**Contributing**](https://psilvmoreira.github.io/localctl/contributing/).
|
|
345
367
|
|
|
346
|
-
1. Fork the repository and create a branch
|
|
368
|
+
1. Fork the repository and create a branch from an up-to-date `master`.
|
|
347
369
|
2. Make your change and run the tests:
|
|
348
370
|
```sh
|
|
349
371
|
cd cli
|
|
@@ -352,15 +374,19 @@ the docs site) is in [**Contributing**](https://psilvmoreira.github.io/localctl/
|
|
|
352
374
|
npm run test:pack # the published package installs and runs
|
|
353
375
|
```
|
|
354
376
|
3. Open a pull request with a [Conventional Commits](https://www.conventionalcommits.org/) title.
|
|
355
|
-
|
|
377
|
+
PRs are squash-merged, so the title decides the next version. GitHub pre-fills it from the
|
|
378
|
+
branch name, which fails the title check: edit it.
|
|
356
379
|
|
|
357
380
|
| Title | Release |
|
|
358
381
|
|---|---|
|
|
359
|
-
| `fix: ...` | Patch (`0.
|
|
360
|
-
| `feat: ...` | Minor (`0.
|
|
361
|
-
| `feat!: ...` | Major (`0.
|
|
382
|
+
| `fix: ...`, `perf: ...` | Patch (`0.4.0` โ `0.4.1`) |
|
|
383
|
+
| `feat: ...` | Minor (`0.4.1` โ `0.5.0`) |
|
|
384
|
+
| `feat!: ...` | Major (`0.5.0` โ `1.0.0`) |
|
|
362
385
|
| `docs:` `chore:` `ci:` `refactor:` `test:` | No release |
|
|
363
386
|
|
|
387
|
+
4. Check the **release preview** on the `pr-title` check and wait for every check to pass
|
|
388
|
+
(title, tests on Linux/macOS/Windows ร Node 18/22, docs build, non-empty diff).
|
|
389
|
+
|
|
364
390
|
<details>
|
|
365
391
|
<summary><b>Repository layout</b></summary>
|
|
366
392
|
|
|
@@ -376,8 +402,10 @@ localctl/
|
|
|
376
402
|
โโโ cluster/manifests/ cluster-level manifests (TLS store, addon namespace)
|
|
377
403
|
โโโ schema/ JSON Schema for .local/config.json
|
|
378
404
|
โโโ examples/ ready-to-run sample apps
|
|
379
|
-
โโโ docs/ documentation
|
|
380
|
-
|
|
405
|
+
โโโ docs/ documentation pages (MkDocs Material, deployed to GitHub Pages)
|
|
406
|
+
โโโ overrides/ docs site template overrides (landing page)
|
|
407
|
+
โโโ bin/ bootstrap and uninstall scripts for source installs
|
|
408
|
+
โโโ .github/ CI, release and docs workflows, Dependabot config
|
|
381
409
|
```
|
|
382
410
|
|
|
383
411
|
</details>
|
|
@@ -390,8 +418,10 @@ npm uninstall -g @localctl/cli # the CLI itself
|
|
|
390
418
|
```
|
|
391
419
|
|
|
392
420
|
`localctl uninstall` asks for confirmation (skip with `-y`) and is safe to re-run. It leaves the
|
|
393
|
-
shared tools (`k3d`, `kubectl`, `tilt`, `mkcert`, `node`) and mkcert's root CA installed,
|
|
394
|
-
other projects may use them. It prints the exact commands to remove them
|
|
421
|
+
shared tools (`k3d`, `kubectl`, `tilt`, `mkcert`, `helm`, `node`) and mkcert's root CA installed,
|
|
422
|
+
since other projects may use them. It prints the exact commands to remove them for your OS
|
|
423
|
+
(`brew uninstall ...` on macOS; `winget uninstall ...` plus the `~.localctl ools` folder for
|
|
424
|
+
Tilt on Windows). Installed from
|
|
395
425
|
source with the bootstrap script? Use `./bin/uninstall.sh` or `./bin/uninstall.ps1` instead.
|
|
396
426
|
Details: [**Uninstalling**](https://psilvmoreira.github.io/localctl/uninstalling/).
|
|
397
427
|
|
package/package.json
CHANGED
package/src/lib/hostsFile.js
CHANGED
|
@@ -24,6 +24,20 @@ function listApps() {
|
|
|
24
24
|
return Object.keys(registry);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
// The Windows counterpart of `sudo cp`: copies src over the hosts file from an elevated
|
|
28
|
+
// PowerShell, which raises a UAC prompt. Returns false if the prompt is declined or the copy
|
|
29
|
+
// fails. The inner command goes through -EncodedCommand so paths need no nested quoting.
|
|
30
|
+
function copyElevatedWindows(src) {
|
|
31
|
+
const quote = (s) => `'${s.replace(/'/g, "''")}'`;
|
|
32
|
+
const inner = `Copy-Item -LiteralPath ${quote(src)} -Destination ${quote(HOSTS_PATH)} -Force`;
|
|
33
|
+
const encoded = Buffer.from(inner, 'utf16le').toString('base64');
|
|
34
|
+
const res = spawnSync('powershell', [
|
|
35
|
+
'-NoProfile', '-NonInteractive', '-Command',
|
|
36
|
+
`Start-Process powershell -Verb RunAs -Wait -WindowStyle Hidden -ArgumentList '-NoProfile','-NonInteractive','-EncodedCommand','${encoded}'`,
|
|
37
|
+
], { stdio: 'ignore' });
|
|
38
|
+
return res.status === 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
27
41
|
function writeHosts(next, current) {
|
|
28
42
|
if (next === current) {
|
|
29
43
|
logger.info('Hosts file already up to date.');
|
|
@@ -38,8 +52,13 @@ function writeHosts(next, current) {
|
|
|
38
52
|
const tmp = path.join(os.tmpdir(), 'localctl-hosts-new');
|
|
39
53
|
fs.writeFileSync(tmp, next);
|
|
40
54
|
if (process.platform === 'win32') {
|
|
41
|
-
logger.warn('Need Administrator rights to update the hosts file.
|
|
42
|
-
|
|
55
|
+
logger.warn('Need Administrator rights to update the hosts file. Approve the Windows prompt to continue.');
|
|
56
|
+
if (copyElevatedWindows(tmp) && fs.readFileSync(HOSTS_PATH, 'utf8') === next) {
|
|
57
|
+
logger.success(`Updated ${HOSTS_PATH}`);
|
|
58
|
+
} else {
|
|
59
|
+
logger.warn('Hosts file not updated, so *.local.test addresses won\'t resolve. Run in an elevated PowerShell:');
|
|
60
|
+
console.log(` Copy-Item "${tmp}" "${HOSTS_PATH}" -Force`);
|
|
61
|
+
}
|
|
43
62
|
} else {
|
|
44
63
|
logger.warn('Need sudo to update the hosts file.');
|
|
45
64
|
const res = spawnSync('sudo', ['cp', tmp, HOSTS_PATH], { stdio: 'inherit' });
|