#416 auto init of budibase when electron starts

This commit is contained in:
Michael Shanks 2020-07-03 13:03:50 +01:00
parent 83b1ace561
commit 2bf5702bca
4 changed files with 128 additions and 125 deletions

View File

@ -1,88 +1,7 @@
const inquirer = require("inquirer")
const { exists, readFile, writeFile, ensureDir } = require("fs-extra")
const chalk = require("chalk")
const { serverFileName, xPlatHomeDir } = require("../../common")
const { join } = require("path")
const Sqrl = require("squirrelly")
const uuid = require("uuid")
const { xPlatHomeDir } = require("../../common")
const initialiseBudibase = require("@budibase/server/src/utilities/initialiseBudibase")
module.exports = opts => {
return run(opts)
}
const run = async opts => {
try {
await ensureAppDir(opts)
await setEnvironmentVariables(opts)
await createClientDatabase(opts)
await createDevEnvFile(opts)
console.log(chalk.green("Budibase successfully initialised."))
} catch (error) {
console.error(`Error initialising Budibase: ${error.message}`)
}
}
const setEnvironmentVariables = async opts => {
if (opts.couchDbUrl) {
process.env.COUCH_DB_URL = opts.couchDbUrl
} else {
const dataDir = join(opts.dir, ".data")
await ensureDir(dataDir)
process.env.COUCH_DB_URL =
dataDir + (dataDir.endsWith("/") || dataDir.endsWith("\\") ? "" : "/")
}
}
const ensureAppDir = async opts => {
opts.dir = xPlatHomeDir(opts.dir)
await ensureDir(opts.dir)
}
const createClientDatabase = async opts => {
// cannot be a top level require as it
// will cause environment module to be loaded prematurely
const clientDb = require("@budibase/server/src/db/clientDb")
if (opts.clientId === "new") {
// cannot be a top level require as it
// will cause environment module to be loaded prematurely
const CouchDB = require("@budibase/server/src/db/client")
const existing = await CouchDB.allDbs()
let i = 0
let isExisting = true
while (isExisting) {
i += 1
opts.clientId = i.toString()
isExisting = existing.includes(clientDb.name(opts.clientId))
}
}
await clientDb.create(opts.clientId)
}
const createDevEnvFile = async opts => {
const destConfigFile = join(opts.dir, "./.env")
let createConfig = !(await exists(destConfigFile)) || opts.quiet
if (!createConfig) {
const answers = await inquirer.prompt([
{
type: "input",
name: "overwrite",
message: ".env already exists - overwrite? (N/y)",
},
])
createConfig = ["Y", "y", "yes"].includes(answers.overwrite)
}
if (createConfig) {
const template = await readFile(serverFileName(".env.template"), {
encoding: "utf8",
})
opts.adminSecret = uuid.v4()
opts.cookieKey1 = uuid.v4()
opts.cookieKey2 = uuid.v4()
const config = Sqrl.Render(template, opts)
await writeFile(destConfigFile, config, { flag: "w+" })
}
return initialiseBudibase(opts)
}

View File

@ -26,7 +26,7 @@
"test": "jest routes --runInBand",
"test:integration": "jest workflow --runInBand",
"test:watch": "jest --watch",
"initialise": "node ../cli/bin/budi init -b local -q",
"initialise": "node ../cli/bin/budi init -q",
"run:docker": "node src/index",
"budi": "node ../cli/bin/budi",
"dev:builder": "nodemon ../cli/bin/budi run",

View File

@ -1,29 +1,46 @@
const { app, BrowserWindow, shell } = require("electron")
const { join } = require("path")
const { homedir } = require("os")
const isDev = require("electron-is-dev")
const { autoUpdater } = require("electron-updater")
const unhandled = require("electron-unhandled")
const { existsSync } = require("fs-extra")
const initialiseBudibase = require("./utilities/initialiseBudibase")
const { budibaseAppsDir } = require("./utilities/budibaseDir")
require("dotenv").config({ path: join(homedir(), ".budibase", ".env") })
const budibaseDir = budibaseAppsDir()
const envFile = join(budibaseDir, ".env")
if (isDev) {
if (!existsSync(envFile)) {
// assume not initialised
initialiseBudibase({ dir: budibaseDir }).then(() => {
startApp()
})
} else {
startApp()
}
function startApp() {
// evict environment from cache, so it reloads when next asked
delete require.cache[require.resolve("./environment")]
require("dotenv").config({ path: envFile })
if (isDev) {
unhandled({
showDialog: true,
})
}
}
const APP_URL = "http://localhost:4001/_builder"
const APP_TITLE = "Budibase Builder"
const APP_URL = "http://localhost:4001/_builder"
const APP_TITLE = "Budibase Builder"
let win
let win
function handleRedirect(e, url) {
function handleRedirect(e, url) {
e.preventDefault()
shell.openExternal(url)
}
}
async function createWindow() {
async function createWindow() {
app.server = await require("./app")()
win = new BrowserWindow({ width: 1920, height: 1080 })
win.setTitle(APP_TITLE)
@ -37,19 +54,20 @@ async function createWindow() {
// open _blank in default browser
win.webContents.on("new-window", handleRedirect)
win.webContents.on("will-navigate", handleRedirect)
}
}
app.whenReady().then(createWindow)
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on("window-all-closed", () => {
// Quit when all windows are closed.
app.on("window-all-closed", () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== "darwin") app.quit()
})
})
app.on("activate", () => {
app.on("activate", () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) createWindow()
})
})
}

View File

@ -0,0 +1,66 @@
const { exists, readFile, writeFile, ensureDir } = require("fs-extra")
const { join, resolve } = require("path")
const Sqrl = require("squirrelly")
const uuid = require("uuid")
module.exports = async opts => {
await ensureDir(opts.dir)
await setCouchDbUrl(opts)
// need an env file to create the client database
await createDevEnvFile(opts)
await createClientDatabase(opts)
// need to recreate the env file, as we only now have a client id
// quiet flag will force overwrite of config
opts.quiet = true
await createDevEnvFile(opts)
}
const setCouchDbUrl = async opts => {
if (!opts.couchDbUrl) {
const dataDir = join(opts.dir, ".data")
await ensureDir(dataDir)
opts.couchDbUrl =
dataDir + (dataDir.endsWith("/") || dataDir.endsWith("\\") ? "" : "/")
}
}
const createDevEnvFile = async opts => {
const destConfigFile = join(opts.dir, "./.env")
let createConfig = !(await exists(destConfigFile)) || opts.quiet
if (createConfig) {
const template = await readFile(
resolve(__dirname, "..", "..", ".env.template"),
{
encoding: "utf8",
}
)
opts.cookieKey1 = opts.cookieKey1 || uuid.v4()
const config = Sqrl.Render(template, opts)
await writeFile(destConfigFile, config, { flag: "w+" })
}
}
const createClientDatabase = async opts => {
// cannot be a top level require as it
// will cause environment module to be loaded prematurely
const clientDb = require("../db/clientDb")
if (!opts.clientId || opts.clientId === "new") {
// cannot be a top level require as it
// will cause environment module to be loaded prematurely
const CouchDB = require("../db/client")
const existing = await CouchDB.allDbs()
let i = 0
let isExisting = true
while (isExisting) {
i += 1
opts.clientId = i.toString()
isExisting = existing.includes(clientDb.name(opts.clientId))
}
}
await clientDb.create(opts.clientId)
}