improve install steps methods

This commit is contained in:
srgooglo 2023-11-21 19:13:20 +01:00
parent db3fe91bf0
commit 952e27af1d
5 changed files with 193 additions and 90 deletions

View File

@ -2,6 +2,7 @@ import os from "node:os"
import path from "node:path" import path from "node:path"
import fs from "node:fs" import fs from "node:fs"
import child_process from "node:child_process" import child_process from "node:child_process"
import sendToRender from "../utils/sendToRender"
global.OS_USERDATA_PATH = path.resolve( global.OS_USERDATA_PATH = path.resolve(
process.env.APPDATA || process.env.APPDATA ||
@ -18,6 +19,7 @@ import { rimraf } from "rimraf"
import readManifest from "../utils/readManifest" import readManifest from "../utils/readManifest"
import initManifest from "../utils/initManifest" import initManifest from "../utils/initManifest"
import ISM_DRIVE_DL from "./installs_steps_methods/drive"
import ISM_HTTP from "./installs_steps_methods/http" import ISM_HTTP from "./installs_steps_methods/http"
import ISM_GIT_CLONE from "./installs_steps_methods/git_clone" import ISM_GIT_CLONE from "./installs_steps_methods/git_clone"
import ISM_GIT_PULL from "./installs_steps_methods/git_pull" import ISM_GIT_PULL from "./installs_steps_methods/git_pull"
@ -30,6 +32,7 @@ const RealmDBDefault = {
} }
const InstallationStepsMethods = { const InstallationStepsMethods = {
drive_dl: ISM_DRIVE_DL,
http: ISM_HTTP, http: ISM_HTTP,
git_clone: ISM_GIT_CLONE, git_clone: ISM_GIT_CLONE,
git_pull: ISM_GIT_PULL, git_pull: ISM_GIT_PULL,
@ -40,6 +43,12 @@ async function processGenericSteps(manifest, steps) {
for await (const [stepKey, stepValue] of Object.entries(steps)) { for await (const [stepKey, stepValue] of Object.entries(steps)) {
switch (stepKey) { switch (stepKey) {
case "drive_downloads": {
for await (const dl_step of stepValue) {
await InstallationStepsMethods.drive_dl(manifest, dl_step)
}
break;
}
case "http_downloads": { case "http_downloads": {
for await (const dl_step of stepValue) { for await (const dl_step of stepValue) {
await InstallationStepsMethods.http(manifest, dl_step) await InstallationStepsMethods.http(manifest, dl_step)
@ -184,95 +193,97 @@ export default class PkgManager {
manifest.status = "installing" manifest.status = "installing"
if (!Array.isArray(manifest.applied_patches)) {
manifest.applied_patches = []
}
console.log(`Applying changes for [${manifest_id}]... >`, changes) console.log(`Applying changes for [${manifest_id}]... >`, changes)
global.sendToRenderer(`installation:done`, { sendToRender(`installation:done`, {
...manifest, ...manifest,
statusText: "Applying changes...", statusText: "Applying changes...",
}) })
const disablePatches = manifest.patches.filter((p) => { if (Array.isArray(changes.patches)) {
return !changes.patches[p.id] if (!Array.isArray(manifest.applied_patches)) {
}) manifest.applied_patches = []
}
const installPatches = manifest.patches.filter((p) => { const disablePatches = manifest.patches.filter((p) => {
return changes.patches[p.id] return !changes.patches[p.id]
})
for await (let patch of disablePatches) {
console.log(`Removing patch [${patch.id}]...`)
global.sendToRenderer(`installation:status`, {
...manifest,
statusText: `Removing patch [${patch.id}]...`,
}) })
// remove patch additions const installPatches = manifest.patches.filter((p) => {
for await (let addition of patch.additions) { return changes.patches[p.id]
// resolve patch file })
addition.file = await this.parseStringVars(addition.file, manifest)
console.log(`Removing addition [${addition.file}]...`) for await (let patch of disablePatches) {
console.log(`Removing patch [${patch.id}]...`)
if (!fs.existsSync(addition.file)) { sendToRender(`installation:status`, {
...manifest,
statusText: `Removing patch [${patch.id}]...`,
})
// remove patch additions
for await (let addition of patch.additions) {
// resolve patch file
addition.file = await this.parseStringVars(addition.file, manifest)
console.log(`Removing addition [${addition.file}]...`)
if (!fs.existsSync(addition.file)) {
continue
}
// remove addition
await fs.promises.unlink(addition.file, { force: true, recursive: true })
}
// TODO: remove file patch overrides with original file
// remove from applied patches
manifest.applied_patches = manifest.applied_patches.filter((p) => {
return p !== patch.id
})
}
for await (let patch of installPatches) {
if (manifest.applied_patches.includes(patch.id)) {
continue continue
} }
// remove addition console.log(`Applying patch [${patch.id}]...`)
await fs.promises.unlink(addition.file, { force: true, recursive: true })
}
// TODO: remove file patch overrides with original file sendToRender(`installation:status`, {
...manifest,
statusText: `Applying patch [${patch.id}]...`,
})
// remove from applied patches for await (let addition of patch.additions) {
manifest.applied_patches = manifest.applied_patches.filter((p) => { console.log(addition)
return p !== patch.id
})
}
for await (let patch of installPatches) { // resolve patch file
if (manifest.applied_patches.includes(patch.id)) { addition.file = await this.parseStringVars(addition.file, manifest)
continue
}
console.log(`Applying patch [${patch.id}]...`) if (fs.existsSync(addition.file)) {
continue
}
global.sendToRenderer(`installation:status`, { await processGenericSteps(manifest, addition.steps)
...manifest,
statusText: `Applying patch [${patch.id}]...`,
})
for await (let addition of patch.additions) {
console.log(addition)
// resolve patch file
addition.file = await this.parseStringVars(addition.file, manifest)
if (fs.existsSync(addition.file)) {
continue
} }
await processGenericSteps(manifest, addition.steps) // add to applied patches
manifest.applied_patches.push(patch.id)
} }
// add to applied patches
manifest.applied_patches.push(patch.id)
} }
manifest.status = "installed" manifest.status = "installed"
global.sendToRenderer(`installation:done`, { sendToRender(`installation:done`, {
...manifest, ...manifest,
statusText: "Changes applied!", statusText: "Changes applied!",
}) })
db.installations[index] = manifest db.installations[index] = manifest
console.log(`Patches applied for [${manifest_id}]...`) console.log(`Changes applied for [${manifest_id}]...`)
await this.writeDb(db) await this.writeDb(db)
} }
@ -282,7 +293,7 @@ export default class PkgManager {
let pendingTasks = [] let pendingTasks = []
manifest = await readManifest(manifest).catch((error) => { manifest = await readManifest(manifest).catch((error) => {
global.sendToRenderer("runtime:error", "Cannot fetch this manifest") sendToRender("runtime:error", "Cannot fetch this manifest")
return false return false
}) })
@ -298,7 +309,7 @@ export default class PkgManager {
console.log(`Starting to install ${manifest.name}...`) console.log(`Starting to install ${manifest.name}...`)
console.log(`Installing at >`, manifest.packPath) console.log(`Installing at >`, manifest.packPath)
global.sendToRenderer("new:installation", manifest) sendToRender("new:installation", manifest)
fs.mkdirSync(manifest.packPath, { recursive: true }) fs.mkdirSync(manifest.packPath, { recursive: true })
@ -307,7 +318,7 @@ export default class PkgManager {
if (typeof manifest.before_install === "function") { if (typeof manifest.before_install === "function") {
console.log(`Performing before_install hook...`) console.log(`Performing before_install hook...`)
global.sendToRenderer(`installation:status`, { sendToRender(`installation:status`, {
...manifest, ...manifest,
statusText: `Performing before_install hook...`, statusText: `Performing before_install hook...`,
}) })
@ -325,7 +336,7 @@ export default class PkgManager {
if (pendingTasks.length > 0) { if (pendingTasks.length > 0) {
console.log(`Performing pending tasks...`) console.log(`Performing pending tasks...`)
global.sendToRenderer(`installation:status`, { sendToRender(`installation:status`, {
...manifest, ...manifest,
statusText: `Performing pending tasks...`, statusText: `Performing pending tasks...`,
}) })
@ -338,7 +349,7 @@ export default class PkgManager {
if (typeof manifest.after_install === "function") { if (typeof manifest.after_install === "function") {
console.log(`Performing after_install hook...`) console.log(`Performing after_install hook...`)
global.sendToRenderer(`installation:status`, { sendToRender(`installation:status`, {
...manifest, ...manifest,
statusText: `Performing after_install hook...`, statusText: `Performing after_install hook...`,
}) })
@ -357,23 +368,25 @@ export default class PkgManager {
await this.appendInstallation(manifest) await this.appendInstallation(manifest)
// process default patches if (manifest.patches) {
const defaultPatches = manifest.patches.filter((patch) => patch.default) // process default patches
const defaultPatches = manifest.patches.filter((patch) => patch.default)
this.applyChanges(manifest.id, { this.applyChanges(manifest.id, {
patches: Object.fromEntries(defaultPatches.map((patch) => [patch.id, true])), patches: Object.fromEntries(defaultPatches.map((patch) => [patch.id, true])),
}) })
}
console.log(`Successfully installed ${manifest.name}!`) console.log(`Successfully installed ${manifest.name}!`)
global.sendToRenderer(`installation:done`, { sendToRender(`installation:done`, {
...manifest, ...manifest,
statusText: "Successfully installed", statusText: "Successfully installed",
}) })
} catch (error) { } catch (error) {
manifest.status = "failed" manifest.status = "failed"
global.sendToRenderer(`installation:error`, { sendToRender(`installation:error`, {
...manifest, ...manifest,
statusText: error.toString(), statusText: error.toString(),
}) })
@ -387,7 +400,7 @@ export default class PkgManager {
async uninstall(manifest_id) { async uninstall(manifest_id) {
console.log(`Uninstalling >`, manifest_id) console.log(`Uninstalling >`, manifest_id)
global.sendToRenderer("installation:status", { sendToRender("installation:status", {
status: "uninstalling", status: "uninstalling",
id: manifest_id, id: manifest_id,
statusText: `Uninstalling ${manifest_id}...`, statusText: `Uninstalling ${manifest_id}...`,
@ -398,7 +411,7 @@ export default class PkgManager {
const manifest = db.installations.find((i) => i.id === manifest_id) const manifest = db.installations.find((i) => i.id === manifest_id)
if (!manifest) { if (!manifest) {
global.sendToRenderer("runtime:error", "Manifest not found") sendToRender("runtime:error", "Manifest not found")
return false return false
} }
@ -422,7 +435,7 @@ export default class PkgManager {
await this.writeDb(db) await this.writeDb(db)
global.sendToRenderer("installation:uninstalled", { sendToRender("installation:uninstalled", {
id: manifest_id, id: manifest_id,
}) })
} }
@ -433,7 +446,7 @@ export default class PkgManager {
console.log(`Updating >`, manifest_id) console.log(`Updating >`, manifest_id)
global.sendToRenderer("installation:status", { sendToRender("installation:status", {
status: "updating", status: "updating",
id: manifest_id, id: manifest_id,
statusText: `Updating ${manifest_id}...`, statusText: `Updating ${manifest_id}...`,
@ -444,7 +457,7 @@ export default class PkgManager {
let manifest = db.installations.find((i) => i.id === manifest_id) let manifest = db.installations.find((i) => i.id === manifest_id)
if (!manifest) { if (!manifest) {
global.sendToRenderer("runtime:error", "Manifest not found") sendToRender("runtime:error", "Manifest not found")
return false return false
} }
@ -459,7 +472,7 @@ export default class PkgManager {
manifest = await initManifest(manifest) manifest = await initManifest(manifest)
if (typeof manifest.update === "function") { if (typeof manifest.update === "function") {
global.sendToRenderer(`installation:status`, { sendToRender(`installation:status`, {
...manifest, ...manifest,
statusText: `Performing update hook...`, statusText: `Performing update hook...`,
}) })
@ -479,7 +492,7 @@ export default class PkgManager {
if (pendingTasks.length > 0) { if (pendingTasks.length > 0) {
console.log(`Performing pending tasks...`) console.log(`Performing pending tasks...`)
global.sendToRenderer(`installation:status`, { sendToRender(`installation:status`, {
...manifest, ...manifest,
statusText: `Performing pending tasks...`, statusText: `Performing pending tasks...`,
}) })
@ -492,7 +505,7 @@ export default class PkgManager {
if (typeof manifest.after_update === "function") { if (typeof manifest.after_update === "function") {
console.log(`Performing after_update hook...`) console.log(`Performing after_update hook...`)
global.sendToRenderer(`installation:status`, { sendToRender(`installation:status`, {
...manifest, ...manifest,
statusText: `Performing after_update hook...`, statusText: `Performing after_update hook...`,
}) })
@ -512,14 +525,14 @@ export default class PkgManager {
console.log(`Successfully updated ${manifest.name}!`) console.log(`Successfully updated ${manifest.name}!`)
global.sendToRenderer(`installation:done`, { sendToRender(`installation:done`, {
...manifest, ...manifest,
statusText: "Successfully updated", statusText: "Successfully updated",
}) })
} catch (error) { } catch (error) {
manifest.status = "failed" manifest.status = "failed"
global.sendToRenderer(`installation:error`, { sendToRender(`installation:error`, {
...manifest, ...manifest,
statusText: error.toString(), statusText: error.toString(),
}) })
@ -531,7 +544,7 @@ export default class PkgManager {
async execute(manifest_id) { async execute(manifest_id) {
console.log(`Executing ${manifest_id}...`) console.log(`Executing ${manifest_id}...`)
global.sendToRenderer("installation:status", { sendToRender("installation:status", {
status: "starting", status: "starting",
id: manifest_id, id: manifest_id,
statusText: `Executing ${manifest_id}...`, statusText: `Executing ${manifest_id}...`,
@ -542,7 +555,7 @@ export default class PkgManager {
let manifest = db.installations.find((i) => i.id === manifest_id) let manifest = db.installations.find((i) => i.id === manifest_id)
if (!manifest) { if (!manifest) {
global.sendToRenderer("runtime:error", "Manifest not found") sendToRender("runtime:error", "Manifest not found")
return false return false
} }
@ -570,7 +583,7 @@ export default class PkgManager {
}) })
} else { } else {
if (typeof manifest.execute !== "function") { if (typeof manifest.execute !== "function") {
global.sendToRenderer("installation:status", { sendToRender("installation:status", {
status: "execution_failed", status: "execution_failed",
...manifest, ...manifest,
}) })
@ -585,7 +598,7 @@ export default class PkgManager {
}) })
} }
global.sendToRenderer("installation:status", { sendToRender("installation:status", {
status: "installed", status: "installed",
...manifest, ...manifest,
}) })

View File

@ -0,0 +1,85 @@
import path from "node:path"
import fs from "node:fs"
import humanFormat from "human-format"
import got from "got"
import sendToRender from "../../utils/sendToRender"
import extractFile from "../../utils/extractFile"
import GoogleDriveAPI from "../../lib/google_drive"
function convertSize(size) {
return `${humanFormat(size, {
decimals: 2,
})}B`
}
export default async (manifest, step) => {
let _path = path.resolve(manifest.packPath, step.path ?? ".")
console.log(`Downloading ${step.id} to ${_path}...`)
sendToRender(`installation:status`, {
...manifest,
statusText: `Downloading file id ${step.id}`,
})
if (step.tmp) {
_path = path.resolve(TMP_PATH, String(new Date().getTime()))
}
fs.mkdirSync(path.resolve(_path, ".."), { recursive: true })
sendToRender(`installation:status`, {
...manifest,
statusText: `Starting download...`,
})
// Download file from drive
await new Promise((resolve, reject) => {
GoogleDriveAPI.operations.downloadFile(
step.id,
_path,
(err) => {
if (err) {
return reject(err)
}
return resolve()
},
(progress) => {
sendToRender(`installation:${manifest.id}:status`, {
...manifest,
progress: progress,
statusText: `Downloaded ${convertSize(progress.transferred ?? 0)} / ${convertSize(progress.length)} | ${convertSize(progress.speed)}/s`,
})
}
)
})
if (step.extract) {
if (typeof step.extract === "string") {
step.extract = path.resolve(manifest.packPath, step.extract)
} else {
step.extract = path.resolve(manifest.packPath, ".")
}
sendToRender(`installation:status`, {
...manifest,
statusText: `Extracting bundle...`,
})
await extractFile(_path, step.extract)
if (step.delete_after_extract) {
sendToRender(`installation:status`, {
...manifest,
statusText: `Deleting temporal files...`,
})
await fs.promises.rm(_path, { recursive: true })
}
}
}

View File

@ -2,12 +2,14 @@ import path from "node:path"
import fs from "node:fs" import fs from "node:fs"
import ChildProcess from "node:child_process" import ChildProcess from "node:child_process"
import sendToRender from "../../utils/sendToRender"
export default async (manifest, step,) => { export default async (manifest, step,) => {
const _path = path.resolve(manifest.packPath, step.path) const _path = path.resolve(manifest.packPath, step.path)
console.log(`Cloning ${step.url}...`) console.log(`Cloning ${step.url}...`)
sendToRenderer(`installation:status`, { sendToRender(`installation:status`, {
...manifest, ...manifest,
statusText: `Cloning ${step.url}`, statusText: `Cloning ${step.url}`,
}) })

View File

@ -2,12 +2,14 @@ import path from "node:path"
import fs from "node:fs" import fs from "node:fs"
import ChildProcess from "node:child_process" import ChildProcess from "node:child_process"
import sendToRender from "../../utils/sendToRender"
export default async (manifest, step) => { export default async (manifest, step) => {
const _path = path.resolve(manifest.packPath, step.path) const _path = path.resolve(manifest.packPath, step.path)
console.log(`Pulling ${step.url}...`) console.log(`Pulling ${step.url}...`)
sendToRenderer(`installation:status`, { sendToRender(`installation:status`, {
...manifest, ...manifest,
statusText: `Pulling ${step.url}`, statusText: `Pulling ${step.url}`,
}) })

View File

@ -6,6 +6,7 @@ import humanFormat from "human-format"
import got from "got" import got from "got"
import sendToRender from "../../utils/sendToRender"
import extractFile from "../../utils/extractFile" import extractFile from "../../utils/extractFile"
function convertSize(size) { function convertSize(size) {
@ -19,7 +20,7 @@ export default async (manifest, step) => {
console.log(`Downloading ${step.url} to ${_path}...`) console.log(`Downloading ${step.url} to ${_path}...`)
sendToRenderer(`installation:status`, { sendToRender(`installation:status`, {
...manifest, ...manifest,
statusText: `Downloading ${step.url}`, statusText: `Downloading ${step.url}`,
}) })
@ -47,7 +48,7 @@ export default async (manifest, step) => {
let lastTransferred = 0 let lastTransferred = 0
sendToRenderer(`installation:status`, { sendToRender(`installation:status`, {
...manifest, ...manifest,
statusText: `Starting download...`, statusText: `Starting download...`,
}) })
@ -63,7 +64,7 @@ export default async (manifest, step) => {
lastTransferred = progress.transferred ?? 0 lastTransferred = progress.transferred ?? 0
sendToRenderer(`installation:${manifest.id}:status`, { sendToRender(`installation:${manifest.id}:status`, {
...manifest, ...manifest,
progress: progress, progress: progress,
statusText: `Downloaded ${convertSize(progress.transferred ?? 0)} / ${convertSize(progress.total)} | ${convertSize(progress.speed)}/s`, statusText: `Downloaded ${convertSize(progress.transferred ?? 0)} / ${convertSize(progress.total)} | ${convertSize(progress.speed)}/s`,
@ -85,7 +86,7 @@ export default async (manifest, step) => {
step.extract = path.resolve(manifest.packPath, ".") step.extract = path.resolve(manifest.packPath, ".")
} }
sendToRenderer(`installation:status`, { sendToRender(`installation:status`, {
...manifest, ...manifest,
statusText: `Extracting bundle...`, statusText: `Extracting bundle...`,
}) })
@ -93,7 +94,7 @@ export default async (manifest, step) => {
await extractFile(_path, step.extract) await extractFile(_path, step.extract)
if (step.delete_after_extract) { if (step.delete_after_extract) {
sendToRenderer(`installation:status`, { sendToRender(`installation:status`, {
...manifest, ...manifest,
statusText: `Deleting temporal files...`, statusText: `Deleting temporal files...`,
}) })