1
+ import * as fs from "fs-extra"
2
+ import yaml from "js-yaml"
1
3
import * as path from "path"
2
4
import { field , logger , Level } from "@coder/logger"
3
5
import { Args as VsArgs } from "../../lib/vscode/src/vs/server/ipc"
4
6
import { AuthType } from "./http"
5
7
import { xdgLocalDir } from "./util"
8
+ import xdgBasedir from "xdg-basedir"
6
9
7
10
export class Optional < T > {
8
11
public constructor ( public readonly value ?: T ) { }
@@ -19,6 +22,7 @@ export enum LogLevel {
19
22
export class OptionalString extends Optional < string > { }
20
23
21
24
export interface Args extends VsArgs {
25
+ readonly config ?: string
22
26
readonly auth ?: AuthType
23
27
readonly cert ?: OptionalString
24
28
readonly "cert-key" ?: string
@@ -95,6 +99,8 @@ const options: Options<Required<Args>> = {
95
99
96
100
"bind-addr" : { type : "string" , description : "Address to bind to in host:port." } ,
97
101
102
+ config : { type : "string" , description : "Path to yaml config file." } ,
103
+
98
104
// These two have been deprecated by bindAddr.
99
105
host : { type : "string" , description : "" } ,
100
106
port : { type : "number" , description : "" } ,
@@ -275,3 +281,47 @@ export const parse = (argv: string[]): Args => {
275
281
276
282
return args
277
283
}
284
+
285
+ // readConfigFile reads the config file specified in the config flag
286
+ // and loads it's configuration.
287
+ //
288
+ // Flags set on the CLI take priority.
289
+ //
290
+ // The config file can also be passed via $CODE_SERVER_CONFIG and defaults
291
+ // to ~/.config/code-server/config.yaml.
292
+ export async function readConfigFile ( args : Args ) : Promise < Args > {
293
+ const configPath = getConfigPath ( args )
294
+ if ( configPath === undefined ) {
295
+ return args
296
+ }
297
+
298
+ if ( ! ( await fs . pathExists ( configPath ) ) ) {
299
+ await fs . outputFile ( configPath , `default: hello` )
300
+ }
301
+
302
+ const configFile = await fs . readFile ( configPath )
303
+ const config = yaml . safeLoad ( configFile . toString ( ) , {
304
+ filename : args . config ,
305
+ } )
306
+
307
+ // We convert the config file into a set of flags.
308
+ // This is a temporary measure until we add a proper CLI library.
309
+ const configFileArgv = Object . entries ( config ) . map ( ( [ optName , opt ] ) => `--${ optName } =${ opt } ` )
310
+ const configFileArgs = parse ( configFileArgv )
311
+
312
+ // This prioritizes the flags set in args over the ones in the config file.
313
+ return Object . assign ( configFileArgs , args )
314
+ }
315
+
316
+ function getConfigPath ( args : Args ) : string | undefined {
317
+ if ( args . config !== undefined ) {
318
+ return args . config
319
+ }
320
+ if ( process . env . CODE_SERVER_CONFIG !== undefined ) {
321
+ return process . env . CODE_SERVER_CONFIG
322
+ }
323
+ if ( xdgBasedir . config !== undefined ) {
324
+ return `${ xdgBasedir . config } /code-server/config.yaml`
325
+ }
326
+ return undefined
327
+ }
0 commit comments