Spaces:
reon314
/
Runtime error

File size: 4,416 Bytes
3b6afc0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
const { execSync } = require('child_process');
const path = require('path');
const fs = require('fs');
const { askQuestion, isDockerRunning, silentExit } = require('./helpers');

const config = {
  localUpdate: process.argv.includes('-l'),
  dockerUpdate: process.argv.includes('-d'),
  useSingleComposeFile: process.argv.includes('-s'),
};

// 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 function updateConfigWithWizard() {
  if (!config.dockerUpdate && !config.useSingleComposeFile) {
    config.dockerUpdate = (await askQuestion('Are you using Docker? (y/n): '))
      .toLowerCase()
      .startsWith('y');
  }

  if (config.dockerUpdate && !config.useSingleComposeFile) {
    config.useSingleComposeFile = !(
      await askQuestion('Are you using the default docker-compose file? (y/n): ')
    )
      .toLowerCase()
      .startsWith('y');
  }
}

async function validateDockerRunning() {
  if (!config.dockerUpdate && config.useSingleComposeFile) {
    config.dockerUpdate = true;
  }

  if (config.dockerUpdate && !isDockerRunning()) {
    console.red(
      'Error: Docker is not running. You will need to start Docker Desktop or if using linux/mac, run `sudo systemctl start docker`',
    );
    silentExit(1);
  }
}

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;

  if (showWizard) {
    await updateConfigWithWizard();
  }

  await validateDockerRunning();
  const { dockerUpdate, useSingleComposeFile: singleCompose } = config;

  // Fetch latest repo
  console.purple('Fetching the latest repo...');
  execSync('git fetch origin', { stdio: 'inherit' });

  // Switch to main branch
  console.purple('Switching to main branch...');
  execSync('git checkout main', { stdio: 'inherit' });

  // Git pull origin main
  console.purple('Pulling the latest code from main...');
  execSync('git pull origin main', { stdio: 'inherit' });

  if (dockerUpdate) {
    console.purple('Removing previously made Docker container...');
    const downCommand = `docker-compose ${
      singleCompose ? '-f ./docs/dev/single-compose.yml ' : ''
    }down --volumes`;
    console.orange(downCommand);
    execSync(downCommand, { stdio: 'inherit' });
    console.purple('Pruning all LibreChat Docker images...');

    const imageName = singleCompose ? 'librechat_single' : 'librechat';
    try {
      execSync(`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' });
    console.purple('Building new LibreChat image...');
    const buildCommand = `docker-compose ${
      singleCompose ? '-f ./docs/dev/single-compose.yml ' : ''
    }build`;
    console.orange(buildCommand);
    execSync(buildCommand, { stdio: 'inherit' });
  } else {
    // 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 ci', { stdio: 'inherit' });

    // Build client-side code
    console.purple('Building frontend...');
    execSync('npm run frontend', { stdio: 'inherit' });
  }

  let startCommand = 'npm run backend';
  if (dockerUpdate) {
    startCommand = `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);
  console.orange(
    'Note: it\'s also recommended to clear your browser cookies and localStorage for LibreChat to assure a fully clean installation.',
  );
  console.orange('Also: Don\'t worry, your data is safe :)');
})();