@catladder/cli 1.105.2 → 1.106.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/package.json CHANGED
@@ -24,7 +24,7 @@
24
24
  "node": ">=12.0.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@catladder/pipeline": "1.105.2",
27
+ "@catladder/pipeline": "1.106.0",
28
28
  "@kubernetes/client-node": "^0.16.2",
29
29
  "@tsconfig/node14": "^1.0.1",
30
30
  "@types/common-tags": "^1.8.0",
@@ -57,5 +57,5 @@
57
57
  "typescript": "^4.5.4",
58
58
  "vorpal": "^1.12.0"
59
59
  },
60
- "version": "1.105.2"
60
+ "version": "1.106.0"
61
61
  }
@@ -1,29 +1,8 @@
1
1
  import { spawn } from "child-process-promise";
2
- import type Vorpal from "vorpal";
3
2
 
4
- const createProxy = async (instance: string, port: number) => {
5
- const proxy = spawn(
6
- `cloud_sql_proxy -instances ${instance}=tcp:${port}`,
7
- [],
8
- { shell: "bash" }
9
- );
10
- // wait until it starts
11
- await spawn(
12
- `echo -n "Waiting for proxy"
13
- until echo > /dev/tcp/localhost/${port}; do
14
- sleep 0.2
15
- echo -n "."
16
- done 2>/dev/null`,
17
- [],
18
- { shell: "bash" }
19
- );
20
- const stop = () => proxy.childProcess.kill();
21
- process.on("beforeExit", stop);
22
-
23
- return {
24
- stop,
25
- };
26
- };
3
+ import type Vorpal from "vorpal";
4
+ import type { CloudSqlBackgroundProxy } from "../../../../gcloud/cloudSql/startProxy";
5
+ import { startCloudSqlProxyInBackground } from "../../../../gcloud/cloudSql/startProxy";
27
6
 
28
7
  export default async (vorpal: Vorpal) =>
29
8
  vorpal
@@ -39,9 +18,9 @@ export default async (vorpal: Vorpal) =>
39
18
  message: "Source instance (connection string or 'local')? 🤔 ",
40
19
  });
41
20
 
42
- let sourceProxy: { stop: () => void };
21
+ let sourceProxy: CloudSqlBackgroundProxy;
43
22
 
44
- let targetProxy: { stop: () => void };
23
+ let targetProxy: CloudSqlBackgroundProxy;
45
24
 
46
25
  let sourcePort: number;
47
26
  let targetPort: number;
@@ -57,7 +36,10 @@ export default async (vorpal: Vorpal) =>
57
36
  sourcePort = sourceLocalPort;
58
37
  } else {
59
38
  sourcePort = 54399;
60
- sourceProxy = await createProxy(sourceInstance, sourcePort);
39
+ sourceProxy = await startCloudSqlProxyInBackground({
40
+ instanceName: sourceInstance,
41
+ localPort: sourcePort,
42
+ });
61
43
  }
62
44
 
63
45
  const { sourceUsername } = await this.prompt({
@@ -86,7 +68,7 @@ export default async (vorpal: Vorpal) =>
86
68
  type: "input",
87
69
  name: "targetInstance",
88
70
 
89
- message: "Targe INSTANCE (connection string or 'local')? 🤔 ",
71
+ message: "Target INSTANCE (connection string or 'local')? 🤔 ",
90
72
  });
91
73
 
92
74
  if (targetInstance === "local") {
@@ -100,7 +82,10 @@ export default async (vorpal: Vorpal) =>
100
82
  targetPort = targetLocalPort;
101
83
  } else {
102
84
  targetPort = 54499;
103
- targetProxy = await createProxy(targetInstance, targetPort);
85
+ targetProxy = await startCloudSqlProxyInBackground({
86
+ instanceName: targetInstance,
87
+ localPort: targetPort,
88
+ });
104
89
  }
105
90
 
106
91
  const { targetUsername } = await this.prompt({
@@ -3,7 +3,6 @@ import {
3
3
  createKubernetesCloudsqlBaseValues,
4
4
  isOfDeployType,
5
5
  } from "@catladder/pipeline";
6
- import { spawn } from "child-process-promise";
7
6
  import type Vorpal from "vorpal";
8
7
  import type { CommandInstance } from "vorpal";
9
8
  import {
@@ -12,6 +11,7 @@ import {
12
11
  parseChoice,
13
12
  } from "../../../../config/getProjectConfig";
14
13
  import { envAndComponents } from "./utils/autocompletions";
14
+ import { startCloudSqlProxyInCurrentShell } from "../../../../gcloud/cloudSql/startProxy";
15
15
 
16
16
  type ProxyInfo = {
17
17
  instanceName: string;
@@ -70,14 +70,11 @@ export default async (vorpal: Vorpal) =>
70
70
  `DATABASE_JDBC_URL=jdbc:postgresql://localhost:${localPort}/${DB_NAME}?schema=public&user=${DB_USER}&password=${DB_PASSWORD}`
71
71
  );
72
72
  this.log("");
73
- await spawn(
74
- "cloud_sql_proxy",
75
- ["-instances", `${instanceName}=tcp:${localPort}`],
76
- {
77
- stdio: "inherit",
78
- shell: true,
79
- }
80
- );
73
+
74
+ await startCloudSqlProxyInCurrentShell({
75
+ instanceName,
76
+ localPort,
77
+ });
81
78
  });
82
79
 
83
80
  const getProxyInfoForKubernetes = async (
@@ -0,0 +1,74 @@
1
+ import { spawn } from "child-process-promise";
2
+ import commandExists from "command-exists-promise";
3
+
4
+ export const ERROR_NOT_INSTALLED = "cloud-sql-proxy not installed";
5
+
6
+ export type CloudSqlBackgroundProxy = {
7
+ stop: () => void;
8
+ };
9
+
10
+ export type CloudSqlProxyOptions = {
11
+ instanceName: string;
12
+ localPort: number;
13
+ };
14
+
15
+ const getProxyCommandSpawnArgs = async ({
16
+ localPort,
17
+ instanceName,
18
+ }: CloudSqlProxyOptions) => {
19
+ const commandString = (await commandExists("cloud-sql-proxy"))
20
+ ? `cloud-sql-proxy --port ${localPort} ${instanceName}`
21
+ : (await commandExists(
22
+ "cloud_sql_proxy" // v1
23
+ ))
24
+ ? `cloud_sql_proxy -instances ${instanceName}=tcp:${localPort}`
25
+ : null;
26
+ if (!commandString) {
27
+ throw new Error(ERROR_NOT_INSTALLED);
28
+ }
29
+
30
+ const [cmd, ...args] = commandString.split(" ");
31
+ return { cmd, args };
32
+ };
33
+
34
+ export const startCloudSqlProxyInCurrentShell = async (
35
+ opts: CloudSqlProxyOptions
36
+ ) => {
37
+ const { cmd, args } = await getProxyCommandSpawnArgs(opts);
38
+
39
+ await spawn(cmd, args, {
40
+ stdio: "inherit",
41
+ shell: true,
42
+ });
43
+ };
44
+
45
+ export const startCloudSqlProxyInBackground = async (
46
+ opts: CloudSqlProxyOptions
47
+ ): Promise<CloudSqlBackgroundProxy> => {
48
+ const { cmd, args } = await getProxyCommandSpawnArgs(opts);
49
+
50
+ const proxyPromise = spawn(cmd, args, { shell: "bash" });
51
+
52
+ // wait until it starts
53
+ await spawn(
54
+ `echo -n "Waiting for proxy"
55
+ until echo > /dev/tcp/localhost/${opts.localPort}; do
56
+ sleep 0.2
57
+ echo -n "."
58
+ done 2>/dev/null`,
59
+ [],
60
+ { shell: "bash" }
61
+ );
62
+ const stop = () => {
63
+ proxyPromise.catch(() => {
64
+ // ignore
65
+ });
66
+ proxyPromise.childProcess.kill();
67
+ };
68
+ // stop if catladder i stopped
69
+ process.on("beforeExit", stop);
70
+
71
+ return {
72
+ stop,
73
+ };
74
+ };
@@ -13,7 +13,7 @@ declare module "child-process-promise" {
13
13
  type Stdio = "inherit" | "pipe";
14
14
  type SpawnOptions = {
15
15
  stdio?: Stdio | Stdio[];
16
- shell?: boolean;
16
+ shell?: boolean | string;
17
17
  env?: Record<string, string>;
18
18
  };
19
19
 
@@ -31,6 +31,7 @@ declare module "child-process-promise" {
31
31
  ): Promise<unknown> & {
32
32
  childProcess: {
33
33
  stdout: ReadStream;
34
+ kill: () => void;
34
35
  };
35
36
  };
36
37
  }