From 50c0a98406cad49973913e232ea0178fa210dbe3 Mon Sep 17 00:00:00 2001 From: Damyan Petev Date: Mon, 5 Feb 2018 15:34:36 +0200 Subject: [PATCH] feat: `config add` sub command for array values --- lib/Util.ts | 11 +++++++ lib/commands/config.ts | 44 +++++++++++++++++++++++++++ spec/unit/config-spec.ts | 64 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+) diff --git a/lib/Util.ts b/lib/Util.ts index ed46de7a3..36f8e2b5f 100644 --- a/lib/Util.ts +++ b/lib/Util.ts @@ -263,6 +263,17 @@ class Util { } } } + + private static propertyByPath(object: any, propPath: string) { + if (!propPath) { + return object; + } + const pathParts = propPath.split("."); + const currentProp = pathParts.shift(); + if (currentProp in object) { + return this.propertyByPath(object[currentProp], pathParts.join(".")); + } + } } export { Util }; diff --git a/lib/commands/config.ts b/lib/commands/config.ts index 7e59c8c6f..61f4c6582 100644 --- a/lib/commands/config.ts +++ b/lib/commands/config.ts @@ -29,6 +29,20 @@ const command = { } }, handler: command.setHandler + }).command({ + command: "add ", + desc: "Add a value to an existing configuration array", + builder: { + property: { + describe: "Config property to add to", + type: "string" + }, + value: { + describe: "New value to add", + type: "string" + } + }, + handler: command.addHandler }).option("global", { alias: "g", type: "boolean", @@ -70,6 +84,36 @@ const command = { config[argv.property] = argv.value; ProjectConfig.setConfig(config, argv.global); Util.log(`Property "${argv.property}" set`); + }, + addHandler(argv) { + let config; + + if (argv.global) { + config = ProjectConfig.globalConfig(); + } else { + if (!ProjectConfig.hasLocalConfig()) { + Util.error("No configuration file found in this folder!", "red"); + return; + } + config = ProjectConfig.localConfig(); + } + + // TODO: Schema/property validation? + if (!config[argv.property]) { + config[argv.property] = []; + } else if (!Array.isArray(config[argv.property])) { + Util.error(`Configuration property "${argv.property}" is not an array, use config set instead.`, "red"); + return; + } + + if (config[argv.property].indexOf(argv.value) !== -1) { + Util.log(`Value already exists in "${argv.property}".`); + return; + } + + config[argv.property].push(argv.value); + ProjectConfig.setConfig(config, argv.global); + Util.log(`Property "${argv.property}" updated.`); } }; diff --git a/spec/unit/config-spec.ts b/spec/unit/config-spec.ts index 42f1d2a80..34c283393 100644 --- a/spec/unit/config-spec.ts +++ b/spec/unit/config-spec.ts @@ -58,6 +58,9 @@ describe("Unit - Config command", () => { done(); }); + xit("Should show error for array property", async done => { + }); + it("Should set global prop", async done => { spyOn(Util, "log"); spyOn(ProjectConfig, "hasLocalConfig"); @@ -90,4 +93,65 @@ describe("Unit - Config command", () => { done(); }); }); + + describe("Add", () => { + it("Should show error w/o existing project and global flag", async done => { + spyOn(Util, "error"); + spyOn(ProjectConfig, "hasLocalConfig").and.returnValue(false); + + await configCmd.addHandler({ property: "test", value: true }); + expect(Util.error).toHaveBeenCalledWith("No configuration file found in this folder!", "red"); + done(); + }); + + it("Should show error for non-array property", async done => { + spyOn(Util, "error"); + spyOn(ProjectConfig, "hasLocalConfig").and.returnValue(true); + spyOn(ProjectConfig, "localConfig").and.returnValue({ test: "notArray" }); + + await configCmd.addHandler({ property: "test", value: "" }); + expect(Util.error).toHaveBeenCalledWith( + `Configuration property "test" is not an array, use config set instead.`, + "red"); + done(); + }); + + it("Should skip existing", async done => { + spyOn(Util, "log"); + spyOn(ProjectConfig, "hasLocalConfig").and.returnValue(true); + spyOn(ProjectConfig, "localConfig").and.returnValue({ test: ["existing"] }); + + await configCmd.addHandler({ property: "test", value: "existing" }); + expect(Util.log).toHaveBeenCalledWith(`Value already exists in "test".`); + done(); + }); + + it("Should create/add to global prop", async done => { + spyOn(Util, "log"); + spyOn(ProjectConfig, "globalConfig").and.returnValue({ }); + spyOn(ProjectConfig, "setConfig"); + + await configCmd.addHandler({ property: "test", value: "one", global: true }); + expect(ProjectConfig.setConfig).toHaveBeenCalledWith({ test: ["one"] }, true); + expect(Util.log).toHaveBeenCalledWith(`Property "test" updated.`); + + await configCmd.addHandler({ property: "test", value: "two", global: true }); + expect(ProjectConfig.setConfig).toHaveBeenCalledWith({ test: ["one", "two"] }, true); + expect(Util.log).toHaveBeenCalledWith(`Property "test" updated.`); + + done(); + }); + + it("Should add to local prop", async done => { + spyOn(Util, "log"); + spyOn(ProjectConfig, "hasLocalConfig").and.returnValue(true); + spyOn(ProjectConfig, "localConfig").and.returnValue({ test: [] }); + spyOn(ProjectConfig, "setConfig"); + + await configCmd.addHandler({ property: "test", value: "first" }); + expect(ProjectConfig.setConfig).toHaveBeenCalledWith({ test: ["first"] }, undefined); + expect(Util.log).toHaveBeenCalledWith(`Property "test" updated.`); + done(); + }); + }); });