-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce a new Configuration module for persisting UI5 Project specific settings. Complements: #570 JIRA: CPOUI5FOUNDATION-634 Co-authored-by: Yavor Ivanov <yavor.ivanov@sap.com>
- Loading branch information
1 parent
6a09bc9
commit fd37cef
Showing
7 changed files
with
221 additions
and
4 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import path from "node:path"; | ||
import os from "node:os"; | ||
|
||
/** | ||
* Provides basic configuration settings for @ui5/project/ui5Framework/* resolvers. | ||
* Reads/writes configuration from/to ~/.ui5rc | ||
* | ||
* @public | ||
* @class | ||
* @alias @ui5/project/config/Configuration | ||
*/ | ||
class Configuration { | ||
#mavenSnapshotEndpointUrl; | ||
|
||
/** | ||
* @param {object} configuration | ||
* @param {string} [configuration.mavenSnapshotEndpointUrl] | ||
*/ | ||
constructor({mavenSnapshotEndpointUrl}) { | ||
this.#mavenSnapshotEndpointUrl = mavenSnapshotEndpointUrl; | ||
} | ||
|
||
/** | ||
* Maven Repository Snapshot URL. | ||
* Used to download artifacts and packages from Maven's build-snapshots URL. | ||
* | ||
* @public | ||
* @returns {string} | ||
*/ | ||
getMavenSnapshotEndpointUrl() { | ||
return this.#mavenSnapshotEndpointUrl; | ||
} | ||
|
||
/** | ||
* @public | ||
* @returns {object} The configuration in a JSON format | ||
*/ | ||
toJSON() { | ||
return { | ||
mavenSnapshotEndpointUrl: this.#mavenSnapshotEndpointUrl, | ||
}; | ||
} | ||
|
||
/** | ||
* Creates Configuration from a JSON file | ||
* | ||
* @public | ||
* @static | ||
* @param {string} [filePath="~/.ui5rc"] Path to configuration JSON file | ||
* @returns {Promise<@ui5/project/config/Configuration>} Configuration instance | ||
*/ | ||
static async fromFile(filePath) { | ||
filePath = filePath || path.resolve(path.join(os.homedir(), ".ui5rc")); | ||
|
||
const {default: fs} = await import("graceful-fs"); | ||
const {promisify} = await import("node:util"); | ||
const readFile = promisify(fs.readFile); | ||
let config; | ||
try { | ||
const fileContent = await readFile(filePath); | ||
config = JSON.parse(fileContent); | ||
} catch (err) { | ||
if (err.code === "ENOENT") { | ||
// "File or directory does not exist" | ||
config = {}; | ||
} else { | ||
throw err; | ||
} | ||
} | ||
return new Configuration(config); | ||
} | ||
|
||
/** | ||
* Saves Configuration to a JSON file | ||
* | ||
* @public | ||
* @static | ||
* @param {@ui5/project/config/Configuration} config Configuration to save | ||
* @param {string} [filePath="~/.ui5rc"] Path to configuration JSON file | ||
* @returns {Promise<void>} | ||
*/ | ||
static async toFile(config, filePath) { | ||
filePath = filePath || path.resolve(path.join(os.homedir(), ".ui5rc")); | ||
|
||
const {default: fs} = await import("graceful-fs"); | ||
const {promisify} = await import("node:util"); | ||
const writeFile = promisify(fs.writeFile); | ||
|
||
return writeFile(filePath, JSON.stringify(config.toJSON())); | ||
} | ||
} | ||
|
||
export default Configuration; |
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
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,122 @@ | ||
import test from "ava"; | ||
import sinonGlobal from "sinon"; | ||
import esmock from "esmock"; | ||
|
||
test.beforeEach(async (t) => { | ||
const sinon = t.context.sinon = sinonGlobal.createSandbox(); | ||
|
||
t.context.homedirStub = sinon.stub().returns("~"); | ||
t.context.promisifyStub = sinon.stub(); | ||
t.context.resolveStub = sinon.stub().callsFake((path) => path); | ||
t.context.joinStub = sinon.stub().callsFake((...args) => args.join("/")); | ||
t.context.Configuration = await esmock.p("../../../lib/config/Configuration.js", { | ||
"node:path": { | ||
resolve: t.context.resolveStub, | ||
join: t.context.joinStub | ||
}, | ||
"node:util": { | ||
"promisify": t.context.promisifyStub | ||
}, | ||
"node:os": { | ||
"homedir": t.context.homedirStub | ||
} | ||
}); | ||
}); | ||
|
||
test.afterEach.always((t) => { | ||
t.context.sinon.restore(); | ||
esmock.purge(t.context.Configuration); | ||
}); | ||
|
||
test.serial("Build configuration with defaults", (t) => { | ||
const {Configuration} = t.context; | ||
|
||
const config = new Configuration({}); | ||
|
||
t.deepEqual(config.toJSON(), { | ||
mavenSnapshotEndpointUrl: undefined | ||
}); | ||
}); | ||
|
||
|
||
test.serial("Overwrite defaults defaults", (t) => { | ||
const {Configuration} = t.context; | ||
|
||
const params = { | ||
mavenSnapshotEndpointUrl: "https://snapshot.url" | ||
}; | ||
|
||
const config = new Configuration(params); | ||
|
||
t.deepEqual(config.toJSON(), params); | ||
}); | ||
|
||
test.serial("Check getters", (t) => { | ||
const {Configuration} = t.context; | ||
|
||
const params = { | ||
mavenSnapshotEndpointUrl: "https://snapshot.url" | ||
}; | ||
|
||
const config = new Configuration(params); | ||
|
||
t.is(config.getMavenSnapshotEndpointUrl(), params.mavenSnapshotEndpointUrl); | ||
}); | ||
|
||
|
||
test.serial("fromFile", async (t) => { | ||
const fromFile = t.context.Configuration.fromFile; | ||
const {promisifyStub, sinon} = t.context; | ||
|
||
const ui5rcContents = { | ||
mavenSnapshotEndpointUrl: "https://snapshot.url" | ||
}; | ||
const responseStub = sinon.stub().resolves(JSON.stringify(ui5rcContents)); | ||
promisifyStub.callsFake(() => responseStub); | ||
|
||
const config = await fromFile("/custom/path/.ui5rc"); | ||
|
||
t.deepEqual(config.toJSON(), ui5rcContents); | ||
}); | ||
|
||
test.serial("fromFile: configuration file not found- fallback to default config", async (t) => { | ||
const {promisifyStub, sinon, Configuration} = t.context; | ||
const fromFile = Configuration.fromFile; | ||
|
||
const responseStub = sinon.stub().throws({code: "ENOENT"}); | ||
promisifyStub.callsFake(() => responseStub); | ||
|
||
const config = await fromFile("/non-existing/path/.ui5rc"); | ||
|
||
t.is(config instanceof Configuration, true, "Created a default configuration"); | ||
t.is(config.getMavenSnapshotEndpointUrl(), undefined, "Dafault settings"); | ||
}); | ||
|
||
test.serial("fromFile: throws", async (t) => { | ||
const fromFile = t.context.Configuration.fromFile; | ||
const {promisifyStub, sinon} = t.context; | ||
|
||
const responseStub = sinon.stub().throws(new Error("Error")); | ||
promisifyStub.callsFake(() => responseStub); | ||
|
||
await t.throwsAsync(fromFile("/non-existing/path/.ui5rc"), { | ||
message: "Error" | ||
}); | ||
}); | ||
|
||
test.serial("toFile", async (t) => { | ||
const {promisifyStub, sinon, Configuration} = t.context; | ||
const toFile = Configuration.toFile; | ||
|
||
const writeStub = sinon.stub().resolves(); | ||
promisifyStub.callsFake(() => writeStub); | ||
|
||
const config = new Configuration({mavenSnapshotEndpointUrl: "https://registry.corp/vendor/build-snapshots/"}); | ||
await toFile(config, "/path/to/save/.ui5rc"); | ||
|
||
t.deepEqual( | ||
writeStub.getCall(0).args, | ||
["/path/to/save/.ui5rc", JSON.stringify(config.toJSON())], | ||
"Write config to path" | ||
); | ||
}); |
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