From e2b26ffa9cbf1abdd688e33992caf7b310bf68b1 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Tue, 30 Mar 2021 10:50:42 +0100 Subject: [PATCH] adding abstraction for config manager --- packages/cli/src/analytics/Client.js | 35 ++++++++++++ packages/cli/src/analytics/index.js | 58 ++------------------ packages/cli/src/config/index.js | 0 packages/cli/src/constants.js | 10 ++++ packages/cli/src/hosting/index.js | 11 +++- packages/cli/src/structures/ConfigManager.js | 45 +++++++++++++++ packages/cli/src/utils.js | 8 +++ 7 files changed, 114 insertions(+), 53 deletions(-) create mode 100644 packages/cli/src/analytics/Client.js delete mode 100644 packages/cli/src/config/index.js create mode 100644 packages/cli/src/structures/ConfigManager.js diff --git a/packages/cli/src/analytics/Client.js b/packages/cli/src/analytics/Client.js new file mode 100644 index 0000000000..83eca791ad --- /dev/null +++ b/packages/cli/src/analytics/Client.js @@ -0,0 +1,35 @@ +const PostHog = require("posthog-node") +const path = require("path") +const fs = require("fs") +const os = require("os") +const { BUDIBASE_POSTHOG_URL, BUDIBASE_POSTHOG_TOKEN, AnalyticsEvents } = require("../constants") +const ConfigManager = require("../structures/ConfigManager") + +class AnalyticsClient { + constructor() { + this.client = new PostHog(BUDIBASE_POSTHOG_TOKEN, { host: BUDIBASE_POSTHOG_URL }) + this.configManager = new ConfigManager() + } + + capture(event) { + if (this.manager.config.analyticsDisabled) return + + this.client.capture(event) + } + + enable() { + this.configManager.removeKey("analyticsDisabled") + this.client.capture({ event: AnalyticsEvents.OptIn, distinctId: "cli" }) + } + + disable() { + this.client.capture({ event: AnalyticsEvents.OptOut, distinctId: "cli" }) + this.configManager.setValue("analyticsDisabled", true) + } + + status() { + return this.configManager.config.analyticsDisabled ? "disabled" : "enabled" + } +} + +module.exports = AnalyticsClient \ No newline at end of file diff --git a/packages/cli/src/analytics/index.js b/packages/cli/src/analytics/index.js index 84091bde1e..d11e8d6a3a 100644 --- a/packages/cli/src/analytics/index.js +++ b/packages/cli/src/analytics/index.js @@ -1,71 +1,26 @@ -const PostHog = require("posthog-node") const Command = require("../structures/Command") -const { CommandWords, InitTypes } = require("../constants") +const { CommandWords, InitTypes, BUDIBASE_POSTHOG_URL } = require("../constants") const { lookpath } = require("lookpath") const { - downloadFile, - logErrorToFile, success, + error, info, parseEnv, } = require("../utils") const { confirmation } = require("../questions") const fs = require("fs") -// const makeEnv = require("./makeEnv") const axios = require("axios") - -const Events = { - OptOut: "opt_out", - OptIn: "opt_in", -} - -class AnalyticsClient { - constructor() { - this.client = new PostHog("Oeq9KzIpZYaNsXIvHw5QTZWNpfiG_EOjAOpjTyAiitY", { host: "https://posthog.budi.live" }) - } - - capture() { - if (!enabled) return - - this.client.capture({ - event: Events.OptOut - }) - } - - enable() { - this.disabled = false - } - - disable() { - this.disabled = true - } - - status() { - return this.disabled ? "disabled" : "enabled" - } -} - -class BudibaseConfig { - constructor(config) { - this.config = config - } - - write() { - // fs.wri - } -} +const AnalyticsClient = require("./Client") const client = new AnalyticsClient() - async function optOut() { - client.capture({ event: Events.OptOut }) - client.disable() try { // opt them out + client.disable() console.log(success("Successfully opted out of budibase analytics. You can opt in at any time by running 'budi analytics opt-in'")) } catch (err) { - console.log(error("Error opting out of budibase analytics. Please try again later.")) + console.log(error("Error opting out of budibase analytics. Please try again later.", err)) } } @@ -73,8 +28,7 @@ async function optIn() { try { // opt them in client.enable() - client.capture({ event: Events.OptIn }) - console.log(success("Successfully opted in of budibase analytics. Thank you for helping us make budibase better!")) + console.log(success("Successfully opted in to budibase analytics. Thank you for helping us make budibase better!")) } catch (err) { console.log(error("Error opting in to budibase analytics. Please try again later.")) } diff --git a/packages/cli/src/config/index.js b/packages/cli/src/config/index.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/cli/src/constants.js b/packages/cli/src/constants.js index 1220b1401f..1bc668cc8e 100644 --- a/packages/cli/src/constants.js +++ b/packages/cli/src/constants.js @@ -8,3 +8,13 @@ exports.InitTypes = { QUICK: "quick", DIGITAL_OCEAN: "do", } + +exports.AnalyticsEvents = { + OptOut: "analytics_opt_out", + OptIn: "analytics_opt_in", + SelfHostInit: "hosting_init" +} + + +exports.BUDIBASE_POSTHOG_URL = "https://posthog.budi.live" +exports.BUDIBASE_POSTHOG_TOKEN = process.env.BUDIBASE_POSTHOG_TOKEN \ No newline at end of file diff --git a/packages/cli/src/hosting/index.js b/packages/cli/src/hosting/index.js index 710397f301..52f4f58c0b 100644 --- a/packages/cli/src/hosting/index.js +++ b/packages/cli/src/hosting/index.js @@ -1,5 +1,5 @@ const Command = require("../structures/Command") -const { CommandWords, InitTypes } = require("../constants") +const { CommandWords, InitTypes, AnalyticsEvents } = require("../constants") const { lookpath } = require("lookpath") const { downloadFile, @@ -13,6 +13,7 @@ const fs = require("fs") const compose = require("docker-compose") const makeEnv = require("./makeEnv") const axios = require("axios") +const AnalyticsClient = require("../analytics/Client") const BUDIBASE_SERVICES = ["app-service", "worker-service"] const ERROR_FILE = "docker-error.log" @@ -22,6 +23,8 @@ const FILE_URLS = [ ] const DO_USER_DATA_URL = "http://169.254.169.254/metadata/v1/user-data" +const client = new AnalyticsClient() + async function downloadFiles() { const promises = [] for (let url of FILE_URLS) { @@ -70,6 +73,12 @@ async function init(type) { return } } + client.capture({ + event: AnalyticsEvents.SelfHostInit, + properties: { + type + } + }) await downloadFiles() const config = isQuick ? makeEnv.QUICK_CONFIG : {} if (type === InitTypes.DIGITAL_OCEAN) { diff --git a/packages/cli/src/structures/ConfigManager.js b/packages/cli/src/structures/ConfigManager.js new file mode 100644 index 0000000000..1fc1f43cfc --- /dev/null +++ b/packages/cli/src/structures/ConfigManager.js @@ -0,0 +1,45 @@ +const fs = require("fs") +const path = require("path") +const os = require("os") +const { error } = require("../utils") + +class ConfigManager { + constructor() { + this.path = path.join(os.homedir(), ".budibase.json") + if (!fs.existsSync(this.path)) { + fs.writeFileSync(this.path, "{}") + } + } + + get config() { + try { + return JSON.parse(fs.readFileSync(this.path, "utf8")) + } catch (err) { + console.log(error(("Error parsing configuration file. Please check your .budibase.json is valid."))) + } + } + + set config(json) { + fs.writeFileSync(this.path, JSON.stringify(json)) + } + + getValue(key) { + return this.config[key] + } + + setValue(key, value) { + const updated = { + ...this.config, + [key]: value + } + this.config = updated + } + + removeKey(key) { + const updated = { ...this.config } + delete updated[key] + this.config = updated + } +} + +module.exports = ConfigManager \ No newline at end of file diff --git a/packages/cli/src/utils.js b/packages/cli/src/utils.js index f61636389d..935c96cf3c 100644 --- a/packages/cli/src/utils.js +++ b/packages/cli/src/utils.js @@ -56,3 +56,11 @@ exports.parseEnv = env => { } return result } + +exports.getConfigValue = (key, value) => { + +} + +exports.setConfigValue = (key, value) => { + +}