@ovrdev/cli 0.1.0-alpha.17 → 0.1.0-alpha.18

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 (2) hide show
  1. package/dist/cli/index.js +68 -7
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -781,6 +781,22 @@ import { defineConfig } from "@ovrdev/cli"
781
781
 
782
782
  export default defineConfig({ plugins: [] }, ({ workspace, kind }) => ({
783
783
  services: {
784
+ // A placeholder so \`ovr run\` boots something right away. It prints a few tips and
785
+ // stays up until you quit (qq). Replace it with your real service(s) — see the example.
786
+ hello: kind.shell({
787
+ command: [
788
+ "echo ''",
789
+ "echo ' \uD83D\uDC4B ovr is running this repo.'",
790
+ "echo ''",
791
+ "echo ' • Edit ovr.config.mts to declare your real services, then rerun ovr run.'",
792
+ "echo ' • A service is a process: kind.shell({ command, env, ready, exports }).'",
793
+ "echo ' • Every service gets its own allocated port — cross-wire with refs.'",
794
+ "echo ' • Press qq to quit; a service that stays up keeps the run alive.'",
795
+ "echo ''",
796
+ "tail -f /dev/null", // hang until ovr stops it (SIGTERM on quit)
797
+ ].join(" && "),
798
+ }),
799
+
784
800
  // web: kind.shell({
785
801
  // prepare: async ({ ports }) => ({ port: await ports.alloc() }),
786
802
  // command: ({ port }) => \`pnpm dev --port \${port}\`,
@@ -897,6 +913,46 @@ async function cmdSetup(args = [], override) {
897
913
  if (!touched)
898
914
  console.log(dim("Nothing to provision (no setup declared, or nothing overridden)."));
899
915
  }
916
+ function methodOfUrl(url) {
917
+ if (/^(git@|ssh:\/\/)/.test(url))
918
+ return "ssh";
919
+ if (/^https?:\/\//.test(url))
920
+ return "https";
921
+ return;
922
+ }
923
+ function inferCloneMethod(cfg) {
924
+ for (const def of Object.values(cfg.workspaces)) {
925
+ for (const decl of Object.values(def.repos ?? {})) {
926
+ if (decl.path) {
927
+ const m = methodOfUrl(decl.remote);
928
+ if (m)
929
+ return m;
930
+ }
931
+ }
932
+ }
933
+ return;
934
+ }
935
+ async function ensureCloneMethod(cfg, remote) {
936
+ if (cfg.cloneMethod)
937
+ return;
938
+ if (/^(git@|ssh:\/\/|https?:\/\/|file:\/\/)/.test(remote) || /^[/.~]/.test(remote))
939
+ return;
940
+ if (!process.stdin.isTTY)
941
+ return;
942
+ const initialValue = inferCloneMethod(cfg) ?? DEFAULT_CLONE_METHOD;
943
+ const sel = await clack.select({
944
+ message: "Clone method (how org/repo slugs expand)",
945
+ options: [
946
+ { value: "ssh", label: "ssh", hint: "git@github.com:org/repo.git" },
947
+ { value: "https", label: "https" }
948
+ ],
949
+ initialValue
950
+ });
951
+ if (clack.isCancel(sel))
952
+ return;
953
+ cfg.cloneMethod = sel;
954
+ saveConfig(cfg);
955
+ }
900
956
  function cloneInto(cfg, workspace, name, decl) {
901
957
  const dir = repoDir(cfg, workspace, name);
902
958
  if (existsSync6(dir))
@@ -907,7 +963,7 @@ function cloneInto(cfg, workspace, name, decl) {
907
963
  console.log(`Cloning ${name} (${url}) → ${dir}`);
908
964
  execFileSync2("git", ["clone", "--branch", branch, url, dir], { stdio: "inherit" });
909
965
  }
910
- function cmdRepoAdd(args, override) {
966
+ async function cmdRepoAdd(args, override) {
911
967
  let name;
912
968
  let branch;
913
969
  let noClone = false;
@@ -936,8 +992,10 @@ function cmdRepoAdd(args, override) {
936
992
  const decl = { remote };
937
993
  if (branch)
938
994
  decl.branch = branch;
939
- if (!noClone)
995
+ if (!noClone) {
996
+ await ensureCloneMethod(cfg, remote);
940
997
  cloneInto(cfg, workspace, repoName, decl);
998
+ }
941
999
  proj.repos ??= {};
942
1000
  proj.repos[repoName] = decl;
943
1001
  saveConfig(cfg);
@@ -1261,7 +1319,7 @@ ${bold(name)} ${dim("$ git fetch --prune")}`);
1261
1319
  console.log(fetched.size ? `
1262
1320
  ✓ fetched ${fetched.size} repo(s)` : "Nothing to fetch.");
1263
1321
  }
1264
- function cmdRepoClone(args, override) {
1322
+ async function cmdRepoClone(args, override) {
1265
1323
  const all = args.includes("--all") || args.includes("-a");
1266
1324
  const name = args.find((a) => !a.startsWith("-"));
1267
1325
  const cfg = loadConfig();
@@ -1282,8 +1340,10 @@ function cmdRepoClone(args, override) {
1282
1340
  }
1283
1341
  if (!targets.length)
1284
1342
  return console.log("Nothing to clone — all declared repos are present.");
1285
- for (const r of targets)
1343
+ for (const r of targets) {
1344
+ await ensureCloneMethod(cfg, repos[r].remote);
1286
1345
  cloneInto(cfg, workspace, r, repos[r]);
1346
+ }
1287
1347
  console.log(`✓ cloned ${targets.length} repo(s) into '${workspace}'`);
1288
1348
  }
1289
1349
  async function cmdFork(args, override) {
@@ -1667,7 +1727,7 @@ Shell integration — add to ${rc.display}:`);
1667
1727
  seeded.active = base;
1668
1728
  saveConfig(seeded);
1669
1729
  }
1670
- cmdRepoClone(["--all"], base);
1730
+ await cmdRepoClone(["--all"], base);
1671
1731
  }
1672
1732
  }
1673
1733
  clack2.outro("Bootstrap complete.");
@@ -2037,10 +2097,11 @@ async function cmdInit(args) {
2037
2097
  if (!cfg.root) {
2038
2098
  const root = positional[0] ? resolve2(positional[0]) : defaultRoot();
2039
2099
  cfg.root = root;
2040
- cfg.cloneMethod = methodFlag ?? cfg.cloneMethod ?? DEFAULT_CLONE_METHOD;
2100
+ if (methodFlag)
2101
+ cfg.cloneMethod = methodFlag;
2041
2102
  mkdirSync9(root, { recursive: true });
2042
2103
  saveConfig(cfg);
2043
- console.log(`✓ bootstrapped — root → ${root} · clone → ${cfg.cloneMethod}`);
2104
+ console.log(`✓ bootstrapped — root → ${root}${cfg.cloneMethod ? ` · clone → ${cfg.cloneMethod}` : ""}`);
2044
2105
  }
2045
2106
  const cwd = process.cwd();
2046
2107
  const existing = findConfigFile(cwd);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ovrdev/cli",
3
- "version": "0.1.0-alpha.17",
3
+ "version": "0.1.0-alpha.18",
4
4
  "description": "Override — the dev control plane: environments, repos, services, tasks",
5
5
  "type": "module",
6
6
  "bin": {