From 777d64088b3685401871d4543eac531e5b061f2b Mon Sep 17 00:00:00 2001 From: Danny Avila <110412045+danny-avila@users.noreply.github.com> Date: Thu, 27 Jul 2023 11:11:56 -0400 Subject: [PATCH] feat: stop-backend.js and update.js linux support (#712) * chore(dependabot.yml): update target-branch from "develop" to "dev" for npm package updates in /api, /client, and root directory * feat: stop-backend.js and update.js linux support (#701) * feat: stop-backend.js and update.js linux support * feat: update.js sudo support * chore(helpers.js): add deleteNodeModules function feat(packages.js): add script to delete node_modules and install dependencies refactor(update.js): remove unnecessary imports and use deleteNodeModules function feat(package.json): add update:linux script to update with sudo * chore(package.json): rename 'update:linux' script to 'update:sudo' * refactor(update.js): simplify downCommand and buildCommand by removing redundant use of sudo command, add sudo to single docker command --------- Co-authored-by: Fuegovic <32828263+fuegovic@users.noreply.github.com> --- .github/dependabot.yml | 6 +++--- config/helpers.js | 11 +++++++++++ config/packages.js | 26 ++++++++++++++++++++++++++ config/stop-backend.js | 23 +++++++++++++++++++++++ config/update.js | 32 +++++++++++++++----------------- package.json | 2 ++ 6 files changed, 80 insertions(+), 20 deletions(-) create mode 100644 config/packages.js create mode 100644 config/stop-backend.js diff --git a/.github/dependabot.yml b/.github/dependabot.yml index eb933db57..ccdc68d81 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,7 +7,7 @@ version: 2 updates: - package-ecosystem: "npm" # See documentation for possible values directory: "/api" # Location of package manifests - target-branch: "develop" + target-branch: "dev" versioning-strategy: increase-if-necessary schedule: interval: "weekly" @@ -20,7 +20,7 @@ updates: include: "scope" - package-ecosystem: "npm" # See documentation for possible values directory: "/client" # Location of package manifests - target-branch: "develop" + target-branch: "dev" versioning-strategy: increase-if-necessary schedule: interval: "weekly" @@ -33,7 +33,7 @@ updates: include: "scope" - package-ecosystem: "npm" # See documentation for possible values directory: "/" # Location of package manifests - target-branch: "develop" + target-branch: "dev" versioning-strategy: increase-if-necessary schedule: interval: "weekly" diff --git a/config/helpers.js b/config/helpers.js index b3d7e7db0..dad22bad1 100644 --- a/config/helpers.js +++ b/config/helpers.js @@ -2,6 +2,8 @@ * Helper functions * This allows us to give the console some colour when running in a terminal */ +const fs = require('fs'); +const path = require('path'); const readline = require('readline'); const { execSync } = require('child_process'); @@ -28,6 +30,14 @@ function isDockerRunning() { } } +function deleteNodeModules(dir) { + const nodeModulesPath = path.join(dir, 'node_modules'); + if (fs.existsSync(nodeModulesPath)) { + console.purple(`Deleting node_modules in ${dir}`); + fs.rmdirSync(nodeModulesPath, { recursive: true }); + } +} + const silentExit = (code = 0) => { console.log = () => {}; process.exit(code); @@ -48,4 +58,5 @@ module.exports = { askQuestion, silentExit, isDockerRunning, + deleteNodeModules, }; diff --git a/config/packages.js b/config/packages.js new file mode 100644 index 000000000..43f479ed2 --- /dev/null +++ b/config/packages.js @@ -0,0 +1,26 @@ +const { execSync } = require('child_process'); +const path = require('path'); + +const { deleteNodeModules } = require('./helpers'); + +// Set the directories +const rootDir = path.resolve(__dirname, '..'); +const directories = [ + rootDir, + path.resolve(rootDir, 'packages', 'data-provider'), + path.resolve(rootDir, 'client'), + path.resolve(rootDir, 'api'), +]; + +(async () => { + // Delete all node_modules + directories.forEach(deleteNodeModules); + + // Run npm cache clean --force + console.purple('Cleaning npm cache...'); + execSync('npm cache clean --force', { stdio: 'inherit' }); + + // Install dependencies + console.purple('Installing dependencies...'); + execSync('npm install', { stdio: 'inherit' }); +})(); diff --git a/config/stop-backend.js b/config/stop-backend.js new file mode 100644 index 000000000..e863a03ee --- /dev/null +++ b/config/stop-backend.js @@ -0,0 +1,23 @@ +// eslint-disable-next-line +const helpers = require('./helpers'); +const { exec } = require('child_process'); +const { promisify } = require('util'); + +const isWindows = process.platform === 'win32'; +const execAsync = promisify(exec); + +async function main() { + try { + if (isWindows) { + console.red('The backend process has been terminated'); + await execAsync('taskkill /F /IM node.exe /T'); + } else { + await execAsync('pkill -f api/server/index.js'); + console.orange('The backend process has been terminated'); + } + } catch (err) { + console.red('The backend process has been terminated', err.message); + } +} + +main(); diff --git a/config/update.js b/config/update.js index 567528f7c..61c154f6e 100644 --- a/config/update.js +++ b/config/update.js @@ -1,12 +1,12 @@ const { execSync } = require('child_process'); const path = require('path'); -const fs = require('fs'); -const { askQuestion, isDockerRunning, silentExit } = require('./helpers'); +const { askQuestion, isDockerRunning, deleteNodeModules, silentExit } = require('./helpers'); const config = { localUpdate: process.argv.includes('-l'), dockerUpdate: process.argv.includes('-d'), useSingleComposeFile: process.argv.includes('-s'), + useSudo: process.argv.includes('--sudo'), }; // Set the directories @@ -47,14 +47,6 @@ async function validateDockerRunning() { } } -function deleteNodeModules(dir) { - const nodeModulesPath = path.join(dir, 'node_modules'); - if (fs.existsSync(nodeModulesPath)) { - console.purple(`Deleting node_modules in ${dir}`); - execSync(`rd /s /q "${nodeModulesPath}"`, { stdio: 'inherit', shell: 'cmd.exe' }); - } -} - (async () => { const showWizard = !config.localUpdate && !config.dockerUpdate && !config.useSingleComposeFile; @@ -62,9 +54,13 @@ function deleteNodeModules(dir) { await updateConfigWithWizard(); } - await validateDockerRunning(); - const { dockerUpdate, useSingleComposeFile: singleCompose } = config; + console.green( + 'Starting update script, this may take a minute or two depending on your system and network.', + ); + await validateDockerRunning(); + const { dockerUpdate, useSingleComposeFile: singleCompose, useSudo } = config; + const sudo = useSudo ? 'sudo ' : ''; // Fetch latest repo console.purple('Fetching the latest repo...'); execSync('git fetch origin', { stdio: 'inherit' }); @@ -79,7 +75,7 @@ function deleteNodeModules(dir) { if (dockerUpdate) { console.purple('Removing previously made Docker container...'); - const downCommand = `docker-compose ${ + const downCommand = `${sudo}docker-compose ${ singleCompose ? '-f ./docs/dev/single-compose.yml ' : '' }down --volumes`; console.orange(downCommand); @@ -88,14 +84,14 @@ function deleteNodeModules(dir) { const imageName = singleCompose ? 'librechat_single' : 'librechat'; try { - execSync(`docker rmi ${imageName}:latest`, { stdio: 'inherit' }); + execSync(`${sudo}docker rmi ${imageName}:latest`, { stdio: 'inherit' }); } catch (e) { console.purple('Failed to remove Docker image librechat:latest. It might not exist.'); } console.purple('Removing all unused dangling Docker images...'); - execSync('docker image prune -f', { stdio: 'inherit' }); + execSync(`${sudo}docker image prune -f`, { stdio: 'inherit' }); console.purple('Building new LibreChat image...'); - const buildCommand = `docker-compose ${ + const buildCommand = `${sudo}docker-compose ${ singleCompose ? '-f ./docs/dev/single-compose.yml ' : '' }build`; console.orange(buildCommand); @@ -119,7 +115,9 @@ function deleteNodeModules(dir) { let startCommand = 'npm run backend'; if (dockerUpdate) { - startCommand = `docker-compose ${singleCompose ? '-f ./docs/dev/single-compose.yml ' : ''}up`; + startCommand = `${sudo}docker-compose ${ + singleCompose ? '-f ./docs/dev/single-compose.yml ' : '' + }up`; } console.green('Your LibreChat app is now up to date! Start the app with the following command:'); console.purple(startCommand); diff --git a/package.json b/package.json index 8e42b9474..a31188b25 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,12 @@ "update:local": "node config/update.js -l", "update:docker": "node config/update.js -d", "update:single": "node config/update.js -s", + "update:sudo": "node config/update.js --sudo", "upgrade": "node config/upgrade.js", "create-user": "node config/create-user.js", "backend": "cross-env NODE_ENV=production node api/server/index.js", "backend:dev": "cross-env NODE_ENV=development npx nodemon api/server/index.js", + "backend:stop": "node config/stop-backend.js", "build:data-provider": "cd packages/data-provider && npm run build", "frontend": "npm run build:data-provider && cd client && npm run build", "frontend:ci": "npm run build:data-provider && cd client && npm run build:ci",