Blame Raw
Cohee · e3f41666 · · 97 lines (3.4 KB)
1 contributor
1// Plugin manager script.
2// Usage:
3// 1. node plugins.js update
4// 2. node plugins.js install <plugin-git-url>
5// More operations coming soon.
6import fs from 'node:fs';
7import path from 'node:path';
8import process from 'node:process';
9import { fileURLToPath } from 'node:url';
10
11import { default as git, CheckRepoActions } from 'simple-git';
12import { createGitClient } from './src/git/client.js';
13import { color } from './src/util.js';
14
15const __dirname = import.meta.dirname ?? path.dirname(fileURLToPath(import.meta.url));
16process.chdir(__dirname);
17const pluginsPath = './plugins';
18const gitBackend = process.env.SILLYTAVERN_GIT_BACKEND || 'auto';
19
20const command = process.argv[2];
21
22if (!command) {
23 console.log('Usage: node plugins.js <command>');
24 console.log('Commands:');
25 console.log(' update - Update all installed plugins');
26 console.log(' install <plugin-git-url> - Install plugin from a Git URL');
27 process.exit(1);
28}
29
30if (command === 'update') {
31 console.log(color.magenta('Updating all plugins'));
32 updatePlugins();
33}
34
35if (command === 'install') {
36 const pluginName = process.argv[3];
37 console.log('Installing a new plugin', color.green(pluginName));
38 installPlugin(pluginName);
39}
40
41async function updatePlugins() {
42 const directories = fs.readdirSync(pluginsPath)
43 .filter(file => !file.startsWith('.'))
44 .filter(file => fs.statSync(path.join(pluginsPath, file)).isDirectory());
45
46 console.log(`Found ${color.cyan(directories.length)} directories in ./plugins`);
47
48 for (const directory of directories) {
49 try {
50 console.log(`Updating plugin ${color.green(directory)}...`);
51 const pluginPath = path.join(pluginsPath, directory);
52 const pluginRepo = git(pluginPath);
53
54 const isRepo = await pluginRepo.checkIsRepo(CheckRepoActions.IS_REPO_ROOT);
55 if (!isRepo) {
56 console.log(`Directory ${color.yellow(directory)} is not a Git repository`);
57 continue;
58 }
59
60 await pluginRepo.fetch();
61 const commitHash = await pluginRepo.revparse(['HEAD']);
62 const trackingBranch = await pluginRepo.revparse(['--abbrev-ref', '@{u}']);
63 const log = await pluginRepo.log({
64 from: commitHash,
65 to: trackingBranch,
66 });
67
68 if (log.total === 0) {
69 console.log(`Plugin ${color.blue(directory)} is already up to date`);
70 continue;
71 }
72
73 await pluginRepo.pull();
74 const latestCommit = await pluginRepo.revparse(['HEAD']);
75 console.log(`Plugin ${color.green(directory)} updated to commit ${color.cyan(latestCommit)}`);
76 } catch (error) {
77 console.error(color.red(`Failed to update plugin ${directory}: ${error.message}`));
78 }
79 }
80
81 console.log(color.magenta('All plugins updated!'));
82}
83
84async function installPlugin(pluginName) {
85 try {
86 const pluginPath = path.join(pluginsPath, path.basename(pluginName, '.git'));
87
88 if (fs.existsSync(pluginPath)) {
89 return console.log(color.yellow(`Directory already exists at ${pluginPath}`));
90 }
91
92 await createGitClient({ backend: gitBackend }).clone(pluginName, pluginPath, { depth: 1 });
93 console.log(`Plugin ${color.green(pluginName)} installed to ${color.cyan(pluginPath)}`);
94 } catch (error) {
95 console.error(color.red(`Failed to install plugin ${pluginName}`), error);
96 }
97}