Skip to content

Commit

Permalink
Refactor Configuration to a separate class
Browse files Browse the repository at this point in the history
  • Loading branch information
grgar committed Mar 21, 2024
1 parent ab3743e commit 8d283fe
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 53 deletions.
1 change: 1 addition & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"type": "extensionHost",
"request": "launch",
"args": [
"--disable-extensions",
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
Expand Down
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"files.exclude": {
"out": false,
".vscode-test": true,
},
"search.exclude": {
"out": true
"out": true,
".vscode-test": true,
},
"typescript.tsc.autoDetect": "off",
"git.branchProtection": [ ]
Expand Down
3 changes: 0 additions & 3 deletions .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
.vscode-test/**
src/**
.gitignore
.yarnrc
vsc-extension-quickstart.md
**/tsconfig.json
**/.eslintrc.json
**/*.map
**/*.ts
**/.vscode-test.*
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Changelog
### v1.0.1

- Refactor Configuration to a separate class

### v1.0.0

- Add example to readme
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"description": "Apply dotfiles from settings",
"icon": "images/icon-small.png",
"version": "1.0.0",
"version": "1.0.1",
"license": "MIT",
"preview": true,
"engines": {
Expand Down
37 changes: 37 additions & 0 deletions src/Configuration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import path from 'path';
import * as vscode from "vscode";

export default class Configuration {
readonly namespace: string;
readonly logger?: (msg: string) => void;

constructor(namespace: string, logger: (msg: string) => void) {
this.namespace = namespace;
this.logger = logger;
}

getDirectoryPath() {
let directory = vscode.workspace.getConfiguration(this.namespace).get<string>("directory") || process.env["XDG_CONFIG_HOME"] || path.join(process.env["HOME"]!, ".config");
if (directory.endsWith("/")) {
return directory.slice(directory.length - 1);
}
return directory;
}

getFiles() {
return vscode.workspace.getConfiguration(this.namespace).get<{ [key: string]: string; }>("files", {});
}

async setFiles(files: { [key: string]: string; }) {
try {
await vscode.workspace.getConfiguration(this.namespace).update("files", files, vscode.ConfigurationTarget.Global);
} catch (err) {
this.logger?.(`${new Date().toLocaleString()}: failed to update files: ${err}`);
vscode.window.showErrorMessage("Unable to update dotfiles.files: " + err);
}
}

shouldAutoUpdate() {
return vscode.workspace.getConfiguration(this.namespace).get<boolean>("autoUpdate", false);
}
}
45 changes: 12 additions & 33 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,15 @@
import * as fs from "fs/promises";
import path from 'path';
import * as vscode from 'vscode';
import Configuration from "./Configuration";

const configNamespace = "dotfiles";
export const configNamespace = "dotfiles";
const outputChannel = vscode.window.createOutputChannel(configNamespace);

function getDirectoryPath() {
let directory = vscode.workspace.getConfiguration(configNamespace).get<string>("directory") || process.env["XDG_CONFIG_HOME"] || path.join(process.env["HOME"]!, ".config");
if (directory.endsWith("/")) {
return directory.slice(directory.length - 1);
}
return directory;
}

function getFiles() {
return vscode.workspace.getConfiguration(configNamespace).get<{ [key: string]: string; }>("files", {});
}

async function setFiles(files: { [key: string]: string; }) {
try {
await vscode.workspace.getConfiguration(configNamespace).update("files", files, vscode.ConfigurationTarget.Global);
} catch (err) {
outputChannel.appendLine(`${new Date().toLocaleString()}: failed to update files: ${err}`);
vscode.window.showErrorMessage("Unable to update dotfiles.files: " + err);
}
}

function shouldAutoUpdate() {
return vscode.workspace.getConfiguration(configNamespace).get<boolean>("autoUpdate", false);
}

async function apply() {
const directory = getDirectoryPath();
for (const [file, content] of Object.entries(getFiles())) {
const configuration = new Configuration(configNamespace, outputChannel.appendLine);
const directory = configuration.getDirectoryPath();
for (const [file, content] of Object.entries(configuration.getFiles())) {
const filePath = path.join(directory, file);
try {
await fs.stat(filePath);
Expand All @@ -45,24 +22,25 @@ async function apply() {
}

function didSave(doc: vscode.TextDocument) {
if (!shouldAutoUpdate()) {
const configuration = new Configuration(configNamespace, outputChannel.appendLine);
if (!configuration.shouldAutoUpdate()) {
return;
}
if (doc.uri.scheme !== "file") {
return;
}
const directory = getDirectoryPath();
const directory = configuration.getDirectoryPath();
if (!doc.uri.path.startsWith(directory + "/")) {
return;
}
const files = getFiles();
const files = configuration.getFiles();
const relativePath = doc.uri.path.slice(directory.length + 1);
if (!files[relativePath]) {
outputChannel.appendLine(`${new Date().toLocaleString()}: file ${relativePath} in ${directory} not found in settings`);
return;
}
files[relativePath] = doc.getText();
setFiles(files);
configuration.setFiles(files);
outputChannel.appendLine(`${new Date().toLocaleString()}: updated ${relativePath}`);
}

Expand All @@ -71,7 +49,8 @@ export function activate(context: vscode.ExtensionContext) {
vscode.commands.registerCommand("dotfiles.apply", apply),
vscode.workspace.onDidSaveTextDocument(didSave)
);
if (shouldAutoUpdate()) {
const configuration = new Configuration(configNamespace, outputChannel.appendLine);
if (configuration.shouldAutoUpdate()) {
apply();
}
}
Expand Down
26 changes: 14 additions & 12 deletions src/test/extension.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import * as assert from 'assert';
import * as assert from "assert";
import * as vscode from "vscode";
import Configuration from "../Configuration";

// You can import and use all API from the 'vscode' module
// as well as import your extension to test it
import * as vscode from 'vscode';
// import * as myExtension from '../../extension';

suite('Extension Test Suite', () => {
vscode.window.showInformationMessage('Start all tests.');

test('Sample test', () => {
assert.strictEqual(-1, [1, 2, 3].indexOf(5));
assert.strictEqual(-1, [1, 2, 3].indexOf(0));
suite("Extension", () => {
suiteSetup(() => {
vscode.extensions.getExtension("grg.dotfiles")!.activate();
});
test("setFiles is idempotent", () => {
const testNamespace = "dotfiles";
const configuration = new Configuration(testNamespace, () => { });
const files = configuration.getFiles();
configuration.setFiles(files);
configuration.setFiles(files);
assert.deepStrictEqual(configuration.getFiles(), files);
});
});

0 comments on commit 8d283fe

Please sign in to comment.