Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/plugins/status-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { commands, QuickPickItemKind, ThemeColor, window } from "vscode";
import type { QuickPickItem } from "vscode";

import { createPlugin } from "../plugins.ts";
import { checkLocalstackInstalled } from "../utils/install.ts";

export default createPlugin(
"status-bar",
Expand Down
35 changes: 0 additions & 35 deletions src/utils/exec.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,4 @@
import * as childProcess from "node:child_process";
import * as util from "node:util";

// import { appendToEnvPath } from "./env-path.ts";

export const COMMAND_NOT_FOUND_EXIT_CODE = 127;

export const exec = util.promisify(childProcess.exec);

// const execAsync = util.promisify(childProcess.exec);

// export const exec = (command: string, options?: childProcess.ExecOptions) => {
// return execAsync(command, {
// env: {
// ...options?.env,
// //
// PATH: appendToEnvPath(options?.env.PATH ?? "", ""),
// },
// ...options,
// });
// };

export interface ExecException extends Error {
cmd: string;
code: number;
stdout: string;
stderr: string;
}

export function isExecException(error: unknown): error is ExecException {
return (
typeof error === "object" &&
error !== null &&
"code" in error &&
"cmd" in error &&
"stderr" in error &&
"stdout" in error
);
}
74 changes: 3 additions & 71 deletions src/utils/manage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,13 @@ import type { ExtensionContext, LogOutputChannel, MessageItem } from "vscode";
import { commands, env, Uri, window } from "vscode";

import { spawnLocalStack } from "./cli.ts";
import { exec } from "./exec.ts";
import { checkIsLicenseValid } from "./license.ts";
import type { Telemetry } from "./telemetry.ts";

export type LocalstackStatus = "running" | "starting" | "stopping" | "stopped";

let previousStatus: LocalstackStatus | undefined;

export async function fetchHealth(): Promise<boolean> {
// health is ok in the majority of use cases, however, determining status based on it can be flaky.
// for example, if localstack becomes unhealthy while running for reasons other that stop then reporting "stopping" may be misleading.
// though we don't know if it happens often.
// Health is OK in the majority of use cases, however, determining status based on it can be flaky.
// For example, if localstack becomes unhealthy while running for reasons other than the stop,
// then reporting "stopping" may be misleading.
try {
const response = await fetch("http://127.0.0.1:4566/_localstack/health");
return response.ok;
Expand All @@ -38,50 +33,6 @@ async function fetchLocalStackSessionId(): Promise<string> {
return "";
}

async function getStatusFromCLI(): Promise<LocalstackStatus | undefined> {
try {
const result = await exec(
"docker inspect -f '{{.State.Status}}' localstack-main",
);
if (result.stdout.includes("running")) {
return "running";
} else if (result.stdout.includes("stopped")) {
return "stopped";
}
} catch {
return undefined;
}
}

export async function getLocalstackStatus(): Promise<LocalstackStatus> {
const [healthOk, status] = await Promise.all([
fetchHealth(),
getStatusFromCLI(),
]);

if (healthOk && status === "running") {
previousStatus = "running";
return "running";
}

if (!healthOk && status !== "running") {
previousStatus = "stopped";
return "stopped";
}

if (previousStatus === "stopped" && !healthOk && status === "running") {
previousStatus = "starting";
return "starting";
}

if (previousStatus === "running" && !healthOk) {
previousStatus = "stopping";
return "stopping";
}

return previousStatus ?? "stopped";
}

export async function startLocalStack(
outputChannel: LogOutputChannel,
telemetry: Telemetry,
Expand Down Expand Up @@ -226,25 +177,6 @@ async function showErrorMessage(
}
}

export async function getLocalstackVersion(
outputChannel: LogOutputChannel,
): Promise<string | undefined> {
try {
const { stdout } = await exec("localstack --version");
const versionMatch = stdout.match(/\d+\.\d+\.\d+/);
if (!versionMatch) {
outputChannel.error(
`Failed to parse LocalStack from version output: ${stdout}`,
);
return undefined;
}

return versionMatch[0];
} catch {
return undefined;
}
}

// Checks for session_id in workspaceState, creates if missing
export async function getOrCreateExtensionSessionId(
context: ExtensionContext,
Expand Down
41 changes: 0 additions & 41 deletions src/utils/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,6 @@ import type { CancellationToken, LogOutputChannel } from "vscode";

import { spawn, SpawnError } from "./spawn.ts";

export interface DarwinPromptOptions {
message: string;
title: string;
icon: "note";
buttons: string[];
outputChannel: LogOutputChannel;
outputLabel?: string;
cancellationToken?: CancellationToken;
}

export async function darwinPrompt(
options: DarwinPromptOptions,
): Promise<{ cancelled: boolean }> {
try {
await spawn(
"osascript",
[
"-e",
`'display dialog ${JSON.stringify(options.message)} with title ${JSON.stringify(options.title)} with icon ${options.icon} buttons {${options.buttons.map((button) => JSON.stringify(button)).join(",")}} default button 1'`,
],
{
outputChannel: options.outputChannel,
outputLabel: options.outputLabel,
cancellationToken: options.cancellationToken,
},
);
return {
cancelled: false,
};
} catch (error) {
options.outputChannel.error(error instanceof Error ? error : String(error));

// osascript will terminate with code 1 if the user cancels the dialog.
if (error instanceof SpawnError && error.code === 1) {
return { cancelled: true };
}

throw error;
}
}

export interface SpawnElevatedDarwinOptions {
script: string;
outputChannel: LogOutputChannel;
Expand Down
Loading