Repository navigation
Expand file tree
/
Copy pathindex.js
More file actions
executable file
·111 lines (95 loc) · 4.29 KB
/
Copy pathindex.js
File metadata and controls
executable file
·111 lines (95 loc) · 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env node
import { checkbox, confirm, select } from "@inquirer/prompts";
import { checkGitInstalled, checkGitRepo, getBranches, createBranchesArray, getDiff, isWorkingTreeClean } from "./src/gitUtils.js";
import { createZip } from "./src/archiverUtils.js";
// Centralized error handler
const handleCriticalError = (message, error) => {
console.error(`❌ Error: ${message}`);
if (error) {
console.error(error);
}
process.exit(1);
};
// Main application logic
async function main() {
try {
// Check if git is installed
await checkGitInstalled();
// Check if folder is a git repo
await checkGitRepo();
// Get all branches
const branches = await getBranches();
// Create an array from branches of the git repo
const branchesArray = createBranchesArray(branches);
// Check if there are enough branches to compare
if (branchesArray.length < 2) {
handleCriticalError("Not enough branches available in the repository to perform a comparison. You need at least two branches.", null);
// The handleCriticalError function already calls process.exit(1), so no further action needed here.
// However, to be explicit and for linters/static analysis that might not see through handleCriticalError:
return; // Exit main function
}
// Ask for two branches to compare
const selectedBranches = await checkbox({
message: "Select two branches to compare",
choices: branchesArray.map(branch => ({ name: branch, value: branch })),
validate: answer => {
// Ensures that the user selects exactly two branches for comparison.
if (answer.length !== 2) {
return "Please select ONLY 2 branches";
}
return true;
},
});
// Destructure the selected branches for easier access.
const [branch1, branch2] = selectedBranches;
// Ask for confirmation before proceeding with the diff and zip creation.
const isConfirmed = await confirm({
message: `Are you sure you want to create zip file from the diff of ${branch1} and ${branch2}?`,
default: true,
});
if (isConfirmed) {
// Before generating the diff, check if the Git working tree is clean.
// This prevents accidental inclusion of uncommitted or unstaged changes.
const isClean = await isWorkingTreeClean();
if (!isClean) {
// If the working tree is not clean, prompt the user for action.
const uncleanTreeAction = await select({
message: "Your working tree is not clean. What would you like to do?",
choices: [
{ name: "Proceed anyway", value: "proceed", description: "Continue without stashing changes." },
{ name: "Stash changes and abort (manual stash required for now)", value: "stash", description: "You'll need to manually stash then re-run." },
{ name: "Abort", value: "abort", description: "Stop the operation." },
],
});
// If the user chooses to abort or stash (which currently requires manual stashing), exit.
if (uncleanTreeAction === "abort" || uncleanTreeAction === "stash") {
console.log("❌ Operation aborted by user due to unclean working tree.");
process.exit(0); // Graceful exit
}
// If the user chooses "proceed", the script will continue to getDiff.
}
// Get the list of filenames that differ between the two selected branches.
const diffFileNames = await getDiff(branch1, branch2);
// Check if the list of changed files is empty
if (diffFileNames.length === 0) {
console.log(`ℹ️ No differences found between ${branch1} and ${branch2}.`);
process.exit(0); // Graceful exit
}
await createZip(branch1, branch2, diffFileNames);
} else {
console.log("❌ Aborted by user.");
process.exit(0); // Graceful exit
}
} catch (error) {
// Check if the error is specifically an ExitPromptError from inquirer
if (error && error.name === 'ExitPromptError') {
console.log("ℹ️ User forced the app to close.");
process.exit(0); // Graceful exit as it's a user action
} else {
// For all other types of errors, use the existing handler
handleCriticalError("An unexpected error occurred during the process.", error);
}
}
}
// Start the application
main();