Skip to content

Commit 2ecee5e

Browse files
committed
Added the useful ability to kill the previous codify connect so you don't have to go find it
1 parent 989cad3 commit 2ecee5e

File tree

9 files changed

+97
-19
lines changed

9 files changed

+97
-19
lines changed

package-lock.json

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

package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"@types/jju": "^1.4.5",
5858
"@types/js-yaml": "^4.0.9",
5959
"@types/json5": "^2.2.0",
60+
"@types/kill-port": "^2.0.3",
6061
"@types/mocha": "^10.0.10",
6162
"@types/node": "^20",
6263
"@types/react": "^18.3.1",
@@ -73,6 +74,7 @@
7374
"eslint-config-oclif-typescript": "^3.1.13",
7475
"eslint-config-prettier": "^9.0.0",
7576
"ink-testing-library": "^4.0.0",
77+
"kill-port": "^2.0.1",
7678
"memfs": "^4.14.0",
7779
"mocha": "^10",
7880
"oclif": "^4.15.29",
@@ -106,8 +108,12 @@
106108
"bin": "codify",
107109
"dirname": "codify",
108110
"commands": "./dist/commands",
109-
"additionalVersionFlags": ["-v"],
110-
"additionalHelpFlags": ["-h"],
111+
"additionalVersionFlags": [
112+
"-v"
113+
],
114+
"additionalHelpFlags": [
115+
"-h"
116+
],
111117
"defaultCommand": "edit",
112118
"plugins": [
113119
"@oclif/plugin-help",

src/commands/connect.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ For more information, visit: https://docs.codifycli.com/commands/validate
1919
const { flags } = await this.parse(Connect)
2020
const config = this.config;
2121

22-
await ConnectOrchestrator.run(config);
22+
await ConnectOrchestrator.run(config, this.reporter);
2323
}
2424
}

src/commands/edit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ For more information, visit: https://docs.codifycli.com/commands/validate
2121
const { flags } = await this.parse(Edit);
2222
const config = this.config;
2323

24-
await EditOrchestrator.run(config);
24+
await EditOrchestrator.run(config, this.reporter);
2525

2626
}
2727
}

src/events/context.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export enum ProcessName {
2828
IMPORT = 'import',
2929
REFRESH = 'refresh',
3030
INIT = 'init',
31+
TERMINATE = 'terminate',
3132
}
3233

3334
export enum SubProcessName {

src/orchestrators/connect.ts

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
import { Config } from '@oclif/core';
22
import cors from 'cors';
33
import express, { json } from 'express';
4+
import killPort from 'kill-port';
45
import { randomBytes } from 'node:crypto';
6+
import { Server } from 'node:http';
57
import open from 'open';
68

79
import { config } from '../config.js';
810
import router from '../connect/http-routes/router.js';
911
import { LoginHelper } from '../connect/login-helper.js';
1012
import { SocketServer } from '../connect/socket-server.js';
13+
import { ProcessName, ctx } from '../events/context.js';
14+
import { Reporter } from '../ui/reporters/reporter.js';
1115
import { LoginOrchestrator } from './login.js';
1216

1317
export class ConnectOrchestrator {
1418
static rootCommand: string;
1519
static nodeBinary: string;
1620

17-
static async run(oclifConfig: Config, openBrowser = true, onOpen?: (connectionCode: string) => void) {
21+
static async run(oclifConfig: Config, reporter: Reporter, openBrowser = true, onOpen?: (connectionCode: string) => void) {
1822
const login = LoginHelper.get()?.isLoggedIn;
1923
if (!login) {
20-
console.log('User is not logged in. Attempting to log in...')
24+
ctx.log('User is not logged in. Attempting to log in...')
2125
await LoginOrchestrator.run();
2226
}
2327

@@ -31,16 +35,7 @@ export class ConnectOrchestrator {
3135
app.use(json())
3236
app.use(router);
3337

34-
const server = app.listen(config.connectServerPort, (error) => {
35-
if (error) {
36-
if (error.message.includes('EADDRINUSE')) {
37-
console.error('An instance of \'codify connect\' is already running.\n\nExiting...')
38-
return;
39-
}
40-
41-
throw error;
42-
}
43-
38+
const server = await ConnectOrchestrator.listen(app, reporter, () => {
4439
if (openBrowser) {
4540
open(`${config.dashboardUrl}/connection/success?code=${connectionSecret}`)
4641
console.log(`Open browser window to store code.
@@ -55,6 +50,38 @@ ${connectionSecret}`)
5550
SocketServer.init(server, connectionSecret);
5651
}
5752

53+
private static listen(app: express.Application, reporter: Reporter, onOpen: () => void): Promise<Server> {
54+
return new Promise((resolve) => {
55+
const server = app.listen(config.connectServerPort, async (error) => {
56+
if (error) {
57+
if (error.message.includes('EADDRINUSE')) {
58+
const ifTerminate = await reporter.promptConfirmation('An instance of \'codify connect\' is already running. Do you want to terminate the existing instance and continue?');
59+
60+
if (!ifTerminate) {
61+
console.error('\n\nExiting...')
62+
process.exit(1);
63+
}
64+
65+
ctx.processStarted(ProcessName.TERMINATE)
66+
await reporter.displayProgress();
67+
await killPort(config.connectServerPort);
68+
ctx.processFinished(ProcessName.TERMINATE);
69+
await reporter.hide();
70+
71+
setTimeout(() => {
72+
ctx.log('Retrying connection...')
73+
ConnectOrchestrator.listen(app, reporter, onOpen).then((server) => resolve(server));
74+
}, 300);
75+
76+
}
77+
} else {
78+
resolve(server);
79+
onOpen();
80+
}
81+
});
82+
});
83+
}
84+
5885
private static tokenGenerate(bytes = 4): string {
5986
return Buffer.from(randomBytes(bytes)).toString('hex')
6087
}

src/orchestrators/edit.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ import open from 'open';
44
import { DashboardApiClient } from '../api/dashboard/index.js';
55
import { config } from '../config.js';
66
import { LoginHelper } from '../connect/login-helper.js';
7+
import { Reporter } from '../ui/reporters/reporter.js';
78
import { ConnectOrchestrator } from './connect.js';
89
import { LoginOrchestrator } from './login.js';
910

1011
export class EditOrchestrator {
1112

12-
static async run(oclifConfig: Config) {
13+
static async run(oclifConfig: Config, reporter: Reporter) {
1314
const login = LoginHelper.get()?.isLoggedIn;
1415
if (!login) {
1516
console.log('User is not logged in. Attempting to log in...')
@@ -24,10 +25,10 @@ export class EditOrchestrator {
2425
}
2526

2627
const url = defaultDocumentId
27-
? `${config.dashboardUrl}/file/${defaultDocumentId}`
28+
? `${config.dashboardUrl}/document/${defaultDocumentId}`
2829
: config.dashboardUrl;
2930

30-
await ConnectOrchestrator.run(oclifConfig, false, (code) => {
31+
await ConnectOrchestrator.run(oclifConfig, reporter, false, (code) => {
3132
open(`${url}?connection_code=${code}`);
3233
console.log(
3334
`Opening default Codify file:

src/ui/reporters/default-reporter.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const ProgressLabelMapping = {
2525
[ProcessName.REFRESH]: 'Codify refresh',
2626
[ProcessName.IMPORT]: 'Codify import',
2727
[ProcessName.INIT]: 'Codify init',
28+
[ProcessName.TERMINATE]: 'Attempting to terminate existing instance',
2829
[SubProcessName.APPLYING_RESOURCE]: 'Applying resource',
2930
[SubProcessName.GENERATE_PLAN]: 'Refresh states and generating plan',
3031
[SubProcessName.INITIALIZE_PLUGINS]: 'Initializing plugins',

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"moduleResolution": "NodeNext",
55
"esModuleInterop": true,
66
"resolveJsonModule": true,
7+
"allowSyntheticDefaultImports": true,
78
"jsx": "react",
89
"outDir": "dist",
910
"rootDir": "src",

0 commit comments

Comments
 (0)