Skip to content

Commit 90576e1

Browse files
committed
better config file detection and creation
1 parent c73d042 commit 90576e1

5 files changed

Lines changed: 60 additions & 32 deletions

File tree

config.ts

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { join } from "@std/path";
1+
import { dirname, join } from "@std/path";
22
import {
33
applyEdits as applyJSONCEdits,
44
modify as modifyJSONC,
@@ -10,24 +10,44 @@ export interface Config {
1010
content: string;
1111
}
1212

13-
export async function readConfig(rootPath: string): Promise<Config | null> {
14-
try {
15-
const path = join(rootPath, "deno.json");
16-
const content = await Deno.readTextFile(path);
17-
return { path, content };
18-
} catch (e) {
19-
if (!(e instanceof Deno.errors.NotFound)) {
20-
throw e;
21-
}
13+
export async function readConfig(
14+
rootPath: string,
15+
maybeConfigPath: string | undefined,
16+
): Promise<Config | null> {
17+
if (maybeConfigPath) {
18+
const content = await Deno.readTextFile(maybeConfigPath);
19+
return { path: maybeConfigPath, content };
2220
}
2321

24-
try {
25-
const path = join(rootPath, "deno.jsonc");
26-
const content = await Deno.readTextFile(path);
27-
return { path, content };
28-
} catch (e) {
29-
if (!(e instanceof Deno.errors.NotFound)) {
30-
throw e;
22+
let currentDir = rootPath;
23+
24+
while (true) {
25+
try {
26+
const path = join(currentDir, "deno.json");
27+
const content = await Deno.readTextFile(path);
28+
return { path, content };
29+
} catch (e) {
30+
if (!(e instanceof Deno.errors.NotFound)) {
31+
throw e;
32+
}
33+
}
34+
35+
try {
36+
const path = join(currentDir, "deno.jsonc");
37+
const content = await Deno.readTextFile(path);
38+
return { path, content };
39+
} catch (e) {
40+
if (!(e instanceof Deno.errors.NotFound)) {
41+
throw e;
42+
}
43+
}
44+
45+
const parentDir = dirname(currentDir);
46+
47+
if (parentDir == currentDir) {
48+
break;
49+
} else {
50+
currentDir = parentDir;
3151
}
3252
}
3353

@@ -59,7 +79,6 @@ export function getAppFromConfig(
5979

6080
export async function writeConfig(
6181
configContent: Config | null,
62-
rootPath: string,
6382
org: string,
6483
app: string,
6584
) {
@@ -75,7 +94,13 @@ export async function writeConfig(
7594
});
7695
const out = applyJSONCEdits(content, edits);
7796
await Deno.writeTextFile(
78-
configContent?.path ?? join(rootPath, "deno.jsonc"),
97+
configContent?.path ?? join(Deno.cwd(), "deno.jsonc"),
7998
out,
8099
);
100+
101+
if (!configContent) {
102+
console.log(
103+
`Created configuration file at '${join(Deno.cwd(), "deno.jsonc")}'`,
104+
);
105+
}
81106
}

deno.lock

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

env.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type EnvCommandContext = GlobalOptions & {
2525
export const envListCommand = new Command<EnvCommandContext>()
2626
.description("List all environmental variables in an application")
2727
.action(async (options) => {
28-
const configContent = await readConfig(Deno.cwd());
28+
const configContent = await readConfig(Deno.cwd(), options.config);
2929
let { org, app } = getAppFromConfig(configContent);
3030
org ??= options.org;
3131
app ??= options.app;
@@ -112,7 +112,7 @@ export const envAddCommand = new Command<EnvCommandContext>()
112112
.option("--secret", "If the value should be secret", { default: false })
113113
.arguments("<variable:string> <value:string>")
114114
.action(async (options, variable, value) => {
115-
const configContent = await readConfig(Deno.cwd());
115+
const configContent = await readConfig(Deno.cwd(), options.config);
116116
let { org, app } = getAppFromConfig(configContent);
117117
org ??= options.org;
118118
app ??= options.app;
@@ -159,7 +159,7 @@ export const envUpdateValueCommand = new Command<EnvCommandContext>()
159159
)
160160
.arguments("<variable:string> <value:string>")
161161
.action(async (options, variable, value) => {
162-
const configContent = await readConfig(Deno.cwd());
162+
const configContent = await readConfig(Deno.cwd(), options.config);
163163
let { org, app } = getAppFromConfig(configContent);
164164
org ??= options.org;
165165
app ??= options.app;
@@ -209,7 +209,7 @@ You can define no contexts, which is the equivalent to "All"`,
209209
)
210210
.arguments("<variable:string> [new-contexts...:string]")
211211
.action(async (options, variable, ...newContexts) => {
212-
const configContent = await readConfig(Deno.cwd());
212+
const configContent = await readConfig(Deno.cwd(), options.config);
213213
let { org, app } = getAppFromConfig(configContent);
214214
org ??= options.org;
215215
app ??= options.app;
@@ -274,7 +274,7 @@ export const envDeleteCommand = new Command<EnvCommandContext>()
274274
.description("Delete an environmental variable in the application")
275275
.arguments("variable:string")
276276
.action(async (options, variable) => {
277-
const configContent = await readConfig(Deno.cwd());
277+
const configContent = await readConfig(Deno.cwd(), options.config);
278278
let { org, app } = getAppFromConfig(configContent);
279279
org ??= options.org;
280280
app ??= options.app;
@@ -324,7 +324,7 @@ export const envLoadCommand = new Command<EnvCommandContext>()
324324
)
325325
.arguments("<file:string>")
326326
.action(async (options, file) => {
327-
const configContent = await readConfig(Deno.cwd());
327+
const configContent = await readConfig(Deno.cwd(), options.config);
328328
let { org, app } = getAppFromConfig(configContent);
329329
org ??= options.org;
330330
app ??= options.app;

main.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export type GlobalOptions = {
3434
debug: boolean;
3535
endpoint: string;
3636
token: string | undefined;
37+
config: string | undefined;
3738
};
3839

3940
const createCommand = new Command<GlobalOptions>()
@@ -45,10 +46,10 @@ const createCommand = new Command<GlobalOptions>()
4546
.arguments("[root-path:string]")
4647
.action(
4748
async (
48-
{ debug, endpoint, org: initOrg },
49+
{ debug, endpoint, org: initOrg, config },
4950
rootPath = Deno.cwd(),
5051
) => {
51-
const configContent = await readConfig(rootPath);
52+
const configContent = await readConfig(rootPath, config);
5253
const { org, app } = getAppFromConfig(configContent);
5354
if (org || app) {
5455
console.log(
@@ -127,7 +128,7 @@ const tunnelLoginCommand = new Command<GlobalOptions>()
127128
.arguments("[root-path:string]")
128129
.hidden()
129130
.action(async (options, rootPath = Deno.cwd()) => {
130-
const configContent = await readConfig(rootPath);
131+
const configContent = await readConfig(rootPath, options.config);
131132
const { org, app } = getAppFromConfig(configContent);
132133
const gottenApp = await withApp(
133134
options.debug,
@@ -136,7 +137,7 @@ const tunnelLoginCommand = new Command<GlobalOptions>()
136137
org,
137138
app,
138139
);
139-
await writeConfig(configContent, rootPath, gottenApp.org, gottenApp.app);
140+
await writeConfig(configContent, gottenApp.org, gottenApp.app);
140141
});
141142

142143
const envCommand = new Command<GlobalOptions>()
@@ -162,7 +163,7 @@ const logsCommand = new Command<GlobalOptions>()
162163
depends: ["start"],
163164
})
164165
.action(async (options, rootPath = Deno.cwd()) => {
165-
const configContent = await readConfig(rootPath);
166+
const configContent = await readConfig(rootPath, options.config);
166167
let { org, app } = getAppFromConfig(configContent);
167168
org ??= options.org;
168169
app ??= options.app;
@@ -268,6 +269,7 @@ deploy your local directory to the specified application.`)
268269
default: false,
269270
})
270271
.globalOption("--token <token:string>", "Auth token to use")
272+
.globalOption("--config <config:string>", "Path for the config file")
271273
.option("--org <name:string>", "The name of the organization")
272274
.option("--app <name:string>", "The name of the application")
273275
.option("--prod", "Deploy directly to production")
@@ -287,7 +289,7 @@ deploy your local directory to the specified application.`)
287289
options,
288290
rootPath = Deno.cwd(),
289291
) => {
290-
const configContent = await readConfig(rootPath);
292+
const configContent = await readConfig(rootPath, options.config);
291293
let { org, app } = getAppFromConfig(configContent);
292294
org ??= options.org;
293295
app ??= options.app;

publish.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,5 +314,5 @@ export async function publish(
314314
);
315315
}
316316

317-
await writeConfig(configContent, rootPath, org, app);
317+
await writeConfig(configContent, org, app);
318318
}

0 commit comments

Comments
 (0)