-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a ConfigManager to persist configuration (#115)
Stacked on #116 Signed-off-by: Tyler Smalley <tyler@tailscale.com>
- Loading branch information
1 parent
82e0890
commit 5f93acc
Showing
3 changed files
with
96 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import * as vscode from 'vscode'; | ||
import * as fs from 'fs'; | ||
import * as path from 'path'; | ||
import { test, expect, beforeEach } from 'vitest'; | ||
import { ConfigManager } from './config-manager'; | ||
|
||
const extensionContext = { | ||
globalStoragePath: '/tmp/vscode-tailscale', | ||
} as vscode.ExtensionContext; | ||
|
||
const configPath = path.join(extensionContext.globalStoragePath, 'config.json'); | ||
|
||
beforeEach(() => { | ||
if (fs.existsSync(configPath)) { | ||
fs.unlinkSync(configPath); | ||
} | ||
}); | ||
|
||
test('withContext will create directory if it does not exist', () => { | ||
fs.rmSync(extensionContext.globalStoragePath, { recursive: true, force: true }); | ||
expect(fs.existsSync(extensionContext.globalStoragePath)).toBe(false); | ||
|
||
ConfigManager.withContext(extensionContext); | ||
expect(fs.existsSync(extensionContext.globalStoragePath)).toBe(true); | ||
}); | ||
|
||
test('withContext returns an initialized ConfigManager', () => { | ||
const cm = ConfigManager.withContext(extensionContext); | ||
expect(cm.configPath).toBe(configPath); | ||
}); | ||
|
||
test('set persists config to disk', () => { | ||
const cm = new ConfigManager(configPath); | ||
const hosts = { | ||
'host-1': { | ||
user: 'foo', | ||
rootDir: '/', | ||
}, | ||
}; | ||
|
||
cm.set('hosts', hosts); | ||
expect(cm.get('hosts')).toEqual(hosts); | ||
|
||
const f = fs.readFileSync(configPath, 'utf8'); | ||
expect(JSON.parse(f)).toEqual({ hosts }); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import * as vscode from 'vscode'; | ||
import * as fs from 'fs'; | ||
import * as path from 'path'; | ||
|
||
interface Host { | ||
user: string; | ||
rootDir: string; | ||
} | ||
|
||
interface Config { | ||
defaultHost?: Host; | ||
hosts?: Record<string, Host>; | ||
} | ||
|
||
export class ConfigManager { | ||
private config: Config; | ||
|
||
constructor(public readonly configPath: string) { | ||
if (fs.existsSync(this.configPath)) { | ||
const rawData = fs.readFileSync(this.configPath, 'utf8'); | ||
this.config = JSON.parse(rawData); | ||
} else { | ||
this.config = {}; | ||
} | ||
} | ||
|
||
static withContext(context: vscode.ExtensionContext) { | ||
const globalStoragePath = context.globalStoragePath; | ||
|
||
if (!fs.existsSync(globalStoragePath)) { | ||
fs.mkdirSync(globalStoragePath); | ||
} | ||
|
||
return new ConfigManager(path.join(globalStoragePath, 'config.json')); | ||
} | ||
|
||
get<K extends keyof Config>(key: K): Config[K] { | ||
return this.config[key]; | ||
} | ||
|
||
set<K extends keyof Config>(key: K, value: Config[K]) { | ||
this.config[key] = value; | ||
this.saveConfig(); | ||
} | ||
|
||
private saveConfig() { | ||
fs.writeFileSync(this.configPath, JSON.stringify(this.config, null, 2), 'utf8'); | ||
} | ||
} |