@ethlete/cli 2.1.0-next.4 → 2.1.0-next.5

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +29 -8
  3. package/package.json +1 -1
  4. package/src/index.js +4 -0
  5. package/src/index.js.map +1 -1
  6. package/src/lib/api/api-command.d.ts +1 -1
  7. package/src/lib/api/auth-hint.d.ts +9 -0
  8. package/src/lib/api/auth-hint.js +33 -0
  9. package/src/lib/api/auth-hint.js.map +1 -0
  10. package/src/lib/api/clone.d.ts +12 -0
  11. package/src/lib/api/clone.js +24 -0
  12. package/src/lib/api/clone.js.map +1 -0
  13. package/src/lib/api/definition.d.ts +5 -1
  14. package/src/lib/api/definition.js +4 -2
  15. package/src/lib/api/definition.js.map +1 -1
  16. package/src/lib/api/git.d.ts +21 -0
  17. package/src/lib/api/git.js +59 -0
  18. package/src/lib/api/git.js.map +1 -0
  19. package/src/lib/api/help.d.ts +3 -0
  20. package/src/lib/api/help.js +39 -0
  21. package/src/lib/api/help.js.map +1 -0
  22. package/src/lib/api/index.d.ts +5 -0
  23. package/src/lib/api/index.js +5 -0
  24. package/src/lib/api/index.js.map +1 -1
  25. package/src/lib/api/resolve-checkout.d.ts +35 -0
  26. package/src/lib/api/resolve-checkout.js +78 -0
  27. package/src/lib/api/resolve-checkout.js.map +1 -0
  28. package/src/lib/api/run.d.ts +1 -1
  29. package/src/lib/api/run.js +71 -41
  30. package/src/lib/api/run.js.map +1 -1
  31. package/src/lib/config/diagnose.d.ts +7 -0
  32. package/src/lib/config/diagnose.js +103 -0
  33. package/src/lib/config/diagnose.js.map +1 -0
  34. package/src/lib/config/index.d.ts +1 -0
  35. package/src/lib/config/index.js +1 -0
  36. package/src/lib/config/index.js.map +1 -1
  37. package/src/lib/config/local-config.d.ts +13 -0
  38. package/src/lib/config/local-config.js +13 -6
  39. package/src/lib/config/local-config.js.map +1 -1
  40. package/src/lib/doctor/doctor-command.d.ts +4 -0
  41. package/src/lib/doctor/doctor-command.js +65 -0
  42. package/src/lib/doctor/doctor-command.js.map +1 -0
  43. package/src/lib/doctor/index.d.ts +1 -0
  44. package/src/lib/doctor/index.js +5 -0
  45. package/src/lib/doctor/index.js.map +1 -0
  46. package/src/lib/index.d.ts +1 -0
  47. package/src/lib/index.js +1 -0
  48. package/src/lib/index.js.map +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @ethlete/cli
2
2
 
3
+ ## 2.1.0-next.5
4
+
5
+ ### Minor Changes
6
+
7
+ - [`612d735`](https://github.com/ethlete-io/ethdk/commit/612d73563e1689bbfcf948d26ebe7c59d2420781) Thanks [@TomTomB](https://github.com/TomTomB)! - `et api` now clones a missing API checkout from a `repoUrl` in `ethlete.apis.js`, making
8
+ `apiRepoPaths` optional. `runApiCommand` is async as a result.
9
+
10
+ - [#3072](https://github.com/ethlete-io/ethdk/pull/3072) [`4bbbb51`](https://github.com/ethlete-io/ethdk/commit/4bbbb5167989a1c3ef2ffeba09fcfd18ba953fba) Thanks [@github-actions](https://github.com/apps/github-actions)! - Add `et doctor` to check this machine's config, container engine and API checkouts, `et api
11
+ checkout` and `et api pull` (with `--force`) to move an API checkout to the branch it should be on,
12
+ and `et api --help`.
13
+
14
+ ### Patch Changes
15
+
16
+ - [#3072](https://github.com/ethlete-io/ethdk/pull/3072) [`0fd8ba3`](https://github.com/ethlete-io/ethdk/commit/0fd8ba3dd61cc78409c397c8180f0a675282642f) Thanks [@github-actions](https://github.com/apps/github-actions)! - `et doctor` now says when a directory has neither config file rather than reporting no problems.
17
+
3
18
  ## 2.1.0-next.4
4
19
 
5
20
  ### Minor Changes
package/README.md CHANGED
@@ -21,17 +21,36 @@ Turns pending changesets into a tagged, pushed release commit (version → tag
21
21
  Runs the API an app in this repo talks to, from a checkout on your own machine.
22
22
 
23
23
  ```bash
24
- yarn et api up hub # start the containers
25
- yarn et api down hub # stop them
26
- yarn et api logs hub # follow the API's log
27
- yarn et api shell hub # a shell in the API container
28
- yarn et api install hub # an entry from that API's own "exec" map
29
- yarn et api up hub --host # also print the address other devices can reach
24
+ yarn et api --help # the commands, the APIs and what each one accepts
25
+ yarn et api up hub # start the containers
26
+ yarn et api down hub # stop them
27
+ yarn et api logs hub # follow the API's log
28
+ yarn et api shell hub # a shell in the API container
29
+ yarn et api install hub # an entry from that API's own "exec" map
30
+ yarn et api up hub --host # also print the address other devices can reach
31
+ yarn et api checkout hub # switch the checkout to the branch apiRepoBranches names
32
+ yarn et api pull hub # fetch and fast-forward the checked-out branch
33
+ yarn et api pull hub --force # the same, discarding local commits and tracked changes
34
+ yarn et api clone hub # clone the API into .ethlete/hub
30
35
  ```
31
36
 
37
+ `checkout` and `pull` act on the checkout itself, so they work before `make setup` has run and need
38
+ no container engine. `pull` refuses to run on a checkout with uncommitted changes unless you pass
39
+ `--force`. `--force` resets the branch to its remote and throws away local commits and tracked
40
+ changes; it never touches untracked or ignored files, so a `vendor/` directory or a `.env` survives.
41
+
32
42
  The first container tool that answers is used, in this order: `docker compose`,
33
43
  `container compose`, `podman-compose`, `podman compose`.
34
44
 
45
+ ## `et doctor`
46
+
47
+ ```bash
48
+ yarn et doctor
49
+ ```
50
+
51
+ Checks `ethlete.config.local.json`, reports the container engine it would use, and resolves every
52
+ API declared in `ethlete.apis.js`. It exits non-zero when it finds a problem, so CI can run it.
53
+
35
54
  ### Declaring the APIs
36
55
 
37
56
  `ethlete.apis.js` at the repo root describes each API's compose setup. It is a module rather
@@ -64,8 +83,10 @@ Adding an API is an entry in this map. Nothing else changes.
64
83
 
65
84
  ### Where the checkouts live
66
85
 
67
- The paths differ per machine, so they live in a gitignored `ethlete.config.local.json` at the
68
- repo root. `@ethlete/agent-rules` reads the same file, so its skills and `et` agree on where a
86
+ Give an API a `repoUrl` and `et api` clones it into a gitignored `.ethlete/<name>` when you have no
87
+ checkout of your own, asking first (or use `--clone`). To point at a checkout you already have - which
88
+ you want whenever you work in the backend, since compose mounts it into the container - set
89
+ `apiRepoPaths` in a gitignored `ethlete.config.local.json` at the repo root. `@ethlete/agent-rules` reads the same file, so its skills and `et` agree on where a
69
90
  checkout is:
70
91
 
71
92
  ```json
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ethlete/cli",
3
- "version": "2.1.0-next.4",
3
+ "version": "2.1.0-next.5",
4
4
  "license": "MIT",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
package/src/index.js CHANGED
@@ -7,6 +7,8 @@ const USAGE = `et — Ethlete repo tooling
7
7
  et release Turn pending changesets into a tagged, pushed release commit
8
8
  et api <cmd> <api> Run an API from this repo's ethlete.apis.js locally
9
9
  (up, down, logs, shell, plus that API's own exec entries)
10
+ et doctor Check this machine's ethlete.config.local.json, container engine
11
+ and every API checkout
10
12
  `;
11
13
  const cli = (args) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
12
14
  switch (args[0]) {
@@ -17,6 +19,8 @@ const cli = (args) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
17
19
  return 0;
18
20
  case 'api':
19
21
  return (0, lib_1.apiCommand)({ root: process.cwd(), argv: args.slice(1) });
22
+ case 'doctor':
23
+ return (0, lib_1.doctorCommand)({ root: process.cwd() });
20
24
  default:
21
25
  console.log(USAGE);
22
26
  return args[0] === undefined || args[0] === '--help' || args[0] === '-h' ? 0 : 1;
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/cli/src/index.ts"],"names":[],"mappings":";;;AAAA,+BAA4C;AAE5C,MAAM,KAAK,GAAG;;;;;CAKb,CAAC;AAEF,MAAM,GAAG,GAAG,CAAO,IAAc,EAAmB,EAAE;IACpD,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAChB,KAAK,SAAS;YACZ,0FAA0F;YAC1F,wDAAwD;YACxD,MAAM,IAAA,aAAO,EAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YAEzC,OAAO,CAAC,CAAC;QAEX,KAAK,KAAK;YACR,OAAO,IAAA,gBAAU,EAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAElE;YACE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAEnB,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrF,CAAC;AACH,CAAC,CAAA,CAAC;AAEF,gDAAsB;AAEtB,oFAAoF;AACpF,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SACvB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QACb,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC1B,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QACxB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/cli/src/index.ts"],"names":[],"mappings":";;;AAAA,+BAA2D;AAE3D,MAAM,KAAK,GAAG;;;;;;;CAOb,CAAC;AAEF,MAAM,GAAG,GAAG,CAAO,IAAc,EAAmB,EAAE;IACpD,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAChB,KAAK,SAAS;YACZ,0FAA0F;YAC1F,wDAAwD;YACxD,MAAM,IAAA,aAAO,EAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YAEzC,OAAO,CAAC,CAAC;QAEX,KAAK,KAAK;YACR,OAAO,IAAA,gBAAU,EAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAElE,KAAK,QAAQ;YACX,OAAO,IAAA,mBAAa,EAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAEhD;YACE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAEnB,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrF,CAAC;AACH,CAAC,CAAA,CAAC;AAEF,gDAAsB;AAEtB,oFAAoF;AACpF,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SACvB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QACb,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC1B,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QACxB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,4 +1,4 @@
1
1
  export declare const apiCommand: ({ root, argv }: {
2
2
  root: string;
3
3
  argv: string[];
4
- }) => number;
4
+ }) => 1 | Promise<number>;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * A private dependency that will not download is the most common way these commands fail, and git
3
+ * and the package managers report it as a bare 403 or a public-key error. This says what to check.
4
+ */
5
+ export declare const printPrivateDependencyHint: (options: {
6
+ repoHost?: string;
7
+ }) => void;
8
+ /** The host of a git url, for naming it in the hint. Undefined when the url has no host. */
9
+ export declare const gitUrlHost: (repoUrl: string) => string | undefined;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.gitUrlHost = exports.printPrivateDependencyHint = void 0;
4
+ /**
5
+ * A private dependency that will not download is the most common way these commands fail, and git
6
+ * and the package managers report it as a bare 403 or a public-key error. This says what to check.
7
+ */
8
+ const printPrivateDependencyHint = (options) => {
9
+ var _a;
10
+ const host = (_a = options.repoHost) !== null && _a !== void 0 ? _a : 'your git host';
11
+ console.error(`\nThat command may have failed because a private dependency could not be downloaded.\n` +
12
+ `Three things are worth checking:\n\n` +
13
+ ` 1. A personal access token for ${host} with permission to DOWNLOAD code.\n` +
14
+ ` Read access is not enough for a clone, and the server reports the difference as 403.\n` +
15
+ ` 2. An SSH key this machine offers to ${host}, when the dependency is fetched over SSH.\n` +
16
+ ` 3. That the token is where the package manager looks for it, not only in your shell.\n` +
17
+ ` Composer, for example, reads ~/.composer/auth.json rather than the environment.`);
18
+ };
19
+ exports.printPrivateDependencyHint = printPrivateDependencyHint;
20
+ /** The host of a git url, for naming it in the hint. Undefined when the url has no host. */
21
+ const gitUrlHost = (repoUrl) => {
22
+ const scpLike = /^[^/]+@([^:]+):/.exec(repoUrl);
23
+ if (scpLike)
24
+ return scpLike[1];
25
+ try {
26
+ return new URL(repoUrl).hostname || undefined;
27
+ }
28
+ catch (_a) {
29
+ return undefined;
30
+ }
31
+ };
32
+ exports.gitUrlHost = gitUrlHost;
33
+ //# sourceMappingURL=auth-hint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-hint.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/auth-hint.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACI,MAAM,0BAA0B,GAAG,CAAC,OAA8B,EAAE,EAAE;;IAC3E,MAAM,IAAI,GAAG,MAAA,OAAO,CAAC,QAAQ,mCAAI,eAAe,CAAC;IAEjD,OAAO,CAAC,KAAK,CACX,wFAAwF;QACtF,sCAAsC;QACtC,oCAAoC,IAAI,sCAAsC;QAC9E,6FAA6F;QAC7F,0CAA0C,IAAI,8CAA8C;QAC5F,0FAA0F;QAC1F,sFAAsF,CACzF,CAAC;AACJ,CAAC,CAAC;AAZW,QAAA,0BAA0B,8BAYrC;AAEF,4FAA4F;AACrF,MAAM,UAAU,GAAG,CAAC,OAAe,EAAE,EAAE;IAC5C,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEhD,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;IAE/B,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,IAAI,SAAS,CAAC;IAChD,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC,CAAC;AAVW,QAAA,UAAU,cAUrB"}
@@ -0,0 +1,12 @@
1
+ export declare const DEFAULT_CHECKOUT_DIR = ".ethlete";
2
+ /** True when git would ignore the path, so a cloned checkout cannot be committed by accident. */
3
+ export declare const isGitIgnored: (root: string, path: string) => boolean;
4
+ export type CloneRequest = {
5
+ repoUrl: string;
6
+ /** Absolute path to clone into. */
7
+ into: string;
8
+ /** Branch to check out, from `apiRepoBranches`. */
9
+ branch?: string;
10
+ };
11
+ /** Clones an API repo into its managed directory. Git's own output and failures are passed through. */
12
+ export declare const cloneApiRepo: ({ repoUrl, into, branch }: CloneRequest) => number;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cloneApiRepo = exports.isGitIgnored = exports.DEFAULT_CHECKOUT_DIR = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const fs_1 = require("fs");
6
+ const path_1 = require("path");
7
+ const fs_2 = require("fs");
8
+ exports.DEFAULT_CHECKOUT_DIR = '.ethlete';
9
+ /** True when git would ignore the path, so a cloned checkout cannot be committed by accident. */
10
+ const isGitIgnored = (root, path) => (0, child_process_1.spawnSync)('git', ['check-ignore', '-q', path], { cwd: root }).status === 0;
11
+ exports.isGitIgnored = isGitIgnored;
12
+ /** Clones an API repo into its managed directory. Git's own output and failures are passed through. */
13
+ const cloneApiRepo = ({ repoUrl, into, branch }) => {
14
+ var _a;
15
+ if ((0, fs_1.existsSync)(into)) {
16
+ console.error(`${into} already exists.`);
17
+ return 1;
18
+ }
19
+ (0, fs_2.mkdirSync)((0, path_1.dirname)(into), { recursive: true });
20
+ const args = ['clone', ...(branch ? ['--branch', branch] : []), '--', repoUrl, into];
21
+ return (_a = (0, child_process_1.spawnSync)('git', args, { stdio: 'inherit' }).status) !== null && _a !== void 0 ? _a : 1;
22
+ };
23
+ exports.cloneApiRepo = cloneApiRepo;
24
+ //# sourceMappingURL=clone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clone.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/clone.ts"],"names":[],"mappings":";;;AAAA,iDAA0C;AAC1C,2BAAgC;AAChC,+BAA+B;AAC/B,2BAA+B;AAElB,QAAA,oBAAoB,GAAG,UAAU,CAAC;AAE/C,iGAAiG;AAC1F,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,IAAY,EAAE,EAAE,CACzD,IAAA,yBAAS,EAAC,KAAK,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AADhE,QAAA,YAAY,gBACoD;AAU7E,uGAAuG;AAChG,MAAM,YAAY,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAgB,EAAE,EAAE;;IACtE,IAAI,IAAA,eAAU,EAAC,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,kBAAkB,CAAC,CAAC;QAEzC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAA,cAAS,EAAC,IAAA,cAAO,EAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9C,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAErF,OAAO,MAAA,IAAA,yBAAS,EAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,mCAAI,CAAC,CAAC;AAClE,CAAC,CAAC;AAZW,QAAA,YAAY,gBAYvB"}
@@ -16,6 +16,8 @@ export type ApiDefinition = {
16
16
  network?: string;
17
17
  /** Example path shown in the error that asks the developer to configure this API's checkout. */
18
18
  examplePath?: string;
19
+ /** Where to clone this API from when the developer has no checkout of their own. */
20
+ repoUrl?: string;
19
21
  /** localStorage key the app reads to pick its API. Printed by `--host`. */
20
22
  envKey?: string;
21
23
  /** Extra environment for every compose call. An undefined value is dropped rather than passed as "undefined". */
@@ -24,5 +26,7 @@ export type ApiDefinition = {
24
26
  exec?: Record<string, string[]>;
25
27
  };
26
28
  export type ApiDefinitions = Record<string, ApiDefinition>;
27
- export declare const BUILT_IN_API_COMMANDS: readonly ["up", "down", "logs", "shell"];
29
+ export declare const BUILT_IN_API_COMMANDS: readonly ["up", "down", "logs", "shell", "clone", "checkout", "pull"];
30
+ /** These act on the checkout itself, so they run before `make setup` and need no container engine. */
31
+ export declare const GIT_API_COMMANDS: string[];
28
32
  export declare const apiCommandNames: (api: ApiDefinition) => string[];
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.apiCommandNames = exports.BUILT_IN_API_COMMANDS = void 0;
4
- exports.BUILT_IN_API_COMMANDS = ['up', 'down', 'logs', 'shell'];
3
+ exports.apiCommandNames = exports.GIT_API_COMMANDS = exports.BUILT_IN_API_COMMANDS = void 0;
4
+ exports.BUILT_IN_API_COMMANDS = ['up', 'down', 'logs', 'shell', 'clone', 'checkout', 'pull'];
5
+ /** These act on the checkout itself, so they run before `make setup` and need no container engine. */
6
+ exports.GIT_API_COMMANDS = ['clone', 'checkout', 'pull'];
5
7
  const apiCommandNames = (api) => { var _a; return [...exports.BUILT_IN_API_COMMANDS, ...Object.keys((_a = api.exec) !== null && _a !== void 0 ? _a : {})]; };
6
8
  exports.apiCommandNames = apiCommandNames;
7
9
  //# sourceMappingURL=definition.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"definition.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/definition.ts"],"names":[],"mappings":";;;AA4Ba,QAAA,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAEvE,MAAM,eAAe,GAAG,CAAC,GAAkB,EAAE,EAAE,WAAC,OAAA,CAAC,GAAG,6BAAqB,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAA,GAAG,CAAC,IAAI,mCAAI,EAAE,CAAC,CAAC,CAAA,EAAA,CAAC;AAArG,QAAA,eAAe,mBAAsF"}
1
+ {"version":3,"file":"definition.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/definition.ts"],"names":[],"mappings":";;;AA8Ba,QAAA,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,CAAU,CAAC;AAE3G,sGAAsG;AACzF,QAAA,gBAAgB,GAAa,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;AAEjE,MAAM,eAAe,GAAG,CAAC,GAAkB,EAAE,EAAE,WAAC,OAAA,CAAC,GAAG,6BAAqB,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAA,GAAG,CAAC,IAAI,mCAAI,EAAE,CAAC,CAAC,CAAA,EAAA,CAAC;AAArG,QAAA,eAAe,mBAAsF"}
@@ -0,0 +1,21 @@
1
+ export type GitResult = {
2
+ status: number;
3
+ stdout: string;
4
+ stderr: string;
5
+ };
6
+ export declare const currentBranch: (cwd: string) => string | undefined;
7
+ export declare const hasUncommittedChanges: (cwd: string) => boolean;
8
+ /** Switches the API checkout to the branch configured for it. Git's own refusal is passed through. */
9
+ export declare const checkoutApiBranch: (options: {
10
+ repoPath: string;
11
+ branch: string;
12
+ }) => number;
13
+ /**
14
+ * Fast-forwards the checked-out branch. `force` throws away local commits and uncommitted tracked
15
+ * changes on it; untracked files such as `vendor/` and `.env` are never touched.
16
+ */
17
+ export declare const pullApiBranch: (options: {
18
+ repoPath: string;
19
+ expectedBranch?: string;
20
+ force: boolean;
21
+ }) => number;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pullApiBranch = exports.checkoutApiBranch = exports.hasUncommittedChanges = exports.currentBranch = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const git = (cwd, args) => {
6
+ var _a, _b, _c;
7
+ const result = (0, child_process_1.spawnSync)('git', args, { cwd, encoding: 'utf8' });
8
+ return {
9
+ status: (_a = result.status) !== null && _a !== void 0 ? _a : 1,
10
+ stdout: ((_b = result.stdout) !== null && _b !== void 0 ? _b : '').trim(),
11
+ stderr: ((_c = result.stderr) !== null && _c !== void 0 ? _c : '').trim(),
12
+ };
13
+ };
14
+ const gitInherit = (cwd, args) => { var _a; return (_a = (0, child_process_1.spawnSync)('git', args, { cwd, stdio: 'inherit' }).status) !== null && _a !== void 0 ? _a : 1; };
15
+ const currentBranch = (cwd) => {
16
+ const result = git(cwd, ['rev-parse', '--abbrev-ref', 'HEAD']);
17
+ return result.status === 0 ? result.stdout : undefined;
18
+ };
19
+ exports.currentBranch = currentBranch;
20
+ const hasUncommittedChanges = (cwd) => git(cwd, ['status', '--porcelain']).stdout.length > 0;
21
+ exports.hasUncommittedChanges = hasUncommittedChanges;
22
+ /** Switches the API checkout to the branch configured for it. Git's own refusal is passed through. */
23
+ const checkoutApiBranch = (options) => {
24
+ const { repoPath, branch } = options;
25
+ if ((0, exports.currentBranch)(repoPath) === branch) {
26
+ console.log(`Already on ${branch}.`);
27
+ return 0;
28
+ }
29
+ return gitInherit(repoPath, ['checkout', branch]);
30
+ };
31
+ exports.checkoutApiBranch = checkoutApiBranch;
32
+ /**
33
+ * Fast-forwards the checked-out branch. `force` throws away local commits and uncommitted tracked
34
+ * changes on it; untracked files such as `vendor/` and `.env` are never touched.
35
+ */
36
+ const pullApiBranch = (options) => {
37
+ const { repoPath, expectedBranch, force } = options;
38
+ const branch = (0, exports.currentBranch)(repoPath);
39
+ if (!branch) {
40
+ console.error(`${repoPath} is not a git checkout.`);
41
+ return 1;
42
+ }
43
+ if (expectedBranch && branch !== expectedBranch) {
44
+ console.warn(`On ${branch}, but apiRepoBranches expects ${expectedBranch}. Pulling ${branch}.\n`);
45
+ }
46
+ if (!force && (0, exports.hasUncommittedChanges)(repoPath)) {
47
+ console.error(`${repoPath} has uncommitted changes. Commit or stash them, or pass --force to discard them.`);
48
+ return 1;
49
+ }
50
+ const fetched = gitInherit(repoPath, ['fetch', 'origin', branch]);
51
+ if (fetched !== 0)
52
+ return fetched;
53
+ if (!force)
54
+ return gitInherit(repoPath, ['merge', '--ff-only', `origin/${branch}`]);
55
+ console.log(`Discarding local commits and tracked changes on ${branch}.`);
56
+ return gitInherit(repoPath, ['reset', '--hard', `origin/${branch}`]);
57
+ };
58
+ exports.pullApiBranch = pullApiBranch;
59
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { ApiDefinitions } from './definition';
2
+ /** The help text for `et api`, listing the built-in commands and what each API adds to them. */
3
+ export declare const apiHelp: (apis: ApiDefinitions, invocation: string) => string;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.apiHelp = void 0;
4
+ const definition_1 = require("./definition");
5
+ const BUILT_IN_DESCRIPTIONS = {
6
+ up: 'Start the containers of the API',
7
+ down: 'Stop them',
8
+ logs: 'Follow the log of the API container',
9
+ shell: 'Open a shell in the API container',
10
+ clone: 'Clone the API into .ethlete/<name> from its repoUrl',
11
+ checkout: 'Switch the checkout to the branch apiRepoBranches names',
12
+ pull: 'Fetch and fast-forward the checked-out branch',
13
+ };
14
+ const pad = (text, width) => text.padEnd(width);
15
+ /** The help text for `et api`, listing the built-in commands and what each API adds to them. */
16
+ const apiHelp = (apis, invocation) => {
17
+ const entries = Object.entries(apis);
18
+ const width = Math.max(8, ...entries.map(([name]) => name.length));
19
+ const apiLines = entries.map(([name, api]) => ` ${pad(name, width)} ${(0, definition_1.apiCommandNames)(api).join(', ')}`);
20
+ const execNames = [...new Set(entries.flatMap(([, api]) => { var _a; return Object.keys((_a = api.exec) !== null && _a !== void 0 ? _a : {}); }))];
21
+ return [
22
+ `Usage: ${invocation} <command> <api> [--host]`,
23
+ '',
24
+ 'Commands',
25
+ ...definition_1.BUILT_IN_API_COMMANDS.map((command) => ` ${pad(command, 8)} ${BUILT_IN_DESCRIPTIONS[command]}`),
26
+ ...execNames.map((command) => ` ${pad(command, 8)} Declared by the API itself`),
27
+ '',
28
+ 'APIs',
29
+ ...(apiLines.length > 0 ? apiLines : [' none — declare them in ethlete.apis.js']),
30
+ '',
31
+ 'Options',
32
+ ` ${pad('--host', 8)} Also print the address another device on this network can use`,
33
+ ` ${pad('--force', 8)} With pull: discard local commits and tracked changes on the branch`,
34
+ ` ${pad('--clone', 8)} Clone a missing checkout without asking first`,
35
+ ` ${pad('--help', 8)} Show this text`,
36
+ ].join('\n');
37
+ };
38
+ exports.apiHelp = apiHelp;
39
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/help.ts"],"names":[],"mappings":";;;AAAA,6CAAsF;AAEtF,MAAM,qBAAqB,GAA2D;IACpF,EAAE,EAAE,iCAAiC;IACrC,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,qCAAqC;IAC3C,KAAK,EAAE,mCAAmC;IAC1C,KAAK,EAAE,qDAAqD;IAC5D,QAAQ,EAAE,yDAAyD;IACnE,IAAI,EAAE,+CAA+C;CACtD,CAAC;AAEF,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEhE,gGAAgG;AACzF,MAAM,OAAO,GAAG,CAAC,IAAoB,EAAE,UAAkB,EAAE,EAAE;IAClE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAEnE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,IAAA,4BAAe,EAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE3G,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,WAAC,OAAA,MAAM,CAAC,IAAI,CAAC,MAAA,GAAG,CAAC,IAAI,mCAAI,EAAE,CAAC,CAAA,EAAA,CAAC,CAAC,CAAC,CAAC;IAE1F,OAAO;QACL,UAAU,UAAU,2BAA2B;QAC/C,EAAE;QACF,UAAU;QACV,GAAG,kCAAqB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,qBAAqB,CAAC,OAAO,CAAC,EAAE,CAAC;QACpG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,8BAA8B,CAAC;QACjF,EAAE;QACF,MAAM;QACN,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,0CAA0C,CAAC,CAAC;QAClF,EAAE;QACF,SAAS;QACT,KAAK,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,iEAAiE;QACtF,KAAK,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,sEAAsE;QAC5F,KAAK,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,iDAAiD;QACvE,KAAK,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,kBAAkB;KACxC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC,CAAC;AAxBW,QAAA,OAAO,WAwBlB"}
@@ -1,5 +1,10 @@
1
1
  export * from './api-command';
2
2
  export * from './compose';
3
+ export * from './auth-hint';
4
+ export * from './clone';
3
5
  export * from './definition';
6
+ export * from './git';
7
+ export * from './help';
4
8
  export * from './load-definitions';
9
+ export * from './resolve-checkout';
5
10
  export * from './run';
@@ -3,7 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./api-command"), exports);
5
5
  tslib_1.__exportStar(require("./compose"), exports);
6
+ tslib_1.__exportStar(require("./auth-hint"), exports);
7
+ tslib_1.__exportStar(require("./clone"), exports);
6
8
  tslib_1.__exportStar(require("./definition"), exports);
9
+ tslib_1.__exportStar(require("./git"), exports);
10
+ tslib_1.__exportStar(require("./help"), exports);
7
11
  tslib_1.__exportStar(require("./load-definitions"), exports);
12
+ tslib_1.__exportStar(require("./resolve-checkout"), exports);
8
13
  tslib_1.__exportStar(require("./run"), exports);
9
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/index.ts"],"names":[],"mappings":";;;AAAA,wDAA8B;AAC9B,oDAA0B;AAC1B,uDAA6B;AAC7B,6DAAmC;AACnC,gDAAsB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/index.ts"],"names":[],"mappings":";;;AAAA,wDAA8B;AAC9B,oDAA0B;AAC1B,sDAA4B;AAC5B,kDAAwB;AACxB,uDAA6B;AAC7B,gDAAsB;AACtB,iDAAuB;AACvB,6DAAmC;AACnC,6DAAmC;AACnC,gDAAsB"}
@@ -0,0 +1,35 @@
1
+ import { CloneRequest } from './clone';
2
+ import { ApiDefinition } from './definition';
3
+ export type ApiCheckout = {
4
+ repoPath: string;
5
+ /** The directory the compose commands run in. */
6
+ composePath: string;
7
+ };
8
+ /**
9
+ * `legacyConfigWarning` is set on failure too. A wrong path is exactly when the developer needs to
10
+ * know which file the value actually came from.
11
+ */
12
+ export type ApiCheckoutResult = {
13
+ legacyConfigWarning?: string;
14
+ } & ({
15
+ ok: true;
16
+ checkout: ApiCheckout;
17
+ } | {
18
+ ok: false;
19
+ problem: string;
20
+ /** Set when the managed directory is empty and the API declares where to clone from. */
21
+ clonable?: CloneRequest;
22
+ });
23
+ /** Where an API's managed checkout goes when the developer configured no path of their own. */
24
+ export declare const managedCheckoutPath: (root: string, name: string) => string;
25
+ /** Resolves where an API's containers live, with the one message that explains each way it can fail. */
26
+ export declare const resolveApiCheckout: (options: {
27
+ root: string;
28
+ name: string;
29
+ api: ApiDefinition;
30
+ /**
31
+ * The git commands act on the checkout itself, so they must not demand a compose directory or the
32
+ * output of `setupCommand` — both can legitimately be absent on a checkout that was just cloned.
33
+ */
34
+ requireCompose?: boolean;
35
+ }) => ApiCheckoutResult;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveApiCheckout = exports.managedCheckoutPath = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const local_config_1 = require("../config/local-config");
7
+ const clone_1 = require("./clone");
8
+ const isDirectory = (path) => (0, fs_1.existsSync)(path) && (0, fs_1.statSync)(path).isDirectory();
9
+ const missingPathProblem = (options) => {
10
+ var _a;
11
+ const { name, api, reason } = options;
12
+ return (`${reason}\n\nAdd the path of your ${name} API checkout to ${local_config_1.LOCAL_CONFIG_FILE_NAME} in the repo ` +
13
+ `root. The file is gitignored, so it changes nothing for anyone else:\n\n` +
14
+ ` {\n "apiRepoPaths": {\n "${name}": "${(_a = api.examplePath) !== null && _a !== void 0 ? _a : `../${name}-api`}"\n }\n }`);
15
+ };
16
+ /** Where an API's managed checkout goes when the developer configured no path of their own. */
17
+ const managedCheckoutPath = (root, name) => (0, path_1.join)(root, clone_1.DEFAULT_CHECKOUT_DIR, name);
18
+ exports.managedCheckoutPath = managedCheckoutPath;
19
+ /** Resolves where an API's containers live, with the one message that explains each way it can fail. */
20
+ const resolveApiCheckout = (options) => {
21
+ const { root, name, api, requireCompose = true } = options;
22
+ const { config, fileName, isLegacy } = (0, local_config_1.readLocalConfig)(root);
23
+ const configured = (0, local_config_1.configuredApiRepoPath)(config, name);
24
+ const legacyConfigWarning = isLegacy
25
+ ? `${local_config_1.LEGACY_LOCAL_CONFIG_FILE_NAME} still holds "apiRepoPaths". Move it to ${local_config_1.LOCAL_CONFIG_FILE_NAME}.`
26
+ : undefined;
27
+ const repoPath = configured ? (0, local_config_1.resolveConfiguredPath)(root, configured) : (0, exports.managedCheckoutPath)(root, name);
28
+ if (!isDirectory(repoPath)) {
29
+ if (configured) {
30
+ return {
31
+ ok: false,
32
+ legacyConfigWarning,
33
+ problem: `apiRepoPaths.${name} points at ${repoPath}, which is not a directory that exists.`,
34
+ };
35
+ }
36
+ if (!api.repoUrl) {
37
+ return {
38
+ ok: false,
39
+ legacyConfigWarning,
40
+ problem: missingPathProblem({
41
+ name,
42
+ api,
43
+ reason: fileName
44
+ ? `${fileName} has no apiRepoPaths entry for "${name}", and the API declares no repoUrl.`
45
+ : `${name} has no checkout, and the API declares no repoUrl.`,
46
+ }),
47
+ };
48
+ }
49
+ return {
50
+ ok: false,
51
+ legacyConfigWarning,
52
+ problem: `${name} has no checkout at ${repoPath}.`,
53
+ clonable: {
54
+ repoUrl: api.repoUrl,
55
+ into: repoPath,
56
+ branch: (0, local_config_1.configuredApiRepoBranch)(config, name),
57
+ },
58
+ };
59
+ }
60
+ const composePath = (0, path_1.join)(repoPath, api.composeDir);
61
+ if (requireCompose && !isDirectory(composePath)) {
62
+ return {
63
+ ok: false,
64
+ legacyConfigWarning,
65
+ problem: `${repoPath} has no ${api.composeDir} directory. Is apiRepoPaths.${name} the right checkout?`,
66
+ };
67
+ }
68
+ if (requireCompose && api.envFile && !(0, fs_1.existsSync)((0, path_1.join)(composePath, api.envFile))) {
69
+ return {
70
+ ok: false,
71
+ legacyConfigWarning,
72
+ problem: `Missing ${api.envFile} in ${composePath}.${api.setupCommand ? ` Run "${api.setupCommand}" there first.` : ''}`,
73
+ };
74
+ }
75
+ return { ok: true, legacyConfigWarning, checkout: { repoPath, composePath } };
76
+ };
77
+ exports.resolveApiCheckout = resolveApiCheckout;
78
+ //# sourceMappingURL=resolve-checkout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-checkout.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/resolve-checkout.ts"],"names":[],"mappings":"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"}
@@ -7,4 +7,4 @@ export type RunApiCommandOptions = {
7
7
  /** How the caller is invoked, used in the usage line. */
8
8
  invocation?: string;
9
9
  };
10
- export declare const runApiCommand: ({ apis, argv, root, invocation }: RunApiCommandOptions) => number;
10
+ export declare const runApiCommand: ({ apis, argv, root, invocation, }: RunApiCommandOptions) => Promise<number>;
@@ -1,27 +1,38 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runApiCommand = void 0;
4
+ const tslib_1 = require("tslib");
4
5
  const child_process_1 = require("child_process");
5
- const fs_1 = require("fs");
6
- const path_1 = require("path");
7
- const local_config_1 = require("../config/local-config");
8
6
  const compose_1 = require("./compose");
9
7
  const definition_1 = require("./definition");
10
- const configHelp = ({ name, api, reason }) => {
11
- var _a;
12
- return `${reason}\n\nAdd the path of your ${name} API checkout to ${local_config_1.LOCAL_CONFIG_FILE_NAME} in the repo ` +
13
- `root. The file is gitignored, so it changes nothing for anyone else:\n\n` +
14
- ` {\n "apiRepoPaths": {\n "${name}": "${(_a = api.examplePath) !== null && _a !== void 0 ? _a : `../${name}-api`}"\n }\n }`;
15
- };
8
+ const git_1 = require("./git");
9
+ const help_1 = require("./help");
10
+ const resolve_checkout_1 = require("./resolve-checkout");
11
+ const clone_1 = require("./clone");
12
+ const auth_hint_1 = require("./auth-hint");
13
+ const utils_1 = require("../utils");
14
+ const local_config_1 = require("../config/local-config");
15
+ const confirmClone = (options) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
16
+ const { problem, repoUrl, into } = options;
17
+ if (!process.stdin.isTTY) {
18
+ console.error(`${problem}\n\nRe-run with --clone to clone ${repoUrl} into ${into}.`);
19
+ return false;
20
+ }
21
+ const answer = yield (0, utils_1.askQuestion)(`${problem}\n\nClone ${repoUrl}\ninto ${into}? [y/N] `);
22
+ return /^y(es)?$/i.test(answer.trim());
23
+ });
16
24
  const definedEntries = (record) => Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));
17
- const isDirectory = (path) => (0, fs_1.existsSync)(path) && (0, fs_1.statSync)(path).isDirectory();
18
- const runApiCommand = ({ apis, argv, root = process.cwd(), invocation = 'et api' }) => {
19
- var _a, _b, _c, _d;
25
+ const runApiCommand = (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ apis, argv, root = process.cwd(), invocation = 'et api', }) {
26
+ var _b, _c, _d, _e;
20
27
  const exposeOnLan = argv.includes('--host');
21
28
  const [command, name] = argv.filter((arg) => !arg.startsWith('--'));
22
29
  const api = name === undefined ? undefined : apis[name];
30
+ if (argv.includes('--help') || argv.includes('-h') || command === 'help') {
31
+ console.log((0, help_1.apiHelp)(apis, invocation));
32
+ return 0;
33
+ }
23
34
  if (command === undefined || name === undefined || !api) {
24
- console.error(`Usage: ${invocation} <command> <api> [--host]\n\nAPIs: ${Object.keys(apis).join(', ')}`);
35
+ console.error((0, help_1.apiHelp)(apis, invocation));
25
36
  return 1;
26
37
  }
27
38
  const commands = (0, definition_1.apiCommandNames)(api);
@@ -29,34 +40,50 @@ const runApiCommand = ({ apis, argv, root = process.cwd(), invocation = 'et api'
29
40
  console.error(`Unknown command "${command}" for the ${name} API.\n\nCommands: ${commands.join(', ')}`);
30
41
  return 1;
31
42
  }
32
- const { config, fileName, isLegacy } = (0, local_config_1.readLocalConfig)(root);
33
- const configured = (0, local_config_1.configuredApiRepoPath)(config, name);
34
- if (!configured) {
35
- console.error(configHelp({
36
- name,
37
- api,
38
- reason: fileName
39
- ? `${fileName} has no apiRepoPaths entry for "${name}".`
40
- : `${local_config_1.LOCAL_CONFIG_FILE_NAME} does not exist.`,
41
- }));
42
- return 1;
43
- }
44
- if (isLegacy) {
45
- console.warn(`${local_config_1.LEGACY_LOCAL_CONFIG_FILE_NAME} still holds "apiRepoPaths". Move it to ${local_config_1.LOCAL_CONFIG_FILE_NAME}.\n`);
43
+ const isGitCommand = definition_1.GIT_API_COMMANDS.includes(command);
44
+ const checkout = (0, resolve_checkout_1.resolveApiCheckout)({ root, name, api, requireCompose: !isGitCommand });
45
+ if (checkout.legacyConfigWarning) {
46
+ console.warn(`${checkout.legacyConfigWarning}\n`);
46
47
  }
47
- const repoPath = (0, local_config_1.resolveConfiguredPath)(root, configured);
48
- if (!isDirectory(repoPath)) {
49
- console.error(`apiRepoPaths.${name} points at ${repoPath}, which is not a directory that exists.`);
50
- return 1;
48
+ if (!checkout.ok) {
49
+ if (!checkout.clonable) {
50
+ console.error(checkout.problem);
51
+ return 1;
52
+ }
53
+ const { repoUrl, into, branch } = checkout.clonable;
54
+ const accepted = command === 'clone' ||
55
+ argv.includes('--clone') ||
56
+ (yield confirmClone({ problem: checkout.problem, repoUrl, into }));
57
+ if (!accepted)
58
+ return 1;
59
+ if (!(0, clone_1.isGitIgnored)(root, into)) {
60
+ console.warn(`\n${clone_1.DEFAULT_CHECKOUT_DIR}/ is not gitignored. Add it before you commit anything.\n`);
61
+ }
62
+ const cloned = (0, clone_1.cloneApiRepo)({ repoUrl, into, branch });
63
+ if (cloned !== 0) {
64
+ (0, auth_hint_1.printPrivateDependencyHint)({ repoHost: (0, auth_hint_1.gitUrlHost)(repoUrl) });
65
+ return cloned;
66
+ }
67
+ if (command === 'clone')
68
+ return 0;
69
+ return (0, exports.runApiCommand)({ apis, argv, root, invocation });
51
70
  }
52
- const cwd = (0, path_1.join)(repoPath, api.composeDir);
53
- if (!isDirectory(cwd)) {
54
- console.error(`${repoPath} has no ${api.composeDir} directory. Is apiRepoPaths.${name} the right checkout?`);
55
- return 1;
71
+ if (command === 'clone') {
72
+ console.log(`${name} already has a checkout at ${checkout.checkout.repoPath}.`);
73
+ return 0;
56
74
  }
57
- if (api.envFile && !(0, fs_1.existsSync)((0, path_1.join)(cwd, api.envFile))) {
58
- console.error(`Missing ${api.envFile} in ${cwd}.${api.setupCommand ? ` Run "${api.setupCommand}" there first.` : ''}`);
59
- return 1;
75
+ const { repoPath, composePath: cwd } = checkout.checkout;
76
+ if (isGitCommand) {
77
+ const expectedBranch = (0, local_config_1.configuredApiRepoBranch)((0, local_config_1.readLocalConfig)(root).config, name);
78
+ if (command === 'checkout') {
79
+ if (!expectedBranch) {
80
+ console.error(`No branch configured for "${name}". Add it to apiRepoBranches:\n\n` +
81
+ ` {\n "apiRepoBranches": {\n "${name}": "main"\n }\n }`);
82
+ return 1;
83
+ }
84
+ return (0, git_1.checkoutApiBranch)({ repoPath, branch: expectedBranch });
85
+ }
86
+ return (0, git_1.pullApiBranch)({ repoPath, expectedBranch, force: argv.includes('--force') });
60
87
  }
61
88
  const tool = (0, compose_1.resolveComposeTool)();
62
89
  if (!tool) {
@@ -65,7 +92,7 @@ const runApiCommand = ({ apis, argv, root = process.cwd(), invocation = 'et api'
65
92
  }
66
93
  const { engine, compose } = tool;
67
94
  const [binary, ...composePrefix] = compose;
68
- const env = Object.assign(Object.assign(Object.assign({}, (0, compose_1.engineEnv)(engine)), process.env), definedEntries((_b = (_a = api.env) === null || _a === void 0 ? void 0 : _a.call(api)) !== null && _b !== void 0 ? _b : {}));
95
+ const env = Object.assign(Object.assign(Object.assign({}, (0, compose_1.engineEnv)(engine)), process.env), definedEntries((_c = (_b = api.env) === null || _b === void 0 ? void 0 : _b.call(api)) !== null && _c !== void 0 ? _c : {}));
69
96
  let exitCode = 0;
70
97
  const runCompose = (...composeArgs) => {
71
98
  var _a;
@@ -111,9 +138,12 @@ const runApiCommand = ({ apis, argv, root = process.cwd(), invocation = 'et api'
111
138
  runCompose('exec', api.execService, 'bash');
112
139
  }
113
140
  else {
114
- runCompose('exec', api.execService, ...((_d = (_c = api.exec) === null || _c === void 0 ? void 0 : _c[command]) !== null && _d !== void 0 ? _d : []));
141
+ runCompose('exec', api.execService, ...((_e = (_d = api.exec) === null || _d === void 0 ? void 0 : _d[command]) !== null && _e !== void 0 ? _e : []));
142
+ if (exitCode !== 0) {
143
+ (0, auth_hint_1.printPrivateDependencyHint)({ repoHost: api.repoUrl ? (0, auth_hint_1.gitUrlHost)(api.repoUrl) : undefined });
144
+ }
115
145
  }
116
146
  return exitCode;
117
- };
147
+ });
118
148
  exports.runApiCommand = runApiCommand;
119
149
  //# sourceMappingURL=run.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Every problem with the repo topology config: a file that cannot be parsed, a key nothing reads, a
3
+ * checkout that is not there, and values still sitting in the file they moved out of.
4
+ */
5
+ export declare const diagnoseLocalConfig: ({ root }: {
6
+ root: string;
7
+ }) => string[];
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.diagnoseLocalConfig = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const local_config_1 = require("./local-config");
7
+ /** Marks a directory as an `ethlete-sdk` checkout rather than some other folder. */
8
+ const SDK_CHECKOUT_MARKERS = ['libs/components', 'libs/core', 'libs/agent-rules'];
9
+ const quoted = (keys) => keys.map((key) => `"${key}"`).join(', ');
10
+ const describeSdkSourcePath = (options) => {
11
+ const { root, value, fileName } = options;
12
+ if (value === undefined)
13
+ return [];
14
+ if (typeof value !== 'string' || value.trim().length === 0) {
15
+ return [`${fileName} has an invalid "sdkSourcePath" — use a path to an ethlete-sdk checkout.`];
16
+ }
17
+ const absolute = (0, local_config_1.resolveConfiguredPath)(root, value);
18
+ if (!(0, fs_1.existsSync)(absolute)) {
19
+ return [`${fileName} points "sdkSourcePath" at ${absolute}, which does not exist.`];
20
+ }
21
+ if (SDK_CHECKOUT_MARKERS.some((marker) => !(0, fs_1.existsSync)((0, path_1.join)(absolute, marker)))) {
22
+ return [`${fileName} points "sdkSourcePath" at ${absolute}, which is not an ethlete-sdk checkout.`];
23
+ }
24
+ return [];
25
+ };
26
+ const describeApiRepoPaths = (options) => {
27
+ const { root, value, fileName } = options;
28
+ if (value === undefined)
29
+ return [];
30
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
31
+ return [
32
+ `${fileName} has an invalid "apiRepoPaths" value — use an object mapping an app name to its API repo path.`,
33
+ ];
34
+ }
35
+ return Object.entries(value).flatMap(([app, path]) => {
36
+ if (typeof path !== 'string' || path.trim().length === 0) {
37
+ return [`${fileName} has an invalid "apiRepoPaths.${app}" value — use a path to the API repo.`];
38
+ }
39
+ const absolute = (0, local_config_1.resolveConfiguredPath)(root, path);
40
+ if (!(0, fs_1.existsSync)(absolute)) {
41
+ return [`${fileName} points "apiRepoPaths.${app}" at ${absolute}, which does not exist.`];
42
+ }
43
+ if (!(0, fs_1.statSync)(absolute).isDirectory()) {
44
+ return [`${fileName} points "apiRepoPaths.${app}" at ${absolute}, which is not a directory.`];
45
+ }
46
+ return [];
47
+ });
48
+ };
49
+ const describeApiRepoBranches = (options) => {
50
+ const { value, fileName } = options;
51
+ if (value === undefined)
52
+ return [];
53
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
54
+ return [
55
+ `${fileName} has an invalid "apiRepoBranches" value — use an object mapping an app name to its expected API branch.`,
56
+ ];
57
+ }
58
+ return Object.entries(value).flatMap(([app, branch]) => typeof branch === 'string' && branch.trim().length > 0
59
+ ? []
60
+ : [`${fileName} has an invalid "apiRepoBranches.${app}" value — use a non-empty branch name.`]);
61
+ };
62
+ const describeValues = (options) => {
63
+ const { root, config, fileName } = options;
64
+ return [
65
+ ...describeSdkSourcePath({ root, value: config.sdkSourcePath, fileName }),
66
+ ...describeApiRepoPaths({ root, value: config.apiRepoPaths, fileName }),
67
+ ...describeApiRepoBranches({ value: config.apiRepoBranches, fileName }),
68
+ ];
69
+ };
70
+ /**
71
+ * Every problem with the repo topology config: a file that cannot be parsed, a key nothing reads, a
72
+ * checkout that is not there, and values still sitting in the file they moved out of.
73
+ */
74
+ const diagnoseLocalConfig = ({ root }) => {
75
+ const primary = (0, local_config_1.readLocalConfigFile)((0, path_1.join)(root, local_config_1.LOCAL_CONFIG_FILE_NAME));
76
+ if (primary.status === 'unreadable')
77
+ return [`${local_config_1.LOCAL_CONFIG_FILE_NAME} is not valid JSON.`];
78
+ if (primary.status === 'not-an-object')
79
+ return [`${local_config_1.LOCAL_CONFIG_FILE_NAME} is not a JSON object.`];
80
+ if (primary.status === 'ok') {
81
+ const unknownKeys = Object.keys(primary.config).filter((key) => !local_config_1.LOCAL_CONFIG_KEYS.includes(key));
82
+ return [
83
+ ...(unknownKeys.length > 0
84
+ ? [
85
+ `${local_config_1.LOCAL_CONFIG_FILE_NAME} contains key(s) nothing reads: ${quoted(unknownKeys)} — it supports ${quoted(local_config_1.LOCAL_CONFIG_KEYS)}.`,
86
+ ]
87
+ : []),
88
+ ...describeValues({ root, config: primary.config, fileName: local_config_1.LOCAL_CONFIG_FILE_NAME }),
89
+ ];
90
+ }
91
+ const legacy = (0, local_config_1.readLocalConfigFile)((0, path_1.join)(root, local_config_1.LEGACY_LOCAL_CONFIG_FILE_NAME));
92
+ if (legacy.status !== 'ok')
93
+ return [];
94
+ const held = local_config_1.LOCAL_CONFIG_KEYS.filter((key) => legacy.config[key] !== undefined);
95
+ if (held.length === 0)
96
+ return [];
97
+ return [
98
+ `${local_config_1.LEGACY_LOCAL_CONFIG_FILE_NAME} still holds ${quoted(held)} — move ${held.length === 1 ? 'it' : 'them'} to ${local_config_1.LOCAL_CONFIG_FILE_NAME}.`,
99
+ ...describeValues({ root, config: legacy.config, fileName: local_config_1.LEGACY_LOCAL_CONFIG_FILE_NAME }),
100
+ ];
101
+ };
102
+ exports.diagnoseLocalConfig = diagnoseLocalConfig;
103
+ //# sourceMappingURL=diagnose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnose.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/config/diagnose.ts"],"names":[],"mappings":"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"}
@@ -1 +1,2 @@
1
+ export * from './diagnose';
1
2
  export * from './local-config';
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./diagnose"), exports);
4
5
  tslib_1.__exportStar(require("./local-config"), exports);
5
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/config/index.ts"],"names":[],"mappings":";;;AAAA,yDAA+B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/config/index.ts"],"names":[],"mappings":";;;AAAA,qDAA2B;AAC3B,yDAA+B"}
@@ -16,6 +16,17 @@ export type LocalConfig = {
16
16
  /** Branch that represents each API's deployed state, keyed by app name. `"*"` matches any app. */
17
17
  apiRepoBranches?: Record<string, string>;
18
18
  };
19
+ export declare const LOCAL_CONFIG_KEYS: (keyof LocalConfig)[];
20
+ export type LocalConfigFileState = {
21
+ status: 'absent';
22
+ } | {
23
+ status: 'unreadable';
24
+ } | {
25
+ status: 'not-an-object';
26
+ } | {
27
+ status: 'ok';
28
+ config: LocalConfig;
29
+ };
19
30
  export type LocalConfigSource = {
20
31
  config: LocalConfig;
21
32
  /** The file the values came from, or `undefined` when neither file exists. */
@@ -23,6 +34,8 @@ export type LocalConfigSource = {
23
34
  /** True when the values came from `LEGACY_LOCAL_CONFIG_FILE_NAME`. */
24
35
  isLegacy: boolean;
25
36
  };
37
+ /** Reads one config file, keeping "not there" apart from "there but broken" for `et doctor`. */
38
+ export declare const readLocalConfigFile: (path: string) => LocalConfigFileState;
26
39
  /** Reads the local config, falling back to the file the keys used to live in. */
27
40
  export declare const readLocalConfig: (root: string) => LocalConfigSource;
28
41
  export declare const configuredApiRepoPath: (config: LocalConfig, api: string) => string | undefined;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveConfiguredPath = exports.configuredApiRepoBranch = exports.configuredApiRepoPath = exports.readLocalConfig = exports.LEGACY_LOCAL_CONFIG_FILE_NAME = exports.LOCAL_CONFIG_FILE_NAME = void 0;
3
+ exports.resolveConfiguredPath = exports.configuredApiRepoBranch = exports.configuredApiRepoPath = exports.readLocalConfig = exports.readLocalConfigFile = exports.LOCAL_CONFIG_KEYS = exports.LEGACY_LOCAL_CONFIG_FILE_NAME = exports.LOCAL_CONFIG_FILE_NAME = void 0;
4
4
  const fs_1 = require("fs");
5
5
  const path_1 = require("path");
6
6
  exports.LOCAL_CONFIG_FILE_NAME = 'ethlete.config.local.json';
@@ -9,19 +9,26 @@ exports.LOCAL_CONFIG_FILE_NAME = 'ethlete.config.local.json';
9
9
  * fallback so an existing checkout keeps working, and reported so the developer can move them.
10
10
  */
11
11
  exports.LEGACY_LOCAL_CONFIG_FILE_NAME = 'ethlete-agents.config.local.json';
12
- const readJsonObject = (path) => {
12
+ exports.LOCAL_CONFIG_KEYS = ['sdkSourcePath', 'apiRepoPaths', 'apiRepoBranches'];
13
+ /** Reads one config file, keeping "not there" apart from "there but broken" for `et doctor`. */
14
+ const readLocalConfigFile = (path) => {
13
15
  if (!(0, fs_1.existsSync)(path))
14
- return undefined;
16
+ return { status: 'absent' };
15
17
  let parsed;
16
18
  try {
17
19
  parsed = JSON.parse((0, fs_1.readFileSync)(path, 'utf8'));
18
20
  }
19
21
  catch (_a) {
20
- return undefined;
22
+ return { status: 'unreadable' };
21
23
  }
22
24
  if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
23
- return undefined;
24
- return parsed;
25
+ return { status: 'not-an-object' };
26
+ return { status: 'ok', config: parsed };
27
+ };
28
+ exports.readLocalConfigFile = readLocalConfigFile;
29
+ const readJsonObject = (path) => {
30
+ const state = (0, exports.readLocalConfigFile)(path);
31
+ return state.status === 'ok' ? state.config : undefined;
25
32
  };
26
33
  /** Reads the local config, falling back to the file the keys used to live in. */
27
34
  const readLocalConfig = (root) => {
@@ -1 +1 @@
1
- {"version":3,"file":"local-config.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/config/local-config.ts"],"names":[],"mappings":";;;AAAA,2BAA8C;AAC9C,+BAAiD;AAEpC,QAAA,sBAAsB,GAAG,2BAA2B,CAAC;AAElE;;;GAGG;AACU,QAAA,6BAA6B,GAAG,kCAAkC,CAAC;AAuBhF,MAAM,cAAc,GAAG,CAAC,IAAY,EAA2B,EAAE;IAC/D,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAExC,IAAI,MAAe,CAAC;IAEpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAE7F,OAAO,MAAqB,CAAC;AAC/B,CAAC,CAAC;AAEF,iFAAiF;AAC1E,MAAM,eAAe,GAAG,CAAC,IAAY,EAAqB,EAAE;IACjE,MAAM,OAAO,GAAG,cAAc,CAAC,IAAA,WAAI,EAAC,IAAI,EAAE,8BAAsB,CAAC,CAAC,CAAC;IAEnE,IAAI,OAAO;QAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,8BAAsB,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAE3F,MAAM,MAAM,GAAG,cAAc,CAAC,IAAA,WAAI,EAAC,IAAI,EAAE,qCAA6B,CAAC,CAAC,CAAC;IAEzE,IAAI,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,qCAA6B,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAE/F,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACzC,CAAC,CAAC;AAVW,QAAA,eAAe,mBAU1B;AAEF,MAAM,QAAQ,GAAG,CAAC,MAA0C,EAAE,GAAW,EAAE,EAAE,WAAC,OAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,GAAG,CAAC,mCAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,GAAG,CAAC,CAAA,EAAA,CAAC;AAEtG,MAAM,qBAAqB,GAAG,CAAC,MAAmB,EAAE,GAAW,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AAAjG,QAAA,qBAAqB,yBAA4E;AAEvG,MAAM,uBAAuB,GAAG,CAAC,MAAmB,EAAE,GAAW,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;AAAtG,QAAA,uBAAuB,2BAA+E;AAEnH,8FAA8F;AACvF,MAAM,qBAAqB,GAAG,CAAC,IAAY,EAAE,UAAkB,EAAE,EAAE,CACxE,IAAA,iBAAU,EAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAA,cAAO,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AADrD,QAAA,qBAAqB,yBACgC"}
1
+ {"version":3,"file":"local-config.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/config/local-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /** Reports every problem with this machine's setup, so `et api` does not have to find them one at a time. */
2
+ export declare const doctorCommand: ({ root }: {
3
+ root: string;
4
+ }) => 0 | 1;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.doctorCommand = void 0;
4
+ const compose_1 = require("../api/compose");
5
+ const path_1 = require("path");
6
+ const load_definitions_1 = require("../api/load-definitions");
7
+ const resolve_checkout_1 = require("../api/resolve-checkout");
8
+ const diagnose_1 = require("../config/diagnose");
9
+ const local_config_1 = require("../config/local-config");
10
+ const indent = (text) => text.replace(/\n/g, '\n ');
11
+ const describeComposeTool = () => {
12
+ const tool = (0, compose_1.resolveComposeTool)();
13
+ return tool
14
+ ? { line: `container engine: ${(0, compose_1.composeBinary)(tool.compose).join(' ')}`, problems: [] }
15
+ : { line: undefined, problems: [`No compose tool found. Tried: ${(0, compose_1.composeToolNames)().join(', ')}.`] };
16
+ };
17
+ const describeApis = (root) => {
18
+ const { found, apis, fileName } = (0, load_definitions_1.loadApiDefinitions)(root);
19
+ if (!found)
20
+ return { lines: [], problems: [] };
21
+ const lines = [];
22
+ const problems = [];
23
+ for (const [name, api] of Object.entries(apis)) {
24
+ const checkout = (0, resolve_checkout_1.resolveApiCheckout)({ root, name, api });
25
+ if (checkout.ok) {
26
+ lines.push(`${fileName}: ${name} → ${checkout.checkout.composePath}`);
27
+ }
28
+ else if (checkout.clonable) {
29
+ problems.push(`${checkout.problem} Run "et api clone ${name}".`);
30
+ }
31
+ else {
32
+ problems.push(checkout.problem);
33
+ }
34
+ }
35
+ return { lines, problems };
36
+ };
37
+ /** Reports every problem with this machine's setup, so `et api` does not have to find them one at a time. */
38
+ const doctorCommand = ({ root }) => {
39
+ // A file that exists but cannot be parsed still has to be reported, so this asks whether the file
40
+ // is there rather than whether it could be read.
41
+ const hasConfig = [local_config_1.LOCAL_CONFIG_FILE_NAME, local_config_1.LEGACY_LOCAL_CONFIG_FILE_NAME].some((fileName) => (0, local_config_1.readLocalConfigFile)((0, path_1.join)(root, fileName)).status !== 'absent');
42
+ const hasApis = (0, load_definitions_1.loadApiDefinitions)(root).found;
43
+ if (!hasConfig && !hasApis) {
44
+ console.log(`Nothing to check: ${root} has no ${local_config_1.LOCAL_CONFIG_FILE_NAME} and no ${load_definitions_1.API_DEFINITIONS_FILE_NAMES[0]}.`);
45
+ return 0;
46
+ }
47
+ const configProblems = (0, diagnose_1.diagnoseLocalConfig)({ root });
48
+ const compose = describeComposeTool();
49
+ const apis = describeApis(root);
50
+ const problems = [...configProblems, ...compose.problems, ...apis.problems];
51
+ for (const line of [compose.line, ...apis.lines].filter(Boolean)) {
52
+ console.log(` ${line}`);
53
+ }
54
+ if (problems.length === 0) {
55
+ console.log('\nNo problems found.');
56
+ return 0;
57
+ }
58
+ console.error(`\n${problems.length} problem(s):\n`);
59
+ for (const problem of problems) {
60
+ console.error(` - ${indent(problem)}`);
61
+ }
62
+ return 1;
63
+ };
64
+ exports.doctorCommand = doctorCommand;
65
+ //# sourceMappingURL=doctor-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-command.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/doctor/doctor-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from './doctor-command';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./doctor-command"), exports);
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/doctor/index.ts"],"names":[],"mappings":";;;AAAA,2DAAiC"}
@@ -1,3 +1,4 @@
1
1
  export * from './api';
2
2
  export * from './config';
3
+ export * from './doctor';
3
4
  export * from './release';
package/src/lib/index.js CHANGED
@@ -3,5 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./api"), exports);
5
5
  tslib_1.__exportStar(require("./config"), exports);
6
+ tslib_1.__exportStar(require("./doctor"), exports);
6
7
  tslib_1.__exportStar(require("./release"), exports);
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/cli/src/lib/index.ts"],"names":[],"mappings":";;;AAAA,gDAAsB;AACtB,mDAAyB;AACzB,oDAA0B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/cli/src/lib/index.ts"],"names":[],"mappings":";;;AAAA,gDAAsB;AACtB,mDAAyB;AACzB,mDAAyB;AACzB,oDAA0B"}