Files
meteor/packages/tools-core/lib/git.js
2025-07-29 17:12:25 +02:00

139 lines
4.7 KiB
JavaScript

import fs from 'fs';
import path from 'path';
import { logProgress, logSuccess, logInfo, logError } from './log';
/**
* Checks if the given directory is a git repository
* @param {string} dir - Directory to check
* @returns {boolean} - True if the directory is a git repository
*/
export function isGitRepository(dir) {
try {
const gitDir = path.join(dir, '.git');
return fs.existsSync(gitDir) && fs.statSync(gitDir).isDirectory();
} catch (error) {
return false;
}
}
/**
* Checks if a .gitignore file exists in the given directory
* @param {string} dir - Directory to check
* @returns {boolean} - True if .gitignore exists
*/
export function gitignoreExists(dir) {
try {
const gitignorePath = path.join(dir, '.gitignore');
return fs.existsSync(gitignorePath);
} catch (error) {
return false;
}
}
/**
* Creates a .gitignore file in the given directory if it doesn't exist
* @param {string} dir - Directory where to create .gitignore
* @param {string[]} [initialEntries=[]] - Initial entries to add to the .gitignore file
* @returns {boolean} - True if .gitignore was created or already exists
*/
export function ensureGitignoreExists(dir, initialEntries = []) {
const gitignorePath = path.join(dir, '.gitignore');
if (!gitignoreExists(dir)) {
try {
const content = initialEntries.length > 0 ? initialEntries.join('\n') + '\n' : '';
fs.writeFileSync(gitignorePath, content, 'utf8');
return true;
} catch (error) {
console.error(`Error creating .gitignore file: ${error.message}`);
return false;
}
}
return true;
}
/**
* Checks if specific entries exist in the .gitignore file
* @param {string} dir - Directory containing the .gitignore file
* @param {string[]} entries - Entries to check
* @returns {string[]} - Entries that don't exist in the .gitignore file
*/
export function getMissingGitignoreEntries(dir, entries) {
if (!gitignoreExists(dir)) {
return entries;
}
try {
const gitignorePath = path.join(dir, '.gitignore');
const content = fs.readFileSync(gitignorePath, 'utf8');
const lines = content.split('\n').map(line => line.trim());
return entries.filter(entry => !lines.includes(entry));
} catch (error) {
console.error(`Error reading .gitignore file: ${error.message}`);
return entries;
}
}
/**
* Adds entries to the .gitignore file if they don't exist
* @param {string} dir - Directory containing the .gitignore file
* @param {string[]} entries - Entries to add
* @param {string} [context] - Optional context to add as a comment before the entries
* @returns {boolean} - True if entries were added successfully
*/
export function addGitignoreEntries(dir, entries, context = '') {
// Ensure .gitignore exists
if (!ensureGitignoreExists(dir)) {
return false;
}
// Get entries that don't exist
const missingEntries = getMissingGitignoreEntries(dir, entries);
if (missingEntries.length === 0) {
return true; // All entries already exist
}
// Display a header for the gitignore entries addition
logProgress(`┌─────────────────────────────────────────────────`);
logProgress(`│ Adding Gitignore Entries${context ? ` for ${context}` : ''}`);
logProgress(`└─────────────────────────────────────────────────`);
// Show what entries will be added
logInfo(`The following entries will be added to .gitignore:`);
missingEntries.forEach(entry => {
logInfo(`${entry}`);
});
try {
const gitignorePath = path.join(dir, '.gitignore');
let content = '';
if (fs.existsSync(gitignorePath)) {
content = fs.readFileSync(gitignorePath, 'utf8');
// Ensure there's a newline at the end if the file is not empty
if (content.length > 0 && !content.endsWith('\n')) {
content += '\n';
}
}
// Add context as a comment if provided
if (context) {
content += `\n# ${context}\n`;
}
content += missingEntries.join('\n') + '\n';
fs.writeFileSync(gitignorePath, content, 'utf8');
logSuccess(`✅ Gitignore entries${context ? ` for ${context}` : ''} added`);
return true;
} catch (error) {
logError(`\n┌─────────────────────────────────────────────────`);
logError(`│ ❌ Failed to Add Gitignore Entries${context ? ` for ${context}` : ''}`);
logError(`└─────────────────────────────────────────────────`);
logError(`Error: ${error.message}`);
return false;
}
}