You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
6.2 KiB
177 lines
6.2 KiB
#!/usr/bin/env node
|
|
|
|
/**
|
|
* @file check-electron-prerequisites.js
|
|
* @description Verifies and installs required dependencies for Electron builds
|
|
*
|
|
* This script checks if Python's distutils module is available, which is required
|
|
* by node-gyp when compiling native Node.js modules during Electron packaging.
|
|
* Without distutils, builds will fail with "ModuleNotFoundError: No module named 'distutils'".
|
|
*
|
|
* The script performs the following actions:
|
|
* 1. Checks if Python's distutils module is available
|
|
* 2. If missing, offers to install setuptools package which provides distutils
|
|
* 3. Attempts installation through pip or pip3
|
|
* 4. Provides manual installation instructions if automated installation fails
|
|
*
|
|
* Usage:
|
|
* - Direct execution: node scripts/check-electron-prerequisites.js
|
|
* - As npm script: npm run check:electron
|
|
* - Before builds: npm run check:electron && electron-builder
|
|
*
|
|
* Exit codes:
|
|
* - 0: All prerequisites are met or were successfully installed
|
|
* - 1: Prerequisites are missing and weren't installed
|
|
*
|
|
* @author [YOUR_NAME]
|
|
* @version 1.0.0
|
|
* @license MIT
|
|
*/
|
|
|
|
const { execSync } = require('child_process');
|
|
const readline = require('readline');
|
|
const chalk = require('chalk'); // You might need to add this to your dependencies
|
|
|
|
console.log(chalk.blue('🔍 Checking Electron build prerequisites...'));
|
|
|
|
/**
|
|
* Checks if Python's distutils module is available
|
|
*
|
|
* This function attempts to import the distutils module in Python.
|
|
* If successful, it means node-gyp will be able to compile native modules.
|
|
* If unsuccessful, the Electron build will likely fail when compiling native dependencies.
|
|
*
|
|
* @returns {boolean} True if distutils is available, false otherwise
|
|
*
|
|
* @example
|
|
* if (checkDistutils()) {
|
|
* console.log('Ready to build Electron app');
|
|
* }
|
|
*/
|
|
function checkDistutils() {
|
|
try {
|
|
// Attempt to import distutils using Python
|
|
// We use stdio: 'ignore' to suppress any Python output
|
|
execSync('python -c "import distutils"', { stdio: 'ignore' });
|
|
console.log(chalk.green('✅ Python distutils is available'));
|
|
return true;
|
|
} catch (e) {
|
|
// This error occurs if either Python is not found or if distutils is missing
|
|
console.log(chalk.red('❌ Python distutils is missing'));
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Installs the setuptools package which provides distutils
|
|
*
|
|
* This function attempts to install setuptools using pip or pip3.
|
|
* Setuptools is a package that provides the distutils module needed by node-gyp.
|
|
* In Python 3.12+, distutils was moved out of the standard library into setuptools.
|
|
*
|
|
* The function tries multiple installation methods:
|
|
* 1. First attempts with pip
|
|
* 2. If that fails, tries with pip3
|
|
* 3. If both fail, provides instructions for manual installation
|
|
*
|
|
* @returns {Promise<boolean>} True if installation succeeded, false otherwise
|
|
*
|
|
* @example
|
|
* const success = await installSetuptools();
|
|
* if (success) {
|
|
* console.log('Ready to proceed with build');
|
|
* } else {
|
|
* console.log('Please fix prerequisites manually');
|
|
* }
|
|
*/
|
|
async function installSetuptools() {
|
|
console.log(chalk.yellow('📦 Attempting to install setuptools...'));
|
|
|
|
try {
|
|
// First try with pip, commonly used on all platforms
|
|
execSync('pip install setuptools', { stdio: 'inherit' });
|
|
console.log(chalk.green('✅ Successfully installed setuptools'));
|
|
return true;
|
|
} catch (pipError) {
|
|
try {
|
|
// If pip fails, try with pip3 (common on Linux distributions)
|
|
console.log(chalk.yellow('⚠️ Trying with pip3...'));
|
|
execSync('pip3 install setuptools', { stdio: 'inherit' });
|
|
console.log(chalk.green('✅ Successfully installed setuptools using pip3'));
|
|
return true;
|
|
} catch (pip3Error) {
|
|
// If both methods fail, provide manual installation guidance
|
|
console.log(chalk.red('❌ Failed to install setuptools automatically'));
|
|
console.log(chalk.yellow('📝 Please install it manually with:'));
|
|
console.log(' pip install setuptools');
|
|
console.log(' or');
|
|
console.log(' sudo apt install python3-setuptools (on Debian/Ubuntu)');
|
|
console.log(' sudo pacman -S python-setuptools (on Arch Linux)');
|
|
console.log(' sudo dnf install python3-setuptools (on Fedora)');
|
|
console.log(' brew install python-setuptools (on macOS with Homebrew)');
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Main execution function
|
|
*
|
|
* This function orchestrates the checking and installation process:
|
|
* 1. Checks if distutils is already available
|
|
* 2. If not, informs the user and prompts for installation
|
|
* 3. Based on user input, attempts to install or exits
|
|
*
|
|
* The function handles interactive user prompts and orchestrates
|
|
* the overall flow of the script.
|
|
*
|
|
* @returns {Promise<void>}
|
|
* @throws Will exit process with code 1 if prerequisites aren't met
|
|
*/
|
|
async function main() {
|
|
// First check if distutils is already available
|
|
if (checkDistutils()) {
|
|
// All prerequisites are met, exit successfully
|
|
process.exit(0);
|
|
}
|
|
|
|
// Inform the user about the missing prerequisite
|
|
console.log(chalk.yellow('⚠️ Python distutils is required for Electron builds'));
|
|
console.log(chalk.yellow('⚠️ This is needed to compile native modules during the build process'));
|
|
|
|
// Set up readline interface for user interaction
|
|
const rl = readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout
|
|
});
|
|
|
|
// Prompt the user for installation permission
|
|
const answer = await new Promise(resolve => {
|
|
rl.question(chalk.blue('Would you like to install setuptools now? (y/n) '), resolve);
|
|
});
|
|
|
|
// Clean up readline interface
|
|
rl.close();
|
|
|
|
if (answer.toLowerCase() === 'y') {
|
|
// User agreed to installation
|
|
const success = await installSetuptools();
|
|
if (success) {
|
|
// Installation succeeded, exit successfully
|
|
process.exit(0);
|
|
} else {
|
|
// Installation failed, exit with error
|
|
process.exit(1);
|
|
}
|
|
} else {
|
|
// User declined installation
|
|
console.log(chalk.yellow('⚠️ Build may fail without distutils'));
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Execute the main function and handle any uncaught errors
|
|
main().catch(error => {
|
|
console.error(chalk.red('Error during prerequisites check:'), error);
|
|
process.exit(1);
|
|
});
|