-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
executable file
·89 lines (69 loc) · 2.16 KB
/
index.js
File metadata and controls
executable file
·89 lines (69 loc) · 2.16 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
#!/usr/bin/env node
import { checkbox, Separator } from '@inquirer/prompts';
import { execSync } from 'child_process';
import { compareFilesForSort, ERROR_GIT_STATUS_RETRIEVAL, ERROR_UNKNOWN_ERROR, getStatusFromLine, getStatusIsChecked, MAX_FILES_TO_DISPLAY, MESSAGE_NO_CHANGES_DETECTED, STATUS_TO_DISPLAY } from './constants.js';
import { logger } from './utils.js';
try {
await main()
} catch (error) {
if (String(error).includes('User force closed the prompt')) {
process.exit()
}
logger.logError(ERROR_UNKNOWN_ERROR, error)
process.exit()
}
export async function main() {
const files = getEligibleFiles()
const choices = getChoices(files)
const answer = await checkbox({
message: "Select files to stage",
pageSize: MAX_FILES_TO_DISPLAY,
choices
});
const selectedFilePaths = new Set(answer.map(getFilePathFromFileValue))
files.forEach(file => { actOnFile(selectedFilePaths, file) })
}
function actOnFile(selectedFilePaths, file) {
if (selectedFilePaths.has(file.filePath)) {
stageFilePath(file.filePath)
return
}
unstageFilePath(file.filePath)
}
function getFilePathFromFileValue(value) {
return value.slice(2)
}
function unstageFilePath(filePath) {
execSync(`git reset HEAD ${filePath}`)
}
function stageFilePath(filePath) {
execSync(`git add ${filePath}`)
}
function getEligibleFiles() {
try {
const result = String(execSync('git status --porcelain'))
const lines = result.split('\n').filter(Boolean)
if (lines.length === 0) {
logger.logFinalMessage(MESSAGE_NO_CHANGES_DETECTED)
process.exit()
}
return lines.map(lineToFile)
} catch (error) {
logger.logError(ERROR_GIT_STATUS_RETRIEVAL, error)
}
}
function lineToFile(line) {
// TODO: get individual files from untracked directory
// happens when no file is staged in a directory, condition on if filePath ends with '/'?
return {
filePath: line.slice(3),
status: getStatusFromLine(line)
}
}
function getChoices(files) {
return files.sort(compareFilesForSort).map(file => ({
filePath: file.filePath,
checked: getStatusIsChecked(file),
value: `${STATUS_TO_DISPLAY[file.status]} ${file.filePath}`,
}))
}