petcarescript
Version:
PetCareScript - A modern, expressive programming language designed for humans with async, HTTP, database, and testing support
234 lines (198 loc) • 8.35 kB
JavaScript
/**
* Cross-platform file association installer
*/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const os = require('os');
class FileAssociationInstaller {
constructor() {
this.platform = os.platform();
this.projectRoot = path.resolve(__dirname, '..');
}
install() {
console.log('🔗 Installing file associations for PetCareScript...');
// Generate icons first
this.generateIcons();
switch (this.platform) {
case 'win32':
this.installWindows();
break;
case 'darwin':
this.installMacOS();
break;
case 'linux':
this.installLinux();
break;
default:
console.warn(`⚠️ Platform ${this.platform} not supported for automatic file association`);
}
}
generateIcons() {
try {
console.log('🎨 Generating icons...');
const IconGenerator = require('./generate-icons');
const generator = new IconGenerator();
generator.generate();
} catch (error) {
console.warn('⚠️ Could not generate icons:', error.message);
}
}
installWindows() {
console.log('🪟 Installing Windows file associations...');
try {
// Check if running as administrator
execSync('net session', { stdio: 'ignore' });
} catch (error) {
console.error('❌ This script must be run as Administrator on Windows');
console.log('Please run PowerShell as Administrator and try again');
return;
}
try {
const regFile = path.join(this.projectRoot, 'windows', 'file-association.reg');
if (fs.existsSync(regFile)) {
execSync(`reg import "${regFile}"`, { stdio: 'inherit' });
console.log('✅ Windows file associations installed!');
} else {
console.warn('⚠️ Registry file not found. Creating basic association...');
this.createBasicWindowsAssociation();
}
} catch (error) {
console.error('❌ Failed to install Windows file associations:', error.message);
}
}
createBasicWindowsAssociation() {
try {
const commands = [
'reg add "HKCR\\.pcs" /ve /d "PetCareScript.SourceFile" /f',
'reg add "HKCR\\PetCareScript.SourceFile" /ve /d "PetCareScript Source File" /f',
'reg add "HKCR\\PetCareScript.SourceFile\\shell\\open\\command" /ve /d "\\"pcs\\" \\"%1\\"" /f'
];
for (const command of commands) {
execSync(command, { stdio: 'ignore' });
}
console.log('✅ Basic Windows file association created!');
} catch (error) {
console.error('❌ Failed to create basic Windows association:', error.message);
}
}
installMacOS() {
console.log('🍎 Installing macOS file associations...');
// macOS file associations are typically handled by applications
// This would require creating a proper .app bundle
console.log('⚠️ macOS file associations require a proper application bundle');
console.log('For now, you can manually associate .pcs files with Terminal or your preferred editor');
}
installLinux() {
console.log('🐧 Installing Linux file associations...');
try {
const commands = [
// Install MIME type
'sudo cp mime/petcarescript.xml /usr/share/mime/packages/ 2>/dev/null || true',
'sudo update-mime-database /usr/share/mime 2>/dev/null || true',
// Install desktop file
'sudo cp linux/petcarescript.desktop /usr/share/applications/ 2>/dev/null || true',
'sudo update-desktop-database /usr/share/applications 2>/dev/null || true',
// Install icons
this.getLinuxIconCommands().join(' && ')
];
for (const command of commands) {
try {
execSync(command, { cwd: this.projectRoot, stdio: 'inherit' });
} catch (error) {
console.warn(`⚠️ Command failed: ${command}`);
}
}
console.log('✅ Linux file associations installed!');
console.log('You may need to log out and back in for changes to take effect');
} catch (error) {
console.error('❌ Failed to install Linux file associations:', error.message);
}
}
getLinuxIconCommands() {
const commands = [];
const sizes = [16, 32, 48, 64, 128, 256];
const iconsBase = '/usr/share/icons/hicolor';
for (const size of sizes) {
commands.push(
`sudo mkdir -p "${iconsBase}/${size}x${size}/mimetypes"`,
`sudo cp "icons/petcarescript-${size}.png" "${iconsBase}/${size}x${size}/mimetypes/application-x-petcarescript.png" 2>/dev/null || true`
);
}
commands.push(
`sudo mkdir -p "${iconsBase}/scalable/mimetypes"`,
`sudo cp "icons/petcarescript.svg" "${iconsBase}/scalable/mimetypes/application-x-petcarescript.svg" 2>/dev/null || true`,
`sudo gtk-update-icon-cache "${iconsBase}" 2>/dev/null || true`
);
return commands;
}
uninstall() {
console.log('🗑️ Removing file associations...');
switch (this.platform) {
case 'win32':
this.uninstallWindows();
break;
case 'linux':
this.uninstallLinux();
break;
default:
console.log('Manual removal may be required for this platform');
}
}
uninstallWindows() {
try {
const commands = [
'reg delete "HKCR\\.pcs" /f',
'reg delete "HKCR\\PetCareScript.SourceFile" /f'
];
for (const command of commands) {
try {
execSync(command, { stdio: 'ignore' });
} catch (error) {
// Ignore errors for already deleted keys
}
}
console.log('✅ Windows file associations removed!');
} catch (error) {
console.error('❌ Failed to remove Windows file associations:', error.message);
}
}
uninstallLinux() {
try {
const commands = [
'sudo rm -f /usr/share/mime/packages/petcarescript.xml',
'sudo update-mime-database /usr/share/mime 2>/dev/null || true',
'sudo rm -f /usr/share/applications/petcarescript.desktop',
'sudo update-desktop-database /usr/share/applications 2>/dev/null || true'
];
// Remove icons
const sizes = [16, 32, 48, 64, 128, 256];
for (const size of sizes) {
commands.push(`sudo rm -f "/usr/share/icons/hicolor/${size}x${size}/mimetypes/application-x-petcarescript.png"`);
}
commands.push('sudo rm -f "/usr/share/icons/hicolor/scalable/mimetypes/application-x-petcarescript.svg"');
commands.push('sudo gtk-update-icon-cache "/usr/share/icons/hicolor" 2>/dev/null || true');
for (const command of commands) {
try {
execSync(command, { stdio: 'ignore' });
} catch (error) {
// Ignore errors
}
}
console.log('✅ Linux file associations removed!');
} catch (error) {
console.error('❌ Failed to remove Linux file associations:', error.message);
}
}
}
// Execute if run directly
if (require.main === module) {
const installer = new FileAssociationInstaller();
const action = process.argv[2];
if (action === '--uninstall') {
installer.uninstall();
} else {
installer.install();
}
}
module.exports = FileAssociationInstaller;