Skip to content

Commit db34c82

Browse files
committed
feat: load .env files for env subcommand
1 parent 41f2496 commit db34c82

4 files changed

Lines changed: 56 additions & 4 deletions

File tree

deno.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"@cfa/gitignore-parser": "jsr:@cfa/gitignore-parser@^0.1.4",
77
"@cliffy/command": "jsr:@cliffy/command@^1.0.0-rc.8",
88
"@std/cli": "jsr:@std/cli@1.0.21",
9+
"@std/dotenv": "jsr:@std/dotenv@^0.225.5",
910
"@std/encoding": "jsr:@std/encoding@^1.0.8",
1011
"@std/fmt": "jsr:@std/fmt@^1.0.8",
1112
"@std/fs": "jsr:@std/fs@^1.0.14",

deno.lock

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

env.ts

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Command } from "@cliffy/command";
2+
import { parse as dotEnvParse } from "@std/dotenv";
23
import { getAppFromConfig, readConfig } from "./config.ts";
34
import { error, withApp } from "./util.ts";
45
import { createTrpcClient } from "./auth.ts";
@@ -103,7 +104,7 @@ export const envListCommand = new Command<EnvCommandContext>()
103104
export const envAddCommand = new Command<EnvCommandContext>()
104105
.description("Add an environmental variable to the application")
105106
.option("--secret", "If the value should be secret", { default: false })
106-
.arguments("variable:string value:string")
107+
.arguments("<variable:string> <value:string>")
107108
.action(async (options, variable, value) => {
108109
const configContent = await readConfig(Deno.cwd());
109110
let { org, app } = getAppFromConfig(configContent);
@@ -144,7 +145,7 @@ export const envUpdateValueCommand = new Command<EnvCommandContext>()
144145
.description(
145146
"Update the value of an environmental variable in the application",
146147
)
147-
.arguments("variable:string value:string")
148+
.arguments("<variable:string> <value:string>")
148149
.action(async (options, variable, value) => {
149150
const configContent = await readConfig(Deno.cwd());
150151
let { org, app } = getAppFromConfig(configContent);
@@ -188,7 +189,7 @@ export const envUpdateContextsCommand = new Command<EnvCommandContext>()
188189
`Update the contexts of an environmental variable in the application
189190
You can define no contexts, which is the equivalent to "All"`,
190191
)
191-
.arguments("variable:string [new-contexts...:string]")
192+
.arguments("<variable:string> [new-contexts...:string]")
192193
.action(async (options, variable, ...newContexts) => {
193194
const configContent = await readConfig(Deno.cwd());
194195
let { org, app } = getAppFromConfig(configContent);
@@ -282,3 +283,46 @@ export const envDeleteCommand = new Command<EnvCommandContext>()
282283
`Environmental variable '${variable}' has been successfully deleted`,
283284
);
284285
});
286+
287+
export const envLoadCommand = new Command<EnvCommandContext>()
288+
.description(
289+
"Load environmental variables from a .env file into the application",
290+
)
291+
.option(
292+
"--secrets <keys...:string>",
293+
"Which keys in the .env file to treat as secrets",
294+
)
295+
.arguments("<file:string>")
296+
.action(async (options, file) => {
297+
const configContent = await readConfig(Deno.cwd());
298+
let { org, app } = getAppFromConfig(configContent);
299+
org ??= options.org;
300+
app ??= options.app;
301+
302+
const orgAndApp = await withApp(options.endpoint, false, org, app);
303+
const trpcClient = createTrpcClient(options.endpoint);
304+
305+
// deno-lint-ignore no-explicit-any
306+
const fullApp = await (trpcClient.apps as any).get.query({
307+
org: orgAndApp.org,
308+
app: orgAndApp.app,
309+
});
310+
311+
const variables = dotEnvParse(await Deno.readTextFile(file));
312+
313+
// deno-lint-ignore no-explicit-any
314+
await (trpcClient.envVarsContexts as any).updateEnvVars.mutate({
315+
org: orgAndApp.org,
316+
add: Object.entries(variables).map(([key, value]) => ({
317+
app_id: fullApp.id,
318+
key,
319+
value,
320+
is_secret: options.secrets?.includes(key) ?? false,
321+
context_ids: null,
322+
})),
323+
update: [],
324+
remove: [],
325+
});
326+
327+
console.log(`.env file '${file}' has been successfully loaded.`);
328+
});

main.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
envAddCommand,
1111
envDeleteCommand,
1212
envListCommand,
13+
envLoadCommand,
1314
envUpdateContextsCommand,
1415
envUpdateValueCommand,
1516
} from "./env.ts";
@@ -121,7 +122,8 @@ const envCommand = new Command<{ endpoint: string }>()
121122
.command("add", envAddCommand)
122123
.command("update-value", envUpdateValueCommand)
123124
.command("update-contexts", envUpdateContextsCommand)
124-
.command("delete", envDeleteCommand);
125+
.command("delete", envDeleteCommand)
126+
.command("load", envLoadCommand);
125127

126128
const logsCommand = new Command<{ endpoint: string }>()
127129
.description("Stream logs from an application")

0 commit comments

Comments
 (0)