This repository has been archived by the owner on Nov 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#21 - Create a settings loader/manager
Signed-off-by: Wright, Christopher R <Christopher.Wright@ca.com>
- Loading branch information
Wright, Christopher R
authored and
Wright, Christopher R
committed
Sep 14, 2018
1 parent
46fa054
commit 7555654
Showing
8 changed files
with
261 additions
and
2 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
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,12 @@ | ||
/* | ||
* This program and the accompanying materials are made available under the terms of the * | ||
* Eclipse Public License v2.0 which accompanies this distribution, and is available at * | ||
* https://www.eclipse.org/legal/epl-v20.html * | ||
* * | ||
* SPDX-License-Identifier: EPL-2.0 * | ||
* * | ||
* Copyright Contributors to the Zowe Project. * | ||
* * | ||
*/ | ||
|
||
export * from "./src/AppSettings"; |
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,114 @@ | ||
/* | ||
* This program and the accompanying materials are made available under the terms of the * | ||
* Eclipse Public License v2.0 which accompanies this distribution, and is available at * | ||
* https://www.eclipse.org/legal/epl-v20.html * | ||
* * | ||
* SPDX-License-Identifier: EPL-2.0 * | ||
* * | ||
* Copyright Contributors to the Zowe Project. * | ||
* * | ||
*/ | ||
|
||
import {readFileSync} from "jsonfile"; | ||
import {existsSync} from "fs"; | ||
import {ISettingsFile} from "./doc/ISettingsFile"; | ||
|
||
/** | ||
* A recovery function to handle when a settings file is missing on an initialization function. | ||
* | ||
* @param settingsFile The file that could not be found | ||
* @param defaultSettings The default settings provided by {@link AppSettings} | ||
* | ||
* @returns The settings content to be merged into the defaults. | ||
*/ | ||
export type FileRecovery = (settingsFile: string, defaultSettings: ISettingsFile) => ISettingsFile; | ||
|
||
/** | ||
* This class represents settings for an Imperative CLI application that can be configured | ||
* by an end user by modifying a settings file. @TODO expand on this doc | ||
*/ | ||
export class AppSettings { | ||
/** | ||
* | ||
* @param settingsFile The settings file to load from. | ||
* @param missingFileRecovery A recovery function when the settings file isn't found | ||
* | ||
* @throws {@link SettingsAlreadyInitialized} When the settings singleton has previously been initialized. | ||
*/ | ||
public static initialize(settingsFile: string, missingFileRecovery ?: FileRecovery): AppSettings { | ||
if (AppSettings.mInstance) { | ||
// Throw an error imported at runtime so that we minimize file that get included | ||
// on startup. | ||
const { SettingsAlreadyInitialized } = require("./errors/index"); | ||
throw new SettingsAlreadyInitialized(); | ||
} | ||
|
||
AppSettings.mInstance = new AppSettings(settingsFile, missingFileRecovery); | ||
return AppSettings.mInstance; | ||
} | ||
|
||
|
||
/** | ||
* This is an internal reference to the static settings instance. | ||
*/ | ||
private static mInstance: AppSettings; | ||
|
||
/** | ||
* Get the singleton instance of the app settings object that was initialized | ||
* within the {@link AppSettings.initialize} function. | ||
* | ||
* @returns A singleton AppSettings object | ||
* | ||
* @throws {@link SettingsNotInitialized} When the settings singleton has not been initialized. | ||
*/ | ||
public static get instance(): AppSettings { | ||
if (AppSettings.mInstance == null) { | ||
// Throw an error imported at runtime so that we minimize file that get included | ||
// on startup. | ||
const { SettingsNotInitialized } = require("./errors/index"); | ||
throw new SettingsNotInitialized(); | ||
} | ||
|
||
return AppSettings.mInstance; | ||
} | ||
|
||
/** | ||
* Internal reference to the overrides settings. The defaults should | ||
* all be false, indicating that there are no overrides to be done. | ||
*/ | ||
public readonly settings: ISettingsFile; | ||
|
||
/** | ||
* Constructs a new settings object | ||
* | ||
* @param settingsFile The full path to a settings file to load. | ||
* @param missingFileRecovery A recovery function for when the settings file didn't exist | ||
*/ | ||
constructor(settingsFile: string, missingFileRecovery ?: FileRecovery) { | ||
let settings: ISettingsFile; | ||
const defaultSettings: ISettingsFile = { | ||
overrides: { | ||
CredentialManager: false | ||
} | ||
}; | ||
|
||
try { | ||
// Try to load the file immediately, if it fails we will then | ||
// try to recover | ||
settings = readFileSync(settingsFile); | ||
} catch (up) { | ||
if (missingFileRecovery && !existsSync(settingsFile)) { | ||
settings = missingFileRecovery(settingsFile, defaultSettings); | ||
} else { | ||
// Throw up if there is no recovery function or there was a recovery | ||
// function but the file already existed. (Indicates there was a bigger | ||
// issue at play) | ||
throw up; | ||
} | ||
} | ||
this.settings = { | ||
...defaultSettings, | ||
...settings | ||
}; | ||
} | ||
} |
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,41 @@ | ||
/* | ||
* This program and the accompanying materials are made available under the terms of the * | ||
* Eclipse Public License v2.0 which accompanies this distribution, and is available at * | ||
* https://www.eclipse.org/legal/epl-v20.html * | ||
* * | ||
* SPDX-License-Identifier: EPL-2.0 * | ||
* * | ||
* Copyright Contributors to the Zowe Project. * | ||
* * | ||
*/ | ||
|
||
import {IImperativeOverrides} from "../../../imperative/src/doc/IImperativeOverrides"; | ||
|
||
/** | ||
* This interface defines the structure of the settings file. | ||
*/ | ||
export interface ISettingsFile { | ||
/** | ||
* The overrides object determines which items will be used for any overrides in | ||
* the overrides loader. Overrides can come from the base cli or plugins. | ||
*/ | ||
overrides: { | ||
/** | ||
* This object can have any key present in the {@link IImperativeOverrides} object | ||
* as a valid setting, allowing us to be dynamic. | ||
* | ||
* Possible Values | ||
* --------------- | ||
* false - Use the default overrides defined by the base cli application. If | ||
* the base application doesn't provide the override for this key, | ||
* Imperative's default will be used. | ||
* | ||
* string - A string value indicates that there is an installed plugin that | ||
* contains an overrides for this value. The string is the name of | ||
* the plugin. If the plugin doesn't provide the override, a warning | ||
* will be logged to the console, the value will be left unchanged | ||
* and we will act as if the key was null. | ||
*/ | ||
[K in keyof IImperativeOverrides]-?: false | string; // All keys of IImperativeOverrides now become required | ||
}; | ||
} |
23 changes: 23 additions & 0 deletions
23
packages/settings/src/errors/SettingsAlreadyInitialized.ts
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,23 @@ | ||
/* | ||
* This program and the accompanying materials are made available under the terms of the * | ||
* Eclipse Public License v2.0 which accompanies this distribution, and is available at * | ||
* https://www.eclipse.org/legal/epl-v20.html * | ||
* * | ||
* SPDX-License-Identifier: EPL-2.0 * | ||
* * | ||
* Copyright Contributors to the Zowe Project. * | ||
* * | ||
*/ | ||
|
||
import {ImperativeError} from "../../../error/"; | ||
|
||
/** | ||
* This class represents an error that is thrown when a second settings singleton attempts to initialize. | ||
*/ | ||
export class SettingsAlreadyInitialized extends ImperativeError { | ||
constructor() { | ||
super({ | ||
msg: "AppSettings can only be initialized once per application. Please use AppSettings.instance instead!" | ||
}); | ||
} | ||
} |
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,23 @@ | ||
/* | ||
* This program and the accompanying materials are made available under the terms of the * | ||
* Eclipse Public License v2.0 which accompanies this distribution, and is available at * | ||
* https://www.eclipse.org/legal/epl-v20.html * | ||
* * | ||
* SPDX-License-Identifier: EPL-2.0 * | ||
* * | ||
* Copyright Contributors to the Zowe Project. * | ||
* * | ||
*/ | ||
|
||
import {ImperativeError} from "../../../error"; | ||
|
||
/** | ||
* This class represents an error thrown when a null singleton {@link AppSettings} object is referenced. | ||
*/ | ||
export class SettingsNotInitialized extends ImperativeError { | ||
constructor() { | ||
super({ | ||
msg: "AppSettings have not been initialized yet. Please initialize using AppSettings.initialize(...) first!" | ||
}); | ||
} | ||
} |
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,13 @@ | ||
/* | ||
* This program and the accompanying materials are made available under the terms of the * | ||
* Eclipse Public License v2.0 which accompanies this distribution, and is available at * | ||
* https://www.eclipse.org/legal/epl-v20.html * | ||
* * | ||
* SPDX-License-Identifier: EPL-2.0 * | ||
* * | ||
* Copyright Contributors to the Zowe Project. * | ||
* * | ||
*/ | ||
|
||
export * from "./SettingsAlreadyInitialized"; | ||
export * from "./SettingsNotInitialized"; |