77 lines
3.1 KiB
JavaScript
77 lines
3.1 KiB
JavaScript
import { SlashCommandBuilder, PermissionFlagsBits } from 'discord.js';
|
|
import { exec } from 'child_process';
|
|
import { promisify } from 'util';
|
|
const execAsync = promisify(exec);
|
|
|
|
/**
|
|
* Git-related slash commands: /gitstatus and /gitpull
|
|
*/
|
|
export const commands = [
|
|
// Show current branch and commit status
|
|
{
|
|
data: new SlashCommandBuilder()
|
|
.setName('gitstatus')
|
|
.setDescription('Show current git branch and remote status'),
|
|
async execute(interaction, client) {
|
|
try {
|
|
// Get current branch and commit
|
|
const { stdout: branchOut } = await execAsync('git rev-parse --abbrev-ref HEAD');
|
|
const branch = branchOut.trim();
|
|
const { stdout: localOut } = await execAsync('git rev-parse HEAD');
|
|
const local = localOut.trim().slice(0, 7);
|
|
// Fetch updates and get remote commit
|
|
await execAsync('git fetch --quiet');
|
|
const { stdout: remoteOut } = await execAsync(`git rev-parse origin/${branch}`);
|
|
const remote = remoteOut.trim().slice(0, 7);
|
|
// Determine ahead/behind counts
|
|
const { stdout: behindOut } = await execAsync(`git rev-list --count HEAD..origin/${branch}`);
|
|
const behind = parseInt(behindOut.trim(), 10);
|
|
const { stdout: aheadOut } = await execAsync(`git rev-list --count origin/${branch}..HEAD`);
|
|
const ahead = parseInt(aheadOut.trim(), 10);
|
|
const status = (ahead === 0 && behind === 0)
|
|
? 'Up-to-date' : `${ahead} ahead, ${behind} behind`;
|
|
// Reply with status
|
|
await interaction.reply({
|
|
content: `Branch: \`${branch}\`\nLocal: \`${local}\`\nRemote: \`${remote}\`\nStatus: ${status}`,
|
|
ephemeral: true
|
|
});
|
|
} catch (err) {
|
|
client.logger.error(`Error in gitstatus: ${err.message}`);
|
|
await interaction.reply({ content: `Failed to get git status: ${err.message}`, ephemeral: true });
|
|
}
|
|
}
|
|
},
|
|
// Pull latest changes and restart bot (owner only)
|
|
{
|
|
data: new SlashCommandBuilder()
|
|
.setName('gitpull')
|
|
.setDescription('Pull latest changes and restart bot (Owner only)')
|
|
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
|
|
async execute(interaction, client) {
|
|
const ownerId = client.config.owner;
|
|
if (interaction.user.id !== ownerId) {
|
|
return interaction.reply({ content: 'Only the bot owner can perform this action.', ephemeral: true });
|
|
}
|
|
await interaction.deferReply({ ephemeral: true });
|
|
try {
|
|
// Pull with fast-forward only
|
|
const { stdout, stderr } = await execAsync('git pull --ff-only');
|
|
const output = stdout.trim() || stderr.trim();
|
|
await interaction.editReply({
|
|
content: `Git pull output:\n\`\`\`\n${output}\n\`\`\`\nRestarting...`
|
|
});
|
|
setTimeout(() => process.exit(0), 1000);
|
|
} catch (err) {
|
|
client.logger.error(`Error in gitpull: ${err.message}`);
|
|
await interaction.editReply({ content: `Git pull failed: ${err.message}`, ephemeral: true });
|
|
}
|
|
}
|
|
}
|
|
];
|
|
|
|
/**
|
|
* No special init logic for git utilities
|
|
*/
|
|
export async function init(client, config) {
|
|
client.logger.info('Git utilities module loaded');
|
|
} |