Skip to content

Commit e909558

Browse files
authored
feat: use file watchers to track some setup statuses (#47)
Setup statuses for LS CLI authentication and AWS profile configuration are now checked via file watchers instead of periodic checks. It's still pending to improve the algorithm that checks for both the LS CLI installation and the LS CLI license.
1 parent b3befcf commit e909558

File tree

8 files changed

+308
-80
lines changed

8 files changed

+308
-80
lines changed

package-lock.json

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

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@
110110
"package": "node build/extension.mjs --production",
111111
"pretest": "npm run compile",
112112
"check-types": "tsc",
113-
"lint": "eslint .",
113+
"lint": "eslint",
114+
"format": "biome check",
114115
"test": "vscode-test",
115116
"compile:font": "node build/icon-font.mjs"
116117
},
@@ -126,6 +127,7 @@
126127
"@vscode/test-cli": "^0.0.11",
127128
"@vscode/test-electron": "^2.5.2",
128129
"@vscode/vsce": "^3.6.0",
130+
"chokidar": "^4.0.3",
129131
"esbuild": "^0.25.9",
130132
"eslint": "^9.35.0",
131133
"eslint-plugin-import": "^2.32.0",

src/utils/authenticate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ async function redirectToLocalStack(): Promise<{ cancelled: boolean }> {
8484
return { cancelled: !openSuccessful };
8585
}
8686

87-
const LOCALSTACK_AUTH_FILENAME = `${os.homedir()}/.localstack/auth.json`;
87+
export const LOCALSTACK_AUTH_FILENAME = `${os.homedir()}/.localstack/auth.json`;
8888
const LOCALSTACK_AUTH_FILENAME_READABLE = LOCALSTACK_AUTH_FILENAME.replace(
8989
`${os.homedir()}/`,
9090
"~/",

src/utils/configure-aws.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ const LOCALSTACK_CREDENTIALS_PROPERTIES = {
3535
aws_secret_access_key: "test",
3636
};
3737

38-
const AWS_DIRECTORY = path.join(os.homedir(), ".aws");
38+
export const AWS_DIRECTORY = path.join(os.homedir(), ".aws");
39+
export const AWS_CONFIG_FILENAME = path.join(AWS_DIRECTORY, "config");
40+
export const AWS_CREDENTIALS_FILENAME = path.join(AWS_DIRECTORY, "credentials");
3941

4042
async function overrideSelection(
4143
filesToModify: string[],
@@ -464,13 +466,13 @@ export async function configureAwsProfiles(options: {
464466

465467
export async function checkIsProfileConfigured(): Promise<boolean> {
466468
try {
467-
const awsConfigFilename = path.join(AWS_DIRECTORY, "config");
468-
const awsCredentialsFilename = path.join(AWS_DIRECTORY, "credentials");
469-
470469
const [{ section: configSection }, { section: credentialsSection }] =
471470
await Promise.all([
472-
getProfile(awsConfigFilename, LOCALSTACK_CONFIG_PROFILE_NAME),
473-
getProfile(awsCredentialsFilename, LOCALSTACK_CREDENTIALS_PROFILE_NAME),
471+
getProfile(AWS_CONFIG_FILENAME, LOCALSTACK_CONFIG_PROFILE_NAME),
472+
getProfile(
473+
AWS_CREDENTIALS_FILENAME,
474+
LOCALSTACK_CREDENTIALS_PROFILE_NAME,
475+
),
474476
]);
475477

476478
const [configNeedsOverride, credentialsNeedsOverride] = await Promise.all([

src/utils/immediate-once.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Creates a function that calls the given callback immediately once.
3+
*
4+
* Multiple calls during the same tick are ignored.
5+
*
6+
* @param callback - The callback to call.
7+
* @returns A function that calls the callback immediately once.
8+
*/
9+
export function immediateOnce<T>(callback: () => T): () => void {
10+
let timeout: NodeJS.Immediate | undefined;
11+
12+
return () => {
13+
if (timeout) {
14+
return;
15+
}
16+
17+
timeout = setImmediate(() => {
18+
void Promise.resolve(callback()).finally(() => {
19+
timeout = undefined;
20+
});
21+
});
22+
};
23+
}

src/utils/license.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,36 @@
1+
import { homedir, platform } from "node:os";
2+
import { join } from "node:path";
3+
14
import type { CancellationToken, LogOutputChannel } from "vscode";
25

36
import { execLocalStack } from "./cli.ts";
47

8+
/**
9+
* See https://github.com/localstack/localstack/blob/de861e1f656a52eaa090b061bd44fc1a7069715e/localstack-core/localstack/utils/files.py#L38-L55.
10+
* @returns The cache directory for the current platform.
11+
*/
12+
const cacheDirectory = () => {
13+
switch (platform()) {
14+
case "win32":
15+
return join(process.env.LOCALAPPDATA!, "cache");
16+
case "darwin":
17+
return join(homedir(), "Library", "Caches");
18+
default:
19+
return process.env.XDG_CACHE_HOME ?? join(homedir(), ".cache");
20+
}
21+
};
22+
23+
/**
24+
* The file that contains the license information of the LocalStack CLI.
25+
*
26+
* The license file is stored in the cache directory for the current platform.
27+
*/
28+
export const LICENSE_FILENAME = join(
29+
cacheDirectory(),
30+
"localstack-cli",
31+
"license.json",
32+
);
33+
534
const LICENSE_VALIDITY_MARKER = "license validity: valid";
635

736
export async function checkIsLicenseValid(outputChannel: LogOutputChannel) {

0 commit comments

Comments
 (0)