mirror of
https://github.com/whyour/qinglong.git
synced 2025-11-22 16:38:33 +08:00
* Initial plan * Add non-root user guide and improve error messages Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Add PM2_HOME configuration to fix non-root user permission errors Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Fix PM2 socket error by using /tmp for PM2_HOME instead of mounted volume Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Document symlink permission limitation for non-root users Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Clarify that scheduled tasks auto-adapt to use full paths when symlinks unavailable Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Add error handling for symlink creation to prevent worker crashes Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Add practical solutions for non-root users to use ql and task commands Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Modify linkCommand to create symlinks in ~/bin for non-root users Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * 修复链接 task 命令 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> Co-authored-by: whyour <imwhyour@gmail.com>
79 lines
1.9 KiB
TypeScript
79 lines
1.9 KiB
TypeScript
import path from 'path';
|
|
import fs from 'fs/promises';
|
|
import os from 'os';
|
|
import chokidar from 'chokidar';
|
|
import config from '../config/index';
|
|
import { promiseExec } from '../config/util';
|
|
|
|
async function linkToNodeModule(src: string, dst?: string) {
|
|
const target = path.join(config.rootPath, 'node_modules', dst || src);
|
|
const source = path.join(config.rootPath, src);
|
|
|
|
try {
|
|
const stats = await fs.lstat(target);
|
|
if (!stats) {
|
|
await fs.symlink(source, target, 'dir');
|
|
}
|
|
} catch (error) { }
|
|
}
|
|
|
|
async function linkCommand() {
|
|
const homeDir = os.homedir();
|
|
const userBinDir = path.join(homeDir, 'bin');
|
|
|
|
try {
|
|
await fs.mkdir(userBinDir, { recursive: true });
|
|
} catch (error) {
|
|
const commandPath = await promiseExec('which node');
|
|
const commandDir = path.dirname(commandPath);
|
|
return await linkCommandToDir(commandDir);
|
|
}
|
|
|
|
await linkCommandToDir(userBinDir);
|
|
}
|
|
|
|
async function linkCommandToDir(commandDir: string) {
|
|
const linkShell = [
|
|
{
|
|
src: 'update.sh',
|
|
dest: 'ql',
|
|
tmp: 'ql_tmp',
|
|
},
|
|
{
|
|
src: 'task.sh',
|
|
dest: 'task',
|
|
tmp: 'task_tmp',
|
|
},
|
|
];
|
|
|
|
for (const link of linkShell) {
|
|
const source = path.join(config.rootPath, 'shell', link.src);
|
|
const target = path.join(commandDir, link.dest);
|
|
const tmpTarget = path.join(commandDir, link.tmp);
|
|
try {
|
|
const stats = await fs.lstat(tmpTarget);
|
|
if (stats) {
|
|
await fs.unlink(tmpTarget);
|
|
}
|
|
} catch (error) { }
|
|
|
|
await fs.symlink(source, tmpTarget);
|
|
await fs.rename(tmpTarget, target);
|
|
}
|
|
}
|
|
|
|
export default async (src: string = 'deps') => {
|
|
await linkCommand();
|
|
await linkToNodeModule(src);
|
|
|
|
const source = path.join(config.rootPath, src);
|
|
const watcher = chokidar.watch(source, {
|
|
ignored: /(^|[\/\\])\../, // ignore dotfiles
|
|
persistent: true,
|
|
});
|
|
|
|
watcher
|
|
.on('add', () => linkToNodeModule(src))
|
|
.on('change', () => linkToNodeModule(src));
|
|
};
|