From 67579c78e77ce036aa6562866d4cb8bcd34cd15a Mon Sep 17 00:00:00 2001 From: Witherking25 Date: Fri, 17 Feb 2023 13:06:17 -0500 Subject: [PATCH] feat: added support for reloading decky after deployment and removed some debug logging --- .gitignore | 1 + src/index.ts | 108 +++++++++++++++++++++++++++++---------------------- 2 files changed, 63 insertions(+), 46 deletions(-) diff --git a/.gitignore b/.gitignore index d5b3be1..199c462 100644 --- a/.gitignore +++ b/.gitignore @@ -117,3 +117,4 @@ dist # Compiled code lib/ +bin/ diff --git a/src/index.ts b/src/index.ts index 931a9d1..1a09fab 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,21 +8,20 @@ import * as path from 'path'; import * as child_process from 'child_process'; import {glob} from 'glob'; import {Package} from './package'; + let deck: Deck; let plugin: Plugin; let package_: Package; if (fs.existsSync(path.join(process.cwd(), 'package.json'))) { package_ = new Package(require(path.join(process.cwd(), 'package.json'))) - console.log(package_); + // console.log(package_); if (fs.existsSync(path.join(process.cwd(), 'plugin.json'))) { plugin = new Plugin(require(path.join(process.cwd(), 'plugin.json'))); - console.log(plugin); - } - else throw new Error(path.join(process.cwd(), 'plugin.json') + ' does not exist'); -} -else throw new Error(path.join(process.cwd(), 'package.json') + ' does not exist'); + // console.log(plugin); + } else throw new Error(path.join(process.cwd(), 'plugin.json') + ' does not exist'); +} else throw new Error(path.join(process.cwd(), 'package.json') + ' does not exist'); void yargs .scriptName('dbuild') @@ -33,13 +32,20 @@ void yargs handler: build, builder: {}, }) - .command({ - command: 'deploy', - aliases: ['d'], - describe: 'Deploys a plugin to a test deck', - handler: deploy, - builder: {}, - }) + .command<{ reload: boolean }>({ + command: 'deploy', + aliases: ['d'], + describe: 'Deploys a plugin to a test deck', + handler: deploy, + builder: { + 'reload': { + alias: 'r', + describe: 'Reloads decky', + type: 'boolean', + default: false, + } + }, +}) .demand(1, 'must provide a valid command') .help('h') .alias('h', 'help') @@ -51,20 +57,29 @@ function build() { fs.rmdirSync(path.join(process.cwd(), 'build'), { recursive: true - }) + }); fs.mkdirSync(path.join(process.cwd(), 'build', plugin.name, 'dist'), { recursive: true - }) - } - else + }); + } else { fs.mkdirSync(path.join(process.cwd(), 'build', plugin.name, 'dist'), { recursive: true - }) + }); } + let container: string; + + if (fs.existsSync('/var/run/docker.pid')) + { + container = 'docker'; + } else if (fs.existsSync('/usr/bin/podman') && fs.existsSync('/usr/bin/slirp4netns') && fs.existsSync('/usr/bin/fuse-overlayfs')) + { + container = 'podman' + } else throw new Error('podman or docker not found') + //pull docker images - child_process.execSync('docker pull ghcr.io/steamdeckhomebrew/builder:latest') - child_process.execSync('docker pull ghcr.io/steamdeckhomebrew/holo-base:latest') + child_process.execSync(`${container} pull ghcr.io/steamdeckhomebrew/builder:latest`) + child_process.execSync(`${container} pull ghcr.io/steamdeckhomebrew/holo-base:latest`) //backend console.log(`Detecting backend for plugin ${plugin.name}`); @@ -75,19 +90,18 @@ function build() { console.log('Grabbing provided dockerfile.'); console.log('Building provided Dockerfile.'); - child_process.execSync(`docker build -f ${path.join(process.cwd(), 'backend', 'Dockerfile')} -t "${docker_name}" .`) + child_process.execSync(`${container} build -f ${path.join(process.cwd(), 'backend', 'Dockerfile')} -t "${docker_name}" .`) fs.mkdirSync(path.join(process.cwd(), 'build', 'backend', 'out'), { recursive: true }) if (entrypoint_exists) { console.log(`Running docker image "${docker_name}" with provided entrypoint script.`) - child_process.execSync(`docker run --rm -i -v "${path.join(process.cwd(), 'backend')}":/backend -v "${path.join(process.cwd(), 'build', 'backend', 'out')}":/backend/out --entrypoint /backend/entrypoint.sh "${docker_name}"`) - } - else + child_process.execSync(`${container} run --rm -i -v "${path.join(process.cwd(), 'backend')}":/backend -v "${path.join(process.cwd(), 'build', 'backend', 'out')}":/backend/out --entrypoint /backend/entrypoint.sh "${docker_name}"`) + } else { console.log(`Running docker image "${docker_name}" with entrypoint script specified in Dockerfile.`) - child_process.execSync(`docker run --rm -i -v "${path.join(process.cwd(), 'backend')}":/backend -v "${path.join(process.cwd(), 'build', 'backend', 'out')}":/backend/out "${docker_name}"`) + child_process.execSync(`${container} run --rm -i -v "${path.join(process.cwd(), 'backend')}":/backend -v "${path.join(process.cwd(), 'build', 'backend', 'out')}":/backend/out "${docker_name}"`) } fs.mkdirSync(path.join(process.cwd(), 'build', plugin.name, 'bin'), { recursive: true @@ -96,16 +110,15 @@ function build() recursive: true, overwrite: true }) - child_process.execSync(`docker image rm "${docker_name}"`) + child_process.execSync(`${container} image rm "${docker_name}"`) console.log(`Built ${plugin.name} backend`) - } - else if (!dockerfile_exists && entrypoint_exists) + } else if (!dockerfile_exists && entrypoint_exists) { console.log('Grabbing default docker image and using provided entrypoint script.') fs.mkdirSync(path.join(process.cwd(), 'build', 'backend', 'out'), { recursive: true }) - child_process.execSync(`docker run --rm -i -v "${path.join(process.cwd(), 'backend')}":/backend -v "${path.join(process.cwd(), 'build', 'backend', 'out')}":/backend/out ghcr.io/steamdeckhomebrew/holo-base:latest`) + child_process.execSync(`${container} run --rm -i -v "${path.join(process.cwd(), 'backend')}":/backend -v "${path.join(process.cwd(), 'build', 'backend', 'out')}":/backend/out ghcr.io/steamdeckhomebrew/holo-base:latest`) fs.mkdirSync(path.join(process.cwd(), 'build', plugin.name, 'bin'), { recursive: true }) @@ -114,19 +127,18 @@ function build() overwrite: true }) console.log(`Built ${plugin.name} backend`) - } - else + } else { console.log(`Plugin ${plugin.name} does not have a backend`) } //frontend - child_process.execSync(`docker run --rm -i -v "${process.cwd()}":/plugin -v "${path.join(process.cwd(), 'build', plugin.name)}":/out ghcr.io/steamdeckhomebrew/builder:latest`) + child_process.execSync(`${container} run --rm -i -v "${process.cwd()}":/plugin -v "${path.join(process.cwd(), 'build', plugin.name)}":/out ghcr.io/steamdeckhomebrew/builder:latest`) console.log(` Built ${plugin.name} frontend`) //zip const zip = `${plugin.name}-${package_.version}.zip`; - const license = (fs.existsSync(path.join(process.cwd(), 'LICENSE')) ? 'LICENSE' : fs.existsSync(path.join(process.cwd(), 'license')) ? 'license' : fs.existsSync(path.join(process.cwd(), 'LICENSE.md')) ? 'LICENSE.md' : fs.existsSync(path.join(process.cwd(), 'license.md')) ? 'license.md' : undefined) - const readme = (fs.existsSync(path.join(process.cwd(), 'README.md')) ? 'README.md' : fs.existsSync(path.join(process.cwd(), 'readme.md')) ? 'readme.md' : undefined) + const license = (fs.existsSync(path.join(process.cwd(), 'LICENSE')) ? 'LICENSE':fs.existsSync(path.join(process.cwd(), 'license')) ? 'license':fs.existsSync(path.join(process.cwd(), 'LICENSE.md')) ? 'LICENSE.md':fs.existsSync(path.join(process.cwd(), 'license.md')) ? 'license.md':undefined) + const readme = (fs.existsSync(path.join(process.cwd(), 'README.md')) ? 'README.md':fs.existsSync(path.join(process.cwd(), 'readme.md')) ? 'readme.md':undefined) const has_python = glob.sync(path.join(process.cwd(), '*.py')).length > 0 const has_bin = fs.existsSync(path.join(process.cwd(), 'build', plugin.name, 'bin')) const has_defaults = fs.existsSync(path.join(process.cwd(), 'defaults')) @@ -156,14 +168,12 @@ function build() }); child_process.execSync(`zip -r "${path.join(process.cwd(), zip)}" "${path.join(plugin.name, name)}"`) } - } - else + } else { - if (package_.name !== 'decky-plugin-template') + if (!package_.name.includes('plugin-template')) { throw new Error('defaults.txt found in defaults folder, please remove either defaults.txt or the defaults folder.') - } - else + } else { console.log('plugin template, allowing defaults.txt') } @@ -182,19 +192,25 @@ function build() process.chdir('..') } -function deploy() +function deploy(args: yargs.ArgumentsCamelCase<{ reload: boolean }>) { if (fs.existsSync(path.join(process.cwd(), 'deck.json'))) { deck = new Deck(require(path.join(process.cwd(), 'deck.json'))); - console.log(deck); - } - else throw new Error(path.join(process.cwd(), 'deck.json') + ' does not exist'); + // console.log(deck); + } else if (fs.existsSync(path.join(process.cwd(), '.vscode', 'settings.json'))) + { + deck = new Deck(require(path.join(process.cwd(), '.vscode', 'settings.json'))); + } else throw new Error(`${path.join(process.cwd(), 'deck.json')} or ${path.join(process.cwd(), '.vscode', 'settings.json')} does not exist`); build() const zip = `${plugin.name}-${package_.version}.zip`; child_process.execSync(`unzip "${path.join(process.cwd(), 'build', zip)}" -d ${path.join(process.cwd(), 'build', 'deploy')}`) - child_process.execSync(`ssh deck@${deck.deckip} -p ${deck.deckport} ${deck.deckkey.replace('$HOME', process.env.HOME ? process.env.HOME : '')} 'mkdir -p ${deck.deckdir}/homebrew/pluginloader && mkdir -p ${deck.deckdir}/homebrew/plugins'`) - child_process.execSync(`ssh deck@${deck.deckip} -p ${deck.deckport} ${deck.deckkey.replace('$HOME', process.env.HOME ? process.env.HOME : '')} 'echo "${deck.deckpass}" | sudo -S chmod -R ug+rw ${deck.deckdir}/homebrew/'`) - child_process.execSync(`rsync -azp --delete --chmod=D0755,F0755 --rsh='ssh -p ${deck.deckport} ${deck.deckkey.replace('$HOME', process.env.HOME ? process.env.HOME : '')}' "${path.join(process.cwd(), 'build', 'deploy', plugin.name)}" deck@${deck.deckip}:${deck.deckdir}/homebrew/plugins`) + child_process.execSync(`ssh deck@${deck.deckip} -p ${deck.deckport} ${deck.deckkey.replace('$HOME', process.env.HOME ? process.env.HOME:'')} 'mkdir -p ${deck.deckdir}/homebrew/pluginloader && mkdir -p ${deck.deckdir}/homebrew/plugins'`) + child_process.execSync(`ssh deck@${deck.deckip} -p ${deck.deckport} ${deck.deckkey.replace('$HOME', process.env.HOME ? process.env.HOME:'')} 'echo "${deck.deckpass}" | sudo -S chmod -R ug+rw ${deck.deckdir}/homebrew/'`) + child_process.execSync(`rsync -azp --delete --chmod=D0755,F0755 --rsh='ssh -p ${deck.deckport} ${deck.deckkey.replace('$HOME', process.env.HOME ? process.env.HOME:'')}' "${path.join(process.cwd(), 'build', 'deploy', plugin.name)}" deck@${deck.deckip}:${deck.deckdir}/homebrew/plugins`) + if (args.reload) + { + child_process.execSync(`ssh deck@${deck.deckip} -p ${deck.deckport} ${deck.deckkey.replace('$HOME', process.env.HOME ? process.env.HOME:'')} 'echo "${deck.deckpass}" | sudo -S systemctl restart plugin_loader.service'`) + } }