no-migration
Version:
CLI tool to manage migration changes and user changes separately for React Native miniapp projects
170 lines ⢠8.55 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.commitCommand = commitCommand;
const chalk_1 = __importDefault(require("chalk"));
const gitHelper_1 = require("../utils/gitHelper");
const fileManager_1 = require("../utils/fileManager");
const diffHelper_1 = require("../utils/diffHelper");
async function commitCommand(options) {
try {
console.log(chalk_1.default.blue('š Starting commit process...'));
// Validate message
if (!options.message && !options.amend) {
console.error(chalk_1.default.red('ā Error: Commit message is required (use -m "message")'));
process.exit(1);
}
const git = new gitHelper_1.GitHelper();
// Read tracking files
const excludeList = fileManager_1.FileManager.readExcludeList();
const migrationChanges = fileManager_1.FileManager.readMigrationChanges();
if (excludeList.length === 0) {
console.log(chalk_1.default.yellow('ā ļø No exclude list found. Committing all staged changes...'));
await git.commit(options.message || '', {
amend: options.amend,
noEdit: options.noEdit,
});
console.log(chalk_1.default.green('ā
Committed successfully!'));
return;
}
console.log(chalk_1.default.cyan(`š Processing ${excludeList.length} files in exclude list...`));
// Get current status
const status = await git.getStatus();
const allChangedFiles = new Set([...status.staged, ...status.unstaged]);
// Step 1: Unstage all files in exclude list
console.log(chalk_1.default.cyan('š¤ Unstaging files from exclude list...'));
const stagedExcludeFiles = excludeList.filter(f => status.staged.includes(f));
if (stagedExcludeFiles.length > 0) {
await git.unstageFiles(stagedExcludeFiles);
}
// Step 2: For each file in exclude list, separate user changes from migration changes
console.log(chalk_1.default.cyan('š Separating user changes from migration changes...'));
const filesToProcess = [];
const fileContents = new Map();
for (const filePath of excludeList) {
if (!allChangedFiles.has(filePath)) {
continue; // File not changed
}
const currentContent = git.getFileContent(filePath);
if (!currentContent) {
// File was deleted - check if it's in migration changes
if (migrationChanges?.files[filePath]?.status === 'deleted') {
// This is migration deletion, don't stage it
continue;
}
else {
// User deletion, stage it
filesToProcess.push(filePath);
}
continue;
}
// Get baseline content (from HEAD)
const baselineContent = await git.getFileContentFromGit(filePath);
if (!baselineContent) {
// New file - check if it's from migration
if (migrationChanges?.files[filePath]?.status === 'added') {
// Compare with migration content
const migrationContent = migrationChanges.files[filePath].content || '';
if (currentContent !== migrationContent) {
// File has both migration and user changes
const { userContent, migrationOnlyContent } = diffHelper_1.DiffHelper.separateUserChanges('', migrationContent, currentContent);
fileContents.set(filePath, {
user: userContent,
migration: migrationOnlyContent,
});
filesToProcess.push(filePath);
}
// else: pure migration change, don't stage
}
else {
// Pure user addition
filesToProcess.push(filePath);
}
continue;
}
// File was modified
const migrationFileChange = migrationChanges?.files[filePath];
if (!migrationFileChange) {
// No migration changes for this file, stage all user changes
filesToProcess.push(filePath);
continue;
}
const migrationContent = migrationFileChange.content || baselineContent;
// Check if there are user changes beyond migration
if (currentContent === migrationContent) {
// Only migration changes, don't stage
continue;
}
if (currentContent === baselineContent) {
// No changes anymore, skip
continue;
}
// Separate user changes from migration changes
const { userContent, migrationOnlyContent } = diffHelper_1.DiffHelper.separateUserChanges(baselineContent, migrationContent, currentContent);
fileContents.set(filePath, {
user: userContent,
migration: migrationOnlyContent,
});
filesToProcess.push(filePath);
}
// Step 3: Apply user-only changes and stage them
if (filesToProcess.length > 0) {
console.log(chalk_1.default.cyan(`āļø Applying user changes to ${filesToProcess.length} file(s)...`));
for (const filePath of filesToProcess) {
const contents = fileContents.get(filePath);
if (contents) {
// Write user-only content
git.writeFileContent(filePath, contents.user);
}
}
// Stage the files with user changes
await git.stageFiles(filesToProcess);
// Restore migration changes (unstaged)
for (const filePath of filesToProcess) {
const contents = fileContents.get(filePath);
if (contents) {
// After staging user changes, restore full content (user + migration)
const currentContent = git.getFileContent(filePath);
if (currentContent) {
// Get the actual current content that includes both changes
const actualContent = await git.getFileContentFromGit(filePath, '');
// This is a bit tricky - we need to keep the file with both changes
// but only user changes are staged
// Git will handle this through the staging area
}
}
}
}
// Step 4: Stage all files NOT in exclude list
console.log(chalk_1.default.cyan('š„ Staging user files not in exclude list...'));
const userFiles = Array.from(allChangedFiles).filter(f => !excludeList.includes(f));
const userFilesToStage = userFiles.filter(f => !status.staged.includes(f));
if (userFilesToStage.length > 0) {
await git.stageFiles(userFilesToStage);
console.log(chalk_1.default.green(`ā
Staged ${userFilesToStage.length} user file(s)`));
}
// Step 5: Show what will be committed
const finalStatus = await git.getStatus();
console.log(chalk_1.default.cyan('\nš Files to be committed:'));
finalStatus.staged.forEach(f => console.log(chalk_1.default.green(` ā ${f}`)));
if (finalStatus.unstaged.length > 0) {
console.log(chalk_1.default.cyan('\nš Files with unstaged changes (migration):'));
finalStatus.unstaged.forEach(f => console.log(chalk_1.default.yellow(` ~ ${f}`)));
}
// Step 6: Commit
console.log(chalk_1.default.cyan('\nš¾ Committing changes...'));
await git.commit(options.message || '', {
amend: options.amend,
noEdit: options.noEdit,
});
console.log(chalk_1.default.green('\nā
Commit successful!'));
console.log(chalk_1.default.blue('ā¹ļø Tracking files preserved for next commit'));
}
catch (error) {
console.error(chalk_1.default.red('ā Error during commit:'), error);
process.exit(1);
}
}
//# sourceMappingURL=commit.js.map