This repository was archived by the owner on May 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcheckPush.js
More file actions
194 lines (177 loc) · 5.17 KB
/
Copy pathcheckPush.js
File metadata and controls
194 lines (177 loc) · 5.17 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import {
executeGitCommand,
findClosestSha,
getGitDirectoryRequired,
} from "../utils/git";
import {
getRulesetsFromCodigaFile,
getRulesetsWithRules,
} from "../utils/rulesets";
import { analyzeFiles } from "../utils/rosie";
import { convertRulesetsToRules } from "../utils/rules";
import {
printEmptyLine,
printFailure,
printInfo,
printSubItem,
printSuccess,
printSuggestion,
printViolation,
setPrintToStdErr,
setPrintToStdOut,
} from "../utils/print";
import { BLANK_SHA } from "../utils/constants";
import { isTestMode } from "../tests/test-utils";
/**
* Gets the changed file paths between two SHAs
* @param {string} remoteSHA
* @param {string} localSHA
*/
function getChangedFilePaths(remoteSHA, localSHA) {
const diff = executeGitCommand([
"diff",
"--name-only",
"--diff-filter=d",
remoteSHA,
localSHA,
]);
if (!diff) {
setPrintToStdErr();
printEmptyLine();
printFailure(
`We were unable to get the difference between ${remoteSHA} and ${localSHA}`
);
printSuggestion(
" ↳ Please review your SHAs above and contact support, if needed:",
"https://app.codiga.io/support"
);
printEmptyLine();
setPrintToStdOut();
process.exit(1);
}
return diff.split("\n").filter((s) => s);
}
/**
* Check the given SHAs to see if we should continue on and
* whether we need to use a different remote SHA string
* @param {string} remoteShaArg
* @param {string} localShaArg
* @returns {{ remoteSha: string, localSha: string }} updated SHAs strings
*/
export function checkSHAs(remoteShaArg, localShaArg) {
let remoteSha = remoteShaArg;
let localSha = localShaArg;
// check if we're on a new branch
if (remoteShaArg === BLANK_SHA) {
// search for the closest SHA to compare against
const closestRemoteSha = findClosestSha();
// if we find one, we'll use it, otherwise we'll notify the user and exit
if (closestRemoteSha) {
remoteSha = closestRemoteSha;
} else {
printInfo(
"Tried to find closest SHA but did not find any; exiting with code 0"
);
process.exit(0);
}
}
if (remoteSha === localSha) {
printInfo(
`Remote and local SHA are the same (${remoteSha}); exiting with code 0`
);
process.exit(0);
}
if (isTestMode) {
return {
remoteSha: remoteShaArg,
localSha: localShaArg,
};
}
return {
remoteSha,
localSha,
};
}
/**
* Checks the diff between two SHAs and runs any Rosie rules
* found in the codiga.yml file rulesets
* @param {string} remoteSHA
* @param {string} localSHA
*/
export async function checkPush(remoteShaArg, localShaArg) {
if (!remoteShaArg || !localShaArg) {
setPrintToStdErr();
printFailure("You need to pass in both remote and local SHA values");
printSuggestion(
" ↳ Refer to our documentation for more info:",
"https://doc.codiga.io/docs/cli/#analysis-and-report-issues-between-two-commits"
);
setPrintToStdOut();
process.exit(1);
}
// ensure that there's a git directory to continue
const rootDir = getGitDirectoryRequired();
// check and verify the SHA args
const { remoteSha, localSha } = checkSHAs(remoteShaArg, localShaArg);
// get the ruleset names from the codiga.yml file
const rulesetNames = getRulesetsFromCodigaFile();
// get the rules for all the rulesets in the codiga file
const rulesetsWithRules = await getRulesetsWithRules(rulesetNames);
// get an array of all the rules from the rulesets
const rules = convertRulesetsToRules(rulesetsWithRules);
// get a list of all the files that have changed
const changedFilePaths = getChangedFilePaths(remoteSha, localSha);
// we analyze all the changed files and get back a list of violations and (network) errors
const { violations, errors } = await analyzeFiles(
changedFilePaths,
rules,
rootDir
);
// print out our violations
if (violations.length === 0) {
printEmptyLine();
printSuccess("Codiga found 0 violations");
printEmptyLine();
} else {
printEmptyLine();
printFailure(
`Codiga found ${violations.length} violation${
violations.length === 1 ? "" : "s"
}:`
);
violations.forEach((violation, index) => {
printViolation(index + 1, violation);
});
printEmptyLine();
}
if (errors.length > 0) {
printFailure("There were network errors while processing the following:");
errors.forEach((error) => {
printSubItem(`- ${error}`);
});
printEmptyLine();
printSuggestion(
"Please try again or contact our support:",
"https://www.codiga.io/contact-us/"
);
printEmptyLine();
}
if (violations.length === 0 && errors.length === 0) {
process.exit(0);
} else {
setPrintToStdErr();
printEmptyLine();
printInfo("Do you consider these violations as false positives?");
printSuggestion(
" ↳ You can add the following flag to your `git push` to bypass this check:",
"--no-verify"
);
printSuggestion(
" ↳ Consider commenting on those rules in the Codiga Hub, so the maintainer can improve them:",
"https://app.codiga.io/hub/rulesets"
);
printEmptyLine();
setPrintToStdOut();
process.exit(1);
}
}