@zohodesk/codestandard-validator 0.0.6-exp-18 → 0.0.6-exp-20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/hooks/Precommit/lint.js +138 -237
- package/build/hooks/Precommit/pre-commit.js +376 -9
- package/build/lib/postinstall.js +3 -3
- package/build/utils/CloneCommonLinterRepo/cloneViaCdt.js +1 -1
- package/build/utils/ConfigFileUtils/createConfigFiles.js +68 -0
- package/build/utils/ConfigFileUtils/getEslintExecutablePath.js +24 -0
- package/build/utils/ConfigFileUtils/getLintConfiguration.js +54 -0
- package/build/utils/FileAndFolderOperations/filterFiles.js +27 -2
- package/build/utils/General/getGeneralInfo.js +14 -9
- package/build/utils/PluginsInstallation/Worker/installPluginsByWoker.js +5 -2
- package/build/utils/PluginsInstallation/checkIfPluginsAreInstalled.js +5 -2
- package/build/utils/PluginsInstallation/installPlugins.js +1 -0
- package/index.js +1 -1
- package/package.json +3 -2
|
@@ -7,12 +7,13 @@ const fs = require('fs');
|
|
|
7
7
|
const path = require('path');
|
|
8
8
|
const {
|
|
9
9
|
getEslintExecutablePath
|
|
10
|
-
} = require('../../utils/
|
|
10
|
+
} = require('../../utils/ConfigFileUtils/getEslintExecutablePath');
|
|
11
11
|
const {
|
|
12
12
|
getNodeModulesPath
|
|
13
13
|
} = require('../../utils/General/getNodeModulesPath');
|
|
14
14
|
const {
|
|
15
|
-
filterFiles
|
|
15
|
+
filterFiles,
|
|
16
|
+
filterWarningInFile
|
|
16
17
|
} = require('../../utils/FileAndFolderOperations/filterFiles');
|
|
17
18
|
const {
|
|
18
19
|
Logger
|
|
@@ -35,276 +36,176 @@ const {
|
|
|
35
36
|
shouldWarningsAbortCommit
|
|
36
37
|
} = getConfigurationPrecommit();
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
/* ------------------------------------------
|
|
40
|
+
Git Helpers
|
|
41
|
+
------------------------------------------ */
|
|
42
|
+
|
|
43
|
+
function isMergeCommit() {
|
|
43
44
|
return new Promise((resolve, reject) => {
|
|
44
|
-
exec('git rev-parse -q --verify MERGE_HEAD', (
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
} else if (stderr) {
|
|
48
|
-
resolve(stderr.trim());
|
|
49
|
-
} else if (stdout) {
|
|
50
|
-
resolve(stdout.trim());
|
|
51
|
-
}
|
|
45
|
+
exec('git rev-parse -q --verify MERGE_HEAD', (err, stderr, stdout) => {
|
|
46
|
+
if (err) return reject(err.toString().trim());
|
|
47
|
+
resolve((stdout || stderr).trim());
|
|
52
48
|
});
|
|
53
49
|
});
|
|
54
50
|
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* @function {getStagedFiles} - methods return staged files
|
|
58
|
-
* @returns {Array<string>} - array of files
|
|
59
|
-
*/
|
|
60
|
-
|
|
61
|
-
async function getStagedFiles() {
|
|
51
|
+
function getStagedFiles() {
|
|
62
52
|
return new Promise((resolve, reject) => {
|
|
63
|
-
exec(
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
} else if (stdout.trim() === '') {
|
|
69
|
-
resolve(stdout.trim());
|
|
70
|
-
}
|
|
53
|
+
exec('git diff --staged --name-only', (err, stderr, stdout) => {
|
|
54
|
+
if (err) return reject("Couldn't fetch staged files");
|
|
55
|
+
const output = stderr || stdout;
|
|
56
|
+
if (!output.trim()) return resolve([]);
|
|
57
|
+
resolve(filterDeletedFiles(output.trim().split('\n')));
|
|
71
58
|
});
|
|
72
59
|
});
|
|
73
60
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
* @function {filterDeltedFileFromStagedFiles} - filter deleted staged files
|
|
77
|
-
* @param {Array<string>} files - staged files
|
|
78
|
-
* @returns
|
|
79
|
-
*/
|
|
80
|
-
function filterDeltedFileFromStagedFiles(files) {
|
|
81
|
-
return files.filter(file => {
|
|
82
|
-
const absolutePath = path.resolve(getRootDirectory(), file);
|
|
83
|
-
if (fs.existsSync(absolutePath)) {
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
return false;
|
|
87
|
-
});
|
|
61
|
+
function filterDeletedFiles(files) {
|
|
62
|
+
return files.filter(file => fs.existsSync(path.resolve(getRootDirectory(), file)));
|
|
88
63
|
}
|
|
89
64
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
* @returns {Array<string>} - array of command line report as a string
|
|
94
|
-
*/
|
|
65
|
+
/* ------------------------------------------
|
|
66
|
+
Lint Helpers
|
|
67
|
+
------------------------------------------ */
|
|
95
68
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (isEslintExecutablePresent) {
|
|
104
|
-
return new Promise((resolve, reject) => {
|
|
105
|
-
exec(`npx --ignore-existing "${eslintExecutablePath}" --config "${eslintConfigurationFilePath}" --no-inline-config --resolve-plugins-relative-to="${nodeModulesPathOfProject}/node_modules" ${file}`, (error, stderr, stdout) => {
|
|
106
|
-
if (stderr) {
|
|
107
|
-
resolve(stderr.trim().split('\n'));
|
|
108
|
-
} else if (error) {
|
|
109
|
-
Logger.log(Logger.FAILURE_TYPE, error);
|
|
110
|
-
reject("Error executing eslint command");
|
|
111
|
-
} else {
|
|
112
|
-
resolve([]);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
} else {
|
|
117
|
-
Logger.log(Logger.INFO_TYPE, 'Eslint executable not found. make sure eslint plugin is installed');
|
|
118
|
-
}
|
|
119
|
-
} else {
|
|
120
|
-
Logger.log(Logger.INFO_TYPE, 'node_modules not found');
|
|
69
|
+
function lintFiles(filePath) {
|
|
70
|
+
const ext = path.extname(filePath);
|
|
71
|
+
if (['.js', '.ts', '.tsx', '.jsx'].includes(ext)) {
|
|
72
|
+
return findEslintErrors(filePath);
|
|
73
|
+
}
|
|
74
|
+
if (['.css', '.scss'].includes(ext)) {
|
|
75
|
+
return findStyleLintErrors(filePath);
|
|
121
76
|
}
|
|
77
|
+
return Promise.resolve([]);
|
|
122
78
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
* @param {*} file - path of file
|
|
127
|
-
* @returns {Promise<Array<string>>} - array of command line report as a string
|
|
128
|
-
*/
|
|
129
|
-
async function calculateGitDiffForFile(branch_name, file) {
|
|
130
|
-
let gitDiffCommand = `git diff -U0 ${branch_name.trim()} ${file}`;
|
|
79
|
+
function findStyleLintErrors(filePath) {
|
|
80
|
+
const config = path.resolve(getNodeModulesPath(), '.stylelintrc.js');
|
|
81
|
+
const absolutePath = path.join(getRootDirectory(), filePath);
|
|
131
82
|
return new Promise((resolve, reject) => {
|
|
132
|
-
exec(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
83
|
+
exec(`npx stylelint ${absolutePath} --config ${config}`, {
|
|
84
|
+
cwd: getNodeModulesPath()
|
|
85
|
+
}, (err, stderr) => {
|
|
86
|
+
if (stderr) return resolve(stderr.trim().split('\n'));
|
|
87
|
+
if (err) {
|
|
88
|
+
Logger.log(Logger.FAILURE_TYPE, err);
|
|
89
|
+
return reject('Error executing stylelint command');
|
|
137
90
|
}
|
|
91
|
+
resolve([]);
|
|
92
|
+
});
|
|
93
|
+
}).catch(err => {
|
|
94
|
+
Logger.log(Logger.FAILURE_TYPE, 'Issue linting CSS files');
|
|
95
|
+
return [];
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function findEslintErrors(filePath) {
|
|
99
|
+
const eslintPath = getEslintExecutablePath();
|
|
100
|
+
const nodeModulesPath = getNodeModulesPath();
|
|
101
|
+
const eslintConfig = `${nodeModulesPath}/.eslintrc.js`;
|
|
102
|
+
if (!fs.existsSync(eslintPath)) {
|
|
103
|
+
Logger.log(Logger.INFO_TYPE, 'Eslint executable not found. Ensure eslint plugin is installed.');
|
|
104
|
+
return Promise.resolve([]);
|
|
105
|
+
}
|
|
106
|
+
return new Promise((resolve, reject) => {
|
|
107
|
+
const cmd = `npx --ignore-existing "${eslintPath}" --config "${eslintConfig}" --no-inline-config --resolve-plugins-relative-to="${nodeModulesPath}/node_modules" ${filePath}`;
|
|
108
|
+
exec(cmd, (err, stderr) => {
|
|
109
|
+
if (stderr) return resolve(stderr.trim().split('\n'));
|
|
110
|
+
if (err) {
|
|
111
|
+
Logger.log(Logger.FAILURE_TYPE, err);
|
|
112
|
+
return reject('Error executing eslint command');
|
|
113
|
+
}
|
|
114
|
+
resolve([]);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
function calculateGitDiffForFile(branch, file) {
|
|
119
|
+
return new Promise((resolve, reject) => {
|
|
120
|
+
exec(`git diff -U0 ${branch.trim()} ${file}`, (err, stderr) => {
|
|
121
|
+
if (stderr) return resolve(stderr.trim().split('\n'));
|
|
122
|
+
if (err) return reject(err);
|
|
138
123
|
});
|
|
139
124
|
});
|
|
140
125
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
*/
|
|
126
|
+
|
|
127
|
+
/* ------------------------------------------
|
|
128
|
+
Utility
|
|
129
|
+
------------------------------------------ */
|
|
145
130
|
|
|
146
131
|
function areAllPluginsInstalled() {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
132
|
+
const {
|
|
133
|
+
uninstalledPlugins
|
|
134
|
+
} = checkIfPluginsAreInstalled();
|
|
135
|
+
console.log('unInstalledPlugins', uninstalledPlugins);
|
|
136
|
+
return uninstalledPlugins.length === 0;
|
|
150
137
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
* @returns {Boolean} - returns boolean based on only warnings present or not in file
|
|
155
|
-
*/
|
|
156
|
-
function isOnlyWarningsPresentInFile(eslintErrorsPresent) {
|
|
157
|
-
let severityOfEachErrorInFile = [];
|
|
158
|
-
eslintErrorsPresent.map(error => {
|
|
159
|
-
let partsInString = error.split(" ");
|
|
160
|
-
let severityOfError = partsInString.find(word => word === 'error' || word === 'warning');
|
|
161
|
-
severityOfEachErrorInFile.push(severityOfError);
|
|
162
|
-
});
|
|
163
|
-
return !severityOfEachErrorInFile.includes('error');
|
|
138
|
+
function isOnlyWarningsPresent(errors) {
|
|
139
|
+
const severities = errors.map(e => e.split(' ').find(w => w === 'error' || w === 'warning'));
|
|
140
|
+
return !severities.includes('error');
|
|
164
141
|
}
|
|
165
142
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
*/
|
|
143
|
+
/* ------------------------------------------
|
|
144
|
+
Main Execution
|
|
145
|
+
------------------------------------------ */
|
|
170
146
|
|
|
171
147
|
async function preCommitHook() {
|
|
172
148
|
Logger.log(Logger.INFO_TYPE, 'Executing pre commit hook...');
|
|
173
|
-
Logger.log(Logger.INFO_TYPE, `
|
|
149
|
+
Logger.log(Logger.INFO_TYPE, `Working directory: ${process.cwd()}`);
|
|
174
150
|
try {
|
|
175
|
-
|
|
176
|
-
Logger.log(Logger.INFO_TYPE, 'Looks like you have merged. So skipping pre
|
|
151
|
+
await isMergeCommit();
|
|
152
|
+
Logger.log(Logger.INFO_TYPE, 'Looks like you have merged. So skipping pre-commit check');
|
|
177
153
|
process.exit(0);
|
|
178
|
-
} catch
|
|
179
|
-
if (areAllPluginsInstalled()) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
154
|
+
} catch {
|
|
155
|
+
if (!areAllPluginsInstalled()) {
|
|
156
|
+
Logger.log(Logger.FAILURE_TYPE, 'Commit failed due to missing eslint plugins');
|
|
157
|
+
Logger.log(Logger.INFO_TYPE, `Run \x1b[37mnpx ZDPrecommit setupPlugins\x1b[33m in the project root`);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
let files = await getStagedFiles();
|
|
161
|
+
if (files.length === 0) {
|
|
162
|
+
Logger.log(Logger.INFO_TYPE, 'No files staged. Stage files before committing.');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const currentBranch = await getBranchName().catch(() => '');
|
|
166
|
+
const filteredFiles = filterFiles(files, ['.eslintrc.js'], true);
|
|
167
|
+
let shouldAbort = false;
|
|
168
|
+
for (const file of filteredFiles) {
|
|
169
|
+
if (!getSupportedLanguage().includes(path.extname(file))) continue;
|
|
193
170
|
try {
|
|
194
|
-
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (getSupportedLanguage().includes(path.extname(staged_files[file]))) {
|
|
210
|
-
try {
|
|
211
|
-
var eslintErrorsInFile = await findEslintErrors(staged_files[file]);
|
|
212
|
-
// eslintErrorsInFile = impactBasedPrecommit == false ? filterWarningInFile(eslintErrorsInFile) : eslintErrorsInFile
|
|
213
|
-
if (staged_files[file] && typeof staged_files[file] == 'string') {
|
|
214
|
-
if (!eslintErrorsInFile.length == 0) {
|
|
215
|
-
//Calculating changed lines in a file and storing them in respective arrays
|
|
216
|
-
if (impactBasedPrecommit) {
|
|
217
|
-
//git diff is computed and stored in an array
|
|
218
|
-
let git_diff = await calculateGitDiffForFile(current_branch, staged_files[file]);
|
|
219
|
-
changedLinesArray = git_diff.filter(line => line.startsWith('@@'));
|
|
220
|
-
let changedLinesStartArray = [];
|
|
221
|
-
let changedLinesEndArray = [];
|
|
222
|
-
for (let number of changedLinesArray) {
|
|
223
|
-
let changesStartLine = parseInt(number.split(' ')[2].split(',')[0]);
|
|
224
|
-
changedLinesStartArray.push(changesStartLine);
|
|
225
|
-
let changesEndLine = number.split(' ')[2].split(',')[1];
|
|
226
|
-
if (changesEndLine === undefined) {
|
|
227
|
-
changedLinesEndArray.push(changesStartLine);
|
|
228
|
-
} else {
|
|
229
|
-
changedLinesEndArray.push(changesStartLine + parseInt(changesEndLine) - 1);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
for (let error = 1; error < eslintErrorsInFile.length - 2; error++) {
|
|
233
|
-
//eslintErrorsInFile[error].trim() - 69:26 error => Do not hardcode content. Use I18N key instead no-hardcoding/no-hardcoding,
|
|
234
|
-
//eslintErrorsInFile[error].trim().split(' ')[0] => 69:26
|
|
235
|
-
//eslintErrorsInFile[error].trim().split(' ')[0].split(':')[0] => 69
|
|
236
|
-
|
|
237
|
-
let eslintErrorLineNumber = eslintErrorsInFile[error].trim().split(' ')[0].split(':')[0];
|
|
238
|
-
for (let lineNumber in changedLinesStartArray) {
|
|
239
|
-
if (eslintErrorLineNumber >= changedLinesStartArray[lineNumber] && eslintErrorLineNumber <= changedLinesEndArray[lineNumber]) {
|
|
240
|
-
eslintErrorsInChangedLines.push(eslintErrorsInFile[error]);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
if (eslintErrorsInChangedLines.length > 0) {
|
|
245
|
-
isOnlyEslintWarningsPresentInFile = isOnlyWarningsPresentInFile(eslintErrorsInChangedLines);
|
|
246
|
-
Logger.log(Logger.FAILURE_TYPE, `\x1b[1m${currentFileName}\x1b[0m`);
|
|
247
|
-
for (let eslintError of eslintErrorsInChangedLines) {
|
|
248
|
-
Logger.log(Logger.FAILURE_TYPE, `\x1b[37m${eslintError.trimEnd()}\x1b[0m`);
|
|
249
|
-
}
|
|
250
|
-
if (shouldWarningsAbortCommit) {
|
|
251
|
-
hasEslintErrorsInChangedLines = true;
|
|
252
|
-
shouldAbortCommit = true;
|
|
253
|
-
} else if (!shouldWarningsAbortCommit && isOnlyEslintWarningsPresentInFile) {
|
|
254
|
-
hasEslintErrorsInChangedLines = false;
|
|
255
|
-
} else if (!shouldWarningsAbortCommit && !isOnlyEslintWarningsPresentInFile) {
|
|
256
|
-
hasEslintErrorsInChangedLines = true;
|
|
257
|
-
shouldAbortCommit = true;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
} else {
|
|
261
|
-
if (eslintErrorsInFile.length > 0) {
|
|
262
|
-
let startIndex = 1;
|
|
263
|
-
let endIndex = eslintErrorsInFile.length - 2;
|
|
264
|
-
let listOsEslintErrors = eslintErrorsInFile.slice(startIndex, endIndex);
|
|
265
|
-
isOnlyEslintWarningsPresentInFile = isOnlyWarningsPresentInFile(listOsEslintErrors);
|
|
266
|
-
Logger.log(Logger.FAILURE_TYPE, `\x1b[1m${currentFileName}\x1b[0m`);
|
|
267
|
-
for (let eslintError of listOsEslintErrors) {
|
|
268
|
-
Logger.log(Logger.FAILURE_TYPE, `\x1b[37m${eslintError.trimEnd()}\x1b[0m`);
|
|
269
|
-
}
|
|
270
|
-
if (shouldWarningsAbortCommit) {
|
|
271
|
-
hasEslintErrorsInFiles = true;
|
|
272
|
-
shouldAbortCommit = true;
|
|
273
|
-
} else if (!shouldWarningsAbortCommit && isOnlyEslintWarningsPresentInFile) {
|
|
274
|
-
hasEslintErrorsInFiles = false;
|
|
275
|
-
} else if (!shouldWarningsAbortCommit && !isOnlyEslintWarningsPresentInFile) {
|
|
276
|
-
hasEslintErrorsInFiles = true;
|
|
277
|
-
shouldAbortCommit = true;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
} catch (err) {
|
|
284
|
-
Logger.log(Logger.FAILURE_TYPE, err);
|
|
285
|
-
Logger.log(Logger.FAILURE_TYPE, "Error in executing eslint command");
|
|
286
|
-
}
|
|
171
|
+
const lintResults = await lintFiles(file);
|
|
172
|
+
if (lintResults.length === 0) continue;
|
|
173
|
+
let relevantErrors = [];
|
|
174
|
+
if (impactBasedPrecommit) {
|
|
175
|
+
const gitDiff = await calculateGitDiffForFile(currentBranch, file);
|
|
176
|
+
const changeHunks = gitDiff.filter(line => line.startsWith('@@'));
|
|
177
|
+
const ranges = changeHunks.map(h => {
|
|
178
|
+
const start = parseInt(h.split(' ')[2].split(',')[0]);
|
|
179
|
+
const len = parseInt(h.split(' ')[2].split(',')[1]) || 1;
|
|
180
|
+
return [start, start + len - 1];
|
|
181
|
+
});
|
|
182
|
+
for (const error of lintResults.slice(1, -2)) {
|
|
183
|
+
const lineNum = parseInt(error.trim().split(' ')[0].split(':')[0]);
|
|
184
|
+
if (ranges.some(([start, end]) => lineNum >= start && lineNum <= end)) {
|
|
185
|
+
relevantErrors.push(error);
|
|
287
186
|
}
|
|
288
187
|
}
|
|
289
|
-
} else
|
|
290
|
-
|
|
188
|
+
} else {
|
|
189
|
+
relevantErrors = lintResults.slice(1, -2);
|
|
291
190
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
191
|
+
if (relevantErrors.length) {
|
|
192
|
+
const onlyWarnings = isOnlyWarningsPresent(relevantErrors);
|
|
193
|
+
Logger.log(Logger.FAILURE_TYPE, `\x1b[1m${file}\x1b[0m`);
|
|
194
|
+
relevantErrors.forEach(e => Logger.log(Logger.FAILURE_TYPE, `\x1b[37m${e.trimEnd()}\x1b[0m`));
|
|
195
|
+
if (shouldWarningsAbortCommit || !onlyWarnings) {
|
|
196
|
+
shouldAbort = true;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
} catch (err) {
|
|
200
|
+
Logger.log(Logger.FAILURE_TYPE, err);
|
|
301
201
|
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
Logger.log(Logger.
|
|
305
|
-
Logger.log(Logger.INFO_TYPE, 'Execute the command and kindly try committing again.');
|
|
202
|
+
}
|
|
203
|
+
if (shouldAbort) {
|
|
204
|
+
Logger.log(Logger.FAILURE_TYPE, 'There are eslint errors/warnings. Aborting commit.');
|
|
306
205
|
process.exit(1);
|
|
307
206
|
}
|
|
207
|
+
Logger.log(Logger.SUCCESS_TYPE, 'Commit Successful');
|
|
208
|
+
process.exit(0);
|
|
308
209
|
}
|
|
309
210
|
}
|
|
310
211
|
preCommitHook();
|
|
@@ -4,14 +4,380 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = validateRemotePackages;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
// const {exec, execSync} = require('child_process')
|
|
8
|
+
// const fs = require('fs')
|
|
9
|
+
// const path = require('path')
|
|
10
|
+
// const { getEslintExecutablePath } = require('../../utils/ConfigFileUtils/getEslintExecutablePath')
|
|
11
|
+
// const { getNodeModulesPath } = require('../../utils/General/getNodeModulesPath')
|
|
12
|
+
// const { filterFiles, filterWarningInFile } = require('../../utils/FileAndFolderOperations/filterFiles')
|
|
13
|
+
// const { Logger } = require('../../utils/Logger/Logger')
|
|
14
|
+
// const { checkIfPluginsAreInstalled } = require('../../utils/PluginsInstallation/checkIfPluginsAreInstalled')
|
|
15
|
+
// const { getBranchName } = require('../../utils/GitActions/gitActions')
|
|
16
|
+
// const { getConfigurationPrecommit, getSupportedLanguage } = require('../../utils/General/getGeneralInfo')
|
|
17
|
+
// const { getRootDirectory } = require('../../utils/General/RootDirectoryUtils/getRootDirectory')
|
|
18
|
+
// const { impactBasedPrecommit, shouldWarningsAbortCommit } = getConfigurationPrecommit()
|
|
19
|
+
|
|
20
|
+
// /**
|
|
21
|
+
// * @function isMergeCommit - This method check whether it is merge or not
|
|
22
|
+
// * @returns {Boolean} - return boolean based on latest merge changes
|
|
23
|
+
// */
|
|
24
|
+
// async function isMergeCommit() {
|
|
25
|
+
// return new Promise((resolve, reject) => {
|
|
26
|
+
// exec('git rev-parse -q --verify MERGE_HEAD', (error,stderr,stdout) => {
|
|
27
|
+
// if(error){
|
|
28
|
+
// reject(error.toString().trim())
|
|
29
|
+
// }
|
|
30
|
+
// else if(stderr){
|
|
31
|
+
// resolve(stderr.trim())
|
|
32
|
+
// }
|
|
33
|
+
// else if(stdout){
|
|
34
|
+
// resolve(stdout.trim())
|
|
35
|
+
// }
|
|
36
|
+
// })
|
|
37
|
+
// })
|
|
38
|
+
|
|
39
|
+
// }
|
|
40
|
+
|
|
41
|
+
// /**
|
|
42
|
+
// * @function {getStagedFiles} - methods return staged files
|
|
43
|
+
// * @returns {Array<string>} - array of files
|
|
44
|
+
// */
|
|
45
|
+
|
|
46
|
+
// async function getStagedFiles(){
|
|
47
|
+
// return new Promise((resolve, reject) => {
|
|
48
|
+
// exec("git diff --staged --name-only",(error,stderr,stdout) =>{
|
|
49
|
+
// if (error){
|
|
50
|
+
// if(error != null)
|
|
51
|
+
// reject("Couldn't fetch staged files")
|
|
52
|
+
// }
|
|
53
|
+
// else if(stderr){
|
|
54
|
+
// resolve(filterDeltedFileFromStagedFiles(stderr.trim().split('\n')))
|
|
55
|
+
// }
|
|
56
|
+
// else if(stdout.trim() === ''){
|
|
57
|
+
// resolve(stdout.trim())
|
|
58
|
+
// }
|
|
59
|
+
// })
|
|
60
|
+
// })
|
|
61
|
+
|
|
62
|
+
// }
|
|
63
|
+
|
|
64
|
+
// /**
|
|
65
|
+
// * @function {filterDeltedFileFromStagedFiles} - filter deleted staged files
|
|
66
|
+
// * @param {Array<string>} files - staged files
|
|
67
|
+
// * @returns
|
|
68
|
+
// */
|
|
69
|
+
// function filterDeltedFileFromStagedFiles(files){
|
|
70
|
+
// return files.filter((file) =>{
|
|
71
|
+
// const absolutePath= path.resolve(getRootDirectory(),file)
|
|
72
|
+
// if(fs.existsSync(absolutePath)){
|
|
73
|
+
// return true
|
|
74
|
+
// }
|
|
75
|
+
// return false
|
|
76
|
+
// })
|
|
77
|
+
// }
|
|
78
|
+
|
|
79
|
+
// async function lintFiles(filePath){
|
|
80
|
+
// switch(path.extname(filePath)){
|
|
81
|
+
// case '.js' ||'.ts' || '.tsx' || '.jsx' : {
|
|
82
|
+
// return await findEslintErrors(filePath )
|
|
83
|
+
// }
|
|
84
|
+
|
|
85
|
+
// case '.css' || '.scss' :{
|
|
86
|
+
// return await findStyleLintErrors(filePath)
|
|
87
|
+
// }
|
|
88
|
+
// default : {
|
|
89
|
+
// return []
|
|
90
|
+
// }
|
|
91
|
+
// }
|
|
92
|
+
// }
|
|
93
|
+
|
|
94
|
+
// /**
|
|
95
|
+
// * @function findEslintErrors - method Lint given file based on given configuration
|
|
96
|
+
// * @param {*} file - path of file to lint
|
|
97
|
+
// * @returns {Array<string>} - array of command line report as a string
|
|
98
|
+
// */
|
|
99
|
+
|
|
100
|
+
// function findEslintErrors(file){
|
|
101
|
+
// let nodeModulesPathOfProject = `${getNodeModulesPath()}`
|
|
102
|
+
// let eslintExecutablePath = getEslintExecutablePath()
|
|
103
|
+
// let eslintConfigurationFilePath = `${nodeModulesPathOfProject}/.eslintrc.js`
|
|
104
|
+
// let isEslintExecutablePresent = fs.existsSync(eslintExecutablePath) ? true : false
|
|
105
|
+
// let isNodeModulesPresent = fs.existsSync(nodeModulesPathOfProject)
|
|
106
|
+
|
|
107
|
+
// if(isNodeModulesPresent){
|
|
108
|
+
// if(isEslintExecutablePresent){
|
|
109
|
+
// return new Promise ((resolve, reject) => {
|
|
110
|
+
// exec(`npx --ignore-existing "${eslintExecutablePath}" --config "${eslintConfigurationFilePath}" --no-inline-config --resolve-plugins-relative-to="${nodeModulesPathOfProject}/node_modules" ${file}`,(error,stderr,stdout) => {
|
|
111
|
+
// if(stderr){
|
|
112
|
+
// resolve(stderr.trim().split('\n'))
|
|
113
|
+
// }
|
|
114
|
+
// else if(error){
|
|
115
|
+
// Logger.log(Logger.FAILURE_TYPE,error)
|
|
116
|
+
// reject("Error executing eslint command")
|
|
117
|
+
// }
|
|
118
|
+
// else{
|
|
119
|
+
// resolve([])
|
|
120
|
+
// }
|
|
121
|
+
// })
|
|
122
|
+
// })
|
|
123
|
+
// }
|
|
124
|
+
// else{
|
|
125
|
+
// Logger.log(Logger.INFO_TYPE,'Eslint executable not found. make sure eslint plugin is installed')
|
|
126
|
+
// }
|
|
127
|
+
// }
|
|
128
|
+
// else{
|
|
129
|
+
// Logger.log(Logger.INFO_TYPE,'node_modules not found')
|
|
130
|
+
// }
|
|
131
|
+
// }
|
|
132
|
+
|
|
133
|
+
// /**
|
|
134
|
+
// *
|
|
135
|
+
// * @param {*} params
|
|
136
|
+
// */
|
|
137
|
+
// function findStyleLintErrors(filePath) {
|
|
138
|
+
// const configFilePath = path.resolve(getNodeModulesPath(),'.stylelintrc.json')
|
|
139
|
+
// const absolutePath = path.join(getRootDirectory(),filePath)
|
|
140
|
+
// try{
|
|
141
|
+
// return new Promise ((resolve, reject) => {
|
|
142
|
+
// exec(`npx stylelint ${absolutePath} --config ${configFilePath}`,{cwd:getNodeModulesPath()},(error,stderr,stdout) => {
|
|
143
|
+
// if(stderr){
|
|
144
|
+
// resolve(stderr.trim().split('\n'))
|
|
145
|
+
// }
|
|
146
|
+
// else if(error){
|
|
147
|
+
// Logger.log(Logger.FAILURE_TYPE,error)
|
|
148
|
+
// reject("Error executing eslint command")
|
|
149
|
+
// }
|
|
150
|
+
// else{
|
|
151
|
+
// resolve([])
|
|
152
|
+
// }
|
|
153
|
+
// })
|
|
154
|
+
// })
|
|
155
|
+
// }catch(error){
|
|
156
|
+
// Logger.log(Logger.FAILURE_TYPE,`Issue is lint css files`)
|
|
157
|
+
// return []
|
|
158
|
+
// }
|
|
159
|
+
// }
|
|
160
|
+
|
|
161
|
+
// /**
|
|
162
|
+
// * @function {calculateGitDiffForFile} - method calculate diff of file
|
|
163
|
+
// * @param {*} branch_name - branch name
|
|
164
|
+
// * @param {*} file - path of file
|
|
165
|
+
// * @returns {Promise<Array<string>>} - array of command line report as a string
|
|
166
|
+
// */
|
|
167
|
+
// async function calculateGitDiffForFile(branch_name,file){
|
|
168
|
+
// let gitDiffCommand = `git diff -U0 ${branch_name.trim()} ${file}`
|
|
169
|
+
// return new Promise ((resolve,reject) => {
|
|
170
|
+
// exec(gitDiffCommand,(error, stderr) => {
|
|
171
|
+
// if(stderr){
|
|
172
|
+
// resolve(stderr.trim().split('\n'))
|
|
173
|
+
// }
|
|
174
|
+
// else if(error) {
|
|
175
|
+
// reject(error)
|
|
176
|
+
// }
|
|
177
|
+
// })
|
|
178
|
+
// })
|
|
179
|
+
// }
|
|
180
|
+
// /**
|
|
181
|
+
// * @function {areAllPluginsInstalled} - method whether plugin is installed or not
|
|
182
|
+
// * @returns {Boolean} - return boolean based on plugin installed or not
|
|
183
|
+
// */
|
|
184
|
+
|
|
185
|
+
// function areAllPluginsInstalled(){
|
|
186
|
+
// let unInstalledPlugins = checkIfPluginsAreInstalled().uninstalledPlugins
|
|
187
|
+
// return unInstalledPlugins.length === 0 ? true : false
|
|
188
|
+
// }
|
|
189
|
+
|
|
190
|
+
// /**
|
|
191
|
+
// * @function {isOnlyWarningsPresentInFile} - method that checks if only eslint warnings are present in a file
|
|
192
|
+
// * @returns {Boolean} - returns boolean based on only warnings present or not in file
|
|
193
|
+
// */
|
|
194
|
+
// function isOnlyWarningsPresentInFile(eslintErrorsPresent){
|
|
195
|
+
// let severityOfEachErrorInFile = []
|
|
196
|
+
// eslintErrorsPresent.map(error => {
|
|
197
|
+
// let partsInString = error.split(" ")
|
|
198
|
+
// let severityOfError = partsInString.find(word => word === 'error' || word === 'warning'|| word === '✖')
|
|
199
|
+
// severityOfEachErrorInFile.push(severityOfError)
|
|
200
|
+
// })
|
|
201
|
+
// return !(severityOfEachErrorInFile.includes('✖') || severityOfEachErrorInFile.includes('error'))
|
|
202
|
+
// }
|
|
203
|
+
|
|
204
|
+
// /**
|
|
205
|
+
// * @function {preCommitHook} - method execute pre commit hook
|
|
206
|
+
// * @returns {void}
|
|
207
|
+
// */
|
|
208
|
+
|
|
209
|
+
// async function preCommitHook() {
|
|
210
|
+
// Logger.log(Logger.INFO_TYPE,'Executing pre commit hook...')
|
|
211
|
+
// Logger.log(Logger.INFO_TYPE,`working dir : ${process.cwd()}`)
|
|
212
|
+
// try{
|
|
213
|
+
// let isMerge = await isMergeCommit();
|
|
214
|
+
// Logger.log(Logger.INFO_TYPE,'Looks like you have merged. So skipping pre commit check');
|
|
215
|
+
// process.exit(0);
|
|
216
|
+
// }
|
|
217
|
+
// catch(error){
|
|
218
|
+
// if(areAllPluginsInstalled()){
|
|
219
|
+
// let staged_files = []
|
|
220
|
+
// let eslintConfigFiles = ['.eslintrc.js']
|
|
221
|
+
// let exemptionFiles = []
|
|
222
|
+
// let current_branch = ''
|
|
223
|
+
// let hasEslintErrorsInChangedLines = false
|
|
224
|
+
// let hasEslintErrorsInFiles = false
|
|
225
|
+
// let areFilesStaged = false
|
|
226
|
+
// let shouldAbortCommit = false
|
|
227
|
+
// try{
|
|
228
|
+
// current_branch = await getBranchName()
|
|
229
|
+
// }
|
|
230
|
+
// catch{
|
|
231
|
+
// Logger.log(Logger.INFO_TYPE,"Error fetching current branch")
|
|
232
|
+
// }
|
|
233
|
+
// try{
|
|
234
|
+
// staged_files = await getStagedFiles()
|
|
235
|
+
|
|
236
|
+
// if(!staged_files.length == 0){
|
|
237
|
+
// const {JsFiles:staged_filesJS, CssFiles} = filterFiles(staged_files,eslintConfigFiles,true)
|
|
238
|
+
|
|
239
|
+
// // staged_filesJS = filterFiles(staged_filesJS,exemptionFiles) //this is the code for giving exemption to a file during pre commit
|
|
240
|
+
// // if(staged_filesJS.length === 0){
|
|
241
|
+
// // Logger.log(Logger.SUCCESS_TYPE,`Commit Successful`)
|
|
242
|
+
// // process.exit(0)
|
|
243
|
+
// // }
|
|
244
|
+
// areFilesStaged = true
|
|
245
|
+
// var stagedFiles = [...staged_filesJS,...CssFiles]
|
|
246
|
+
// for (let file in stagedFiles){
|
|
247
|
+
// let currentFileName = stagedFiles[file]
|
|
248
|
+
// let changedLinesArray = []
|
|
249
|
+
// let eslintErrorsInChangedLines = []
|
|
250
|
+
// let isOnlyEslintWarningsPresentInFile = false
|
|
251
|
+
|
|
252
|
+
// if(getSupportedLanguage().includes(path.extname(stagedFiles[file]) )){
|
|
253
|
+
// try{
|
|
254
|
+
// var errorsInFile= await lintFiles(stagedFiles[file])
|
|
255
|
+
// // eslintErrorsInFile = impactBasedPrecommit == false ? filterWarningInFile(errorsInFile) : errorsInFile
|
|
256
|
+
// if(stagedFiles[file] && typeof(stagedFiles[file]) == 'string'){
|
|
257
|
+
// if(! errorsInFile.length == 0){
|
|
258
|
+
// //Calculating changed lines in a file and storing them in respective arrays
|
|
259
|
+
// if(impactBasedPrecommit) {
|
|
260
|
+
|
|
261
|
+
// //git diff is computed and stored in an array
|
|
262
|
+
// let git_diff = await calculateGitDiffForFile(current_branch,stagedFiles[file])
|
|
263
|
+
// changedLinesArray = git_diff.filter((line) => line.startsWith('@@'))
|
|
264
|
+
|
|
265
|
+
// let changedLinesStartArray = []
|
|
266
|
+
// let changedLinesEndArray = []
|
|
267
|
+
|
|
268
|
+
// for (let number of changedLinesArray){
|
|
269
|
+
// let changesStartLine = parseInt(number.split(' ')[2].split(',')[0])
|
|
270
|
+
// changedLinesStartArray.push(changesStartLine)
|
|
271
|
+
// let changesEndLine = number.split(' ')[2].split(',')[1]
|
|
272
|
+
// if(changesEndLine === undefined){
|
|
273
|
+
// changedLinesEndArray.push(changesStartLine)
|
|
274
|
+
// }
|
|
275
|
+
// else{
|
|
276
|
+
// changedLinesEndArray.push(changesStartLine + parseInt(changesEndLine) - 1)
|
|
277
|
+
// }
|
|
278
|
+
// }
|
|
279
|
+
// for (let error=1; error < errorsInFile.length - 2; error++){
|
|
280
|
+
// //errorsInFile[error].trim() - 69:26 error => Do not hardcode content. Use I18N key instead no-hardcoding/no-hardcoding,
|
|
281
|
+
// //errorsInFile[error].trim().split(' ')[0] => 69:26
|
|
282
|
+
// //errorsInFile[error].trim().split(' ')[0].split(':')[0] => 69
|
|
283
|
+
|
|
284
|
+
// let eslintErrorLineNumber = errorsInFile[error].trim().split(' ')[0].split(':')[0]
|
|
285
|
+
|
|
286
|
+
// for(let lineNumber in changedLinesStartArray){
|
|
287
|
+
// if(eslintErrorLineNumber >= changedLinesStartArray[lineNumber] &&
|
|
288
|
+
// eslintErrorLineNumber <= changedLinesEndArray[lineNumber]){
|
|
289
|
+
// eslintErrorsInChangedLines.push(errorsInFile[error])
|
|
290
|
+
// }
|
|
291
|
+
// }
|
|
292
|
+
// }
|
|
293
|
+
// if(eslintErrorsInChangedLines.length > 0){
|
|
294
|
+
// isOnlyEslintWarningsPresentInFile = isOnlyWarningsPresentInFile(eslintErrorsInChangedLines)
|
|
295
|
+
// Logger.log(Logger.FAILURE_TYPE,`\x1b[1m${currentFileName}\x1b[0m`)
|
|
296
|
+
// for(let eslintError of eslintErrorsInChangedLines){
|
|
297
|
+
// Logger.log(Logger.FAILURE_TYPE,`\x1b[37m${eslintError.trimEnd()}\x1b[0m`)
|
|
298
|
+
// }
|
|
299
|
+
// if(shouldWarningsAbortCommit){
|
|
300
|
+
// hasEslintErrorsInChangedLines = true
|
|
301
|
+
// shouldAbortCommit = true
|
|
302
|
+
// }
|
|
303
|
+
// else if(!shouldWarningsAbortCommit && isOnlyEslintWarningsPresentInFile){
|
|
304
|
+
// hasEslintErrorsInChangedLines = false
|
|
305
|
+
// }
|
|
306
|
+
// else if(!shouldWarningsAbortCommit && !isOnlyEslintWarningsPresentInFile){
|
|
307
|
+
// hasEslintErrorsInChangedLines = true
|
|
308
|
+
// shouldAbortCommit = true
|
|
309
|
+
// }
|
|
310
|
+
// }
|
|
311
|
+
// }else{
|
|
312
|
+
// if(errorsInFile.length > 0 ){
|
|
313
|
+
// let startIndex = 1
|
|
314
|
+
// let endIndex = errorsInFile.length - 2
|
|
315
|
+
// let listOsEslintErrors = errorsInFile.slice(startIndex,endIndex)
|
|
316
|
+
// isOnlyEslintWarningsPresentInFile = isOnlyWarningsPresentInFile(listOsEslintErrors)
|
|
317
|
+
// Logger.log(Logger.FAILURE_TYPE,`\x1b[1m${currentFileName}\x1b[0m`)
|
|
318
|
+
// for(let eslintError of listOsEslintErrors){
|
|
319
|
+
// Logger.log(Logger.FAILURE_TYPE,`\x1b[37m${eslintError.trimEnd()}\x1b[0m`)
|
|
320
|
+
// }
|
|
321
|
+
// if(shouldWarningsAbortCommit){
|
|
322
|
+
// hasEslintErrorsInFiles = true
|
|
323
|
+
// shouldAbortCommit = true
|
|
324
|
+
// }
|
|
325
|
+
// else if(!shouldWarningsAbortCommit && isOnlyEslintWarningsPresentInFile){
|
|
326
|
+
// hasEslintErrorsInFiles = false
|
|
327
|
+
// }
|
|
328
|
+
// else if(!shouldWarningsAbortCommit && !isOnlyEslintWarningsPresentInFile){
|
|
329
|
+
// hasEslintErrorsInFiles = true
|
|
330
|
+
// shouldAbortCommit = true
|
|
331
|
+
// }
|
|
332
|
+
// }
|
|
333
|
+
// }
|
|
334
|
+
// }
|
|
335
|
+
// }
|
|
336
|
+
// }
|
|
337
|
+
// catch(err){
|
|
338
|
+
// Logger.log(Logger.FAILURE_TYPE,err)
|
|
339
|
+
// Logger.log(Logger.FAILURE_TYPE,"Error in executing eslint command")
|
|
340
|
+
// }
|
|
341
|
+
|
|
342
|
+
// }
|
|
343
|
+
// }
|
|
344
|
+
// }
|
|
345
|
+
// else if(staged_files.length === 0){
|
|
346
|
+
// Logger.log(Logger.INFO_TYPE,'No files have been staged. Stage your files before committing')
|
|
347
|
+
// }
|
|
348
|
+
// }
|
|
349
|
+
// catch{
|
|
350
|
+
// Logger.log(Logger.INFO_TYPE,'Error executing pre commit hook')
|
|
351
|
+
// }
|
|
352
|
+
// if(shouldAbortCommit){
|
|
353
|
+
// Logger.log(Logger.FAILURE_TYPE, `There are eslint errors/warnings present. So commit is aborted.`);
|
|
354
|
+
// process.exit(1);
|
|
355
|
+
// }
|
|
356
|
+
// else if(shouldAbortCommit === false && staged_files.length !== 0){
|
|
357
|
+
// Logger.log(Logger.SUCCESS_TYPE, `Commit Successful`);
|
|
358
|
+
// process.exit(0);
|
|
359
|
+
// }
|
|
360
|
+
// }
|
|
361
|
+
// else{
|
|
362
|
+
// Logger.log(Logger.FAILURE_TYPE,'Commit failed since some eslint plugins are not installed')
|
|
363
|
+
// Logger.log(Logger.INFO_TYPE,`Kindly execute the command \x1b[37mnpx ZDPrecommit setupPlugins \x1b[33mfrom the location where package.json is present to install the plugins`)
|
|
364
|
+
// Logger.log(Logger.INFO_TYPE,'Execute the command and kindly try committing again.')
|
|
365
|
+
// process.exit(1)
|
|
366
|
+
// }
|
|
367
|
+
// }
|
|
368
|
+
// }
|
|
369
|
+
|
|
370
|
+
// preCommitHook()
|
|
371
|
+
|
|
372
|
+
const {
|
|
373
|
+
getNodeModulesPath
|
|
374
|
+
} = require("../../utils/General/getNodeModulesPath");
|
|
9
375
|
const {
|
|
10
376
|
cloneViaCdt
|
|
11
377
|
} = require("../../utils/CloneCommonLinterRepo/cloneViaCdt");
|
|
12
378
|
const {
|
|
13
|
-
|
|
14
|
-
} = require("../../utils/
|
|
379
|
+
createConfigFiles
|
|
380
|
+
} = require("../../utils/ConfigFileUtils/createConfigFiles");
|
|
15
381
|
const {
|
|
16
382
|
getLastCommitHash,
|
|
17
383
|
getStoredCommitHash
|
|
@@ -26,17 +392,18 @@ async function validateRemotePackages() {
|
|
|
26
392
|
try {
|
|
27
393
|
if (!(getStoredCommitHash() == getLastCommitHash())) {
|
|
28
394
|
await executeMethodsThatReturnBooleanValue("Make sure zgit.csez.zohocorpin.com is accessible", cloneViaCdt, null);
|
|
29
|
-
await executeMethodsThatReturnBooleanValue("Some issue occurred in creating eslint config file.",
|
|
395
|
+
await executeMethodsThatReturnBooleanValue("Some issue occurred in creating eslint config file.", createConfigFiles, null);
|
|
30
396
|
Logger.log(Logger.SUCCESS_TYPE, "Pre commit setup successfull");
|
|
31
397
|
}
|
|
32
398
|
execSync("npx ZDPrecommit setupPlugins", {
|
|
33
|
-
cwd:
|
|
399
|
+
cwd: getNodeModulesPath()
|
|
34
400
|
});
|
|
35
401
|
} catch (error) {
|
|
36
402
|
Logger.log(Logger.FAILURE_TYPE, `Kindly retry npm install. & ${error.message}`);
|
|
37
403
|
}
|
|
38
404
|
}
|
|
39
|
-
|
|
405
|
+
async function lint() {
|
|
40
406
|
await validateRemotePackages();
|
|
41
|
-
require(
|
|
42
|
-
}
|
|
407
|
+
require("./lint");
|
|
408
|
+
}
|
|
409
|
+
lint();
|
package/build/lib/postinstall.js
CHANGED
|
@@ -7,8 +7,8 @@ const {
|
|
|
7
7
|
setupHusky
|
|
8
8
|
} = require("../utils/HuskySetup/setupHusky");
|
|
9
9
|
const {
|
|
10
|
-
|
|
11
|
-
} = require("../utils/
|
|
10
|
+
createConfigFiles
|
|
11
|
+
} = require("../utils/ConfigFileUtils/createConfigFiles");
|
|
12
12
|
const {
|
|
13
13
|
Logger
|
|
14
14
|
} = require("../utils/Logger/Logger");
|
|
@@ -34,7 +34,7 @@ async function postInstall() {
|
|
|
34
34
|
await executeMethodsThatReturnBooleanValue("Some issue in writing node_modules path to json", writeFsPaths, null);
|
|
35
35
|
isGitInitialized() ? await executeMethodsThatReturnBooleanValue("Some issue occurred in setting up husky.", setupHusky, null) : null;
|
|
36
36
|
await executeMethodsThatReturnBooleanValue("Make sure zgit.csez.zohocorpin.com is accessible", cloneViaCdt, null);
|
|
37
|
-
await executeMethodsThatReturnBooleanValue("Some issue occurred in creating eslint config file.",
|
|
37
|
+
await executeMethodsThatReturnBooleanValue("Some issue occurred in creating eslint config file.", createConfigFiles, null);
|
|
38
38
|
Logger.log(Logger.SUCCESS_TYPE, "Pre commit setup successfull");
|
|
39
39
|
// arePluginsInstalled();
|
|
40
40
|
} catch (error) {
|
|
@@ -49,7 +49,7 @@ function cloneViaCdt() {
|
|
|
49
49
|
const runningEnv = getRunningEnv();
|
|
50
50
|
if (runningEnv === "CI" || runningEnv === "DEVAUTOMATION") {
|
|
51
51
|
Logger.log(Logger.INFO_TYPE, `Running in ${runningEnv}`);
|
|
52
|
-
absoluteEndPoint = `https://${userName}:${decrypt(token,
|
|
52
|
+
absoluteEndPoint = `https://${userName}:${decrypt(token, process.env.DECRYPT_TOKEN)}@${endPoint}`;
|
|
53
53
|
}
|
|
54
54
|
var commandToCloneCommonConfigRepo = `npx cdt clone --clone:type=${type} --clone:url=${absoluteEndPoint} --clone:branch=${branch} --clone:cacheDir=${cacheDirectory} --clone:proj:name=${commonLinterRepoName}`;
|
|
55
55
|
let isCommonConfigurationClonedSuccessfully = executeSynchronizedCommands(execSync, [commandToCloneCommonConfigRepo, {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const {
|
|
5
|
+
writeFileSync,
|
|
6
|
+
existsSync,
|
|
7
|
+
unlinkSync,
|
|
8
|
+
readFileSync
|
|
9
|
+
} = require('fs');
|
|
10
|
+
const {
|
|
11
|
+
getNodeModulesPath
|
|
12
|
+
} = require('../General/getNodeModulesPath.js');
|
|
13
|
+
const {
|
|
14
|
+
Logger
|
|
15
|
+
} = require('../Logger/Logger.js');
|
|
16
|
+
const {
|
|
17
|
+
executeSynchronizedCommands
|
|
18
|
+
} = require('../General/executeSyncCommands.js');
|
|
19
|
+
const {
|
|
20
|
+
getServicePathElseCommon
|
|
21
|
+
} = require('./getLintConfiguration.js');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates the ESLint configuration file from the service-specific or common template.
|
|
25
|
+
* Also creates the Stylelint configuration file if available.
|
|
26
|
+
*
|
|
27
|
+
* @returns {boolean} Success status of ESLint config creation
|
|
28
|
+
*/
|
|
29
|
+
function createConfigFiles() {
|
|
30
|
+
const eslintConfigFilePath = path.join(getNodeModulesPath(), '.eslintrc.js');
|
|
31
|
+
const stylelintConfigFilePath = path.join(getNodeModulesPath(), '.stylelintrc.js');
|
|
32
|
+
const {
|
|
33
|
+
pathOfServiceSpecificEslintConfigFile,
|
|
34
|
+
cssLintConfig
|
|
35
|
+
} = getServicePathElseCommon();
|
|
36
|
+
try {
|
|
37
|
+
const eslintContent = readConfig(pathOfServiceSpecificEslintConfigFile, 'eslint');
|
|
38
|
+
const stylelintContent = readConfig(cssLintConfig, 'stylelint');
|
|
39
|
+
if (stylelintContent) {
|
|
40
|
+
writeConfig(stylelintConfigFilePath, stylelintContent, 'stylelint');
|
|
41
|
+
}
|
|
42
|
+
if (existsSync(eslintConfigFilePath)) {
|
|
43
|
+
executeSynchronizedCommands(unlinkSync, [eslintConfigFilePath], 'ESLint configuration file removed successfully!', 'Unable to remove the ESLint config file.', false, false);
|
|
44
|
+
}
|
|
45
|
+
return writeConfig(eslintConfigFilePath, eslintContent, 'eslint');
|
|
46
|
+
} catch (error) {
|
|
47
|
+
Logger.log(Logger.FAILURE_TYPE, error);
|
|
48
|
+
Logger.log(Logger.FAILURE_TYPE, 'Error occurred while creating ESLint config file');
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Reads a configuration file with logging and error handling.
|
|
55
|
+
*/
|
|
56
|
+
function readConfig(filePath, type) {
|
|
57
|
+
return executeSynchronizedCommands(readFileSync, [filePath, 'utf-8'], '', `Unable to read content of ${type} config file.`, true, false);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Writes a configuration file with logging and error handling.
|
|
62
|
+
*/
|
|
63
|
+
function writeConfig(filePath, content, type) {
|
|
64
|
+
return executeSynchronizedCommands(writeFileSync, [filePath, content, 'utf-8'], `${type[0].toUpperCase() + type.slice(1)} configuration file created successfully!`, `Unable to create and write a ${type} configuration file.`, false, true);
|
|
65
|
+
}
|
|
66
|
+
module.exports = {
|
|
67
|
+
createConfigFiles
|
|
68
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const {
|
|
5
|
+
readdirSync
|
|
6
|
+
} = require('fs');
|
|
7
|
+
const {
|
|
8
|
+
getNodeModulesPath
|
|
9
|
+
} = require('../General/getNodeModulesPath');
|
|
10
|
+
const {
|
|
11
|
+
executeSynchronizedCommands
|
|
12
|
+
} = require('../General/executeSyncCommands');
|
|
13
|
+
const {
|
|
14
|
+
getLibraryInstalledLocation
|
|
15
|
+
} = require('../General/getLibraryInstalledLocation');
|
|
16
|
+
function getEslintExecutablePath() {
|
|
17
|
+
let eslintLibraryName = 'eslint';
|
|
18
|
+
let librariesInNodeModulesOfProject = executeSynchronizedCommands(readdirSync, [path.join(getNodeModulesPath(), 'node_modules')], '', 'Unable to get the plugins inside node_modules', true, false);
|
|
19
|
+
let isEslintInstalledinProject = librariesInNodeModulesOfProject.some(library => library === eslintLibraryName);
|
|
20
|
+
return isEslintInstalledinProject ? path.join(getNodeModulesPath(), 'node_modules', eslintLibraryName, 'bin', 'eslint.js') : path.join(getLibraryInstalledLocation(), 'node_modules', eslintLibraryName, 'bin', 'eslint.js');
|
|
21
|
+
}
|
|
22
|
+
module.exports = {
|
|
23
|
+
getEslintExecutablePath
|
|
24
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const {
|
|
5
|
+
existsSync
|
|
6
|
+
} = require('fs');
|
|
7
|
+
const {
|
|
8
|
+
endPoint,
|
|
9
|
+
commonLinterRepoName
|
|
10
|
+
} = require("../../../jsonUtils/commonLinterRepoDetails.js");
|
|
11
|
+
const {
|
|
12
|
+
getRepoName
|
|
13
|
+
} = require('../GitActions/gitActions.js');
|
|
14
|
+
const {
|
|
15
|
+
getLibraryInstalledLocation
|
|
16
|
+
} = require('../General/getLibraryInstalledLocation.js');
|
|
17
|
+
const {
|
|
18
|
+
executeMethodsThatMayThrowException
|
|
19
|
+
} = require("../General/wrapperFunctionToExecuteAFunction.js");
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @function getLintConfiguration - returns eslint configuration file from common linters repo
|
|
23
|
+
* @returns {object} - containing properties of the eslint configuration file
|
|
24
|
+
*/
|
|
25
|
+
function getServicePathElseCommon() {
|
|
26
|
+
const repoName = getRepoName();
|
|
27
|
+
const libraryInstalledLocation = getLibraryInstalledLocation();
|
|
28
|
+
let commonConfigPath = path.join(libraryInstalledLocation, commonLinterRepoName, 'common', 'index.js');
|
|
29
|
+
const _configurationPath = repoName && existsSync(path.join(libraryInstalledLocation, commonLinterRepoName, 'services', repoName, 'index.js')) ? path.join(libraryInstalledLocation, commonLinterRepoName, 'services', repoName, 'index.js') : commonConfigPath;
|
|
30
|
+
let _pathOfServiceSpecificEslintConfigFile = repoName && existsSync(path.join(libraryInstalledLocation, commonLinterRepoName, 'services', repoName, '.eslintrc.js')) ? path.join(libraryInstalledLocation, commonLinterRepoName, 'services', repoName, '.eslintrc.js') : path.join(libraryInstalledLocation, commonLinterRepoName, 'common', '.eslintrc.js');
|
|
31
|
+
let _pluginVersionPath = repoName && existsSync(path.join(libraryInstalledLocation, commonLinterRepoName, 'services', repoName, 'pluginVersion.js')) ? path.join(libraryInstalledLocation, commonLinterRepoName, 'services', repoName, 'pluginVersion.js') : undefined;
|
|
32
|
+
let _stylelintPath = repoName && existsSync(path.join(libraryInstalledLocation, commonLinterRepoName, 'services', repoName, '.stylelintrc.js')) ? path.join(libraryInstalledLocation, commonLinterRepoName, 'services', repoName, '.stylelintrc.js') : path.join(libraryInstalledLocation, commonLinterRepoName, 'common', '.stylelintrc.js');
|
|
33
|
+
return {
|
|
34
|
+
configurationPath: _configurationPath,
|
|
35
|
+
pathOfServiceSpecificEslintConfigFile: _pathOfServiceSpecificEslintConfigFile,
|
|
36
|
+
pluginVersionPath: _pluginVersionPath,
|
|
37
|
+
cssLintConfig: _stylelintPath
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function getLintConfigurationUtil() {
|
|
41
|
+
const {
|
|
42
|
+
configurationPath
|
|
43
|
+
} = getServicePathElseCommon();
|
|
44
|
+
const exceptionHandleObject = {
|
|
45
|
+
rulesConfig: [{}, {}],
|
|
46
|
+
plugins: [],
|
|
47
|
+
extendPlugins: []
|
|
48
|
+
};
|
|
49
|
+
return executeMethodsThatMayThrowException(exceptionHandleObject, `Kindly Ensure that Configuration is setup in Configuration repo \n ${endPoint}`, require, configurationPath);
|
|
50
|
+
}
|
|
51
|
+
module.exports = {
|
|
52
|
+
getLintConfigurationUtil,
|
|
53
|
+
getServicePathElseCommon
|
|
54
|
+
};
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
const {
|
|
4
4
|
Logger
|
|
5
5
|
} = require('../Logger/Logger');
|
|
6
|
-
|
|
6
|
+
const {
|
|
7
|
+
existsSync
|
|
8
|
+
} = require("fs");
|
|
7
9
|
/**
|
|
8
10
|
* @function filterFiles - removes certain files from set of source files
|
|
9
11
|
* @param {Array} arrayOfFilesToBeFiltered - array of files which must be filtered
|
|
@@ -12,6 +14,29 @@ const {
|
|
|
12
14
|
* @returns {Array} - containing the resultant set of files after filtering
|
|
13
15
|
*/
|
|
14
16
|
function filterFiles(arrayOfFilesToBeFiltered, filesToBeRemoved, isConfigFileNeedToBeRemoved = false) {
|
|
17
|
+
/**
|
|
18
|
+
* @function filterFilesByExtension - filter javascript files. omit feature files
|
|
19
|
+
* @param {Array<String>} lintFiles - linter files as Array
|
|
20
|
+
* @returns {Array<String>}
|
|
21
|
+
* */
|
|
22
|
+
function filterFilesByExtension(lintFiles) {
|
|
23
|
+
return lintFiles.reduce((files, currentFile) => {
|
|
24
|
+
if (currentFile.includes('.feature') && existsSync(currentFile)) {
|
|
25
|
+
files.featureFiles.push(currentFile);
|
|
26
|
+
}
|
|
27
|
+
if (currentFile.includes('.js') || currentFile.includes('.ts') || currentFile.includes('.tsx') || currentFile.includes('.jsx') && existsSync(currentFile)) {
|
|
28
|
+
files.JsFiles.push(currentFile);
|
|
29
|
+
}
|
|
30
|
+
if (currentFile.includes('.css') || currentFile.includes('.scss') && existsSync(currentFile)) {
|
|
31
|
+
files.CssFiles.push(currentFile);
|
|
32
|
+
}
|
|
33
|
+
return files;
|
|
34
|
+
}, {
|
|
35
|
+
featureFiles: [],
|
|
36
|
+
JsFiles: [],
|
|
37
|
+
CssFiles: []
|
|
38
|
+
});
|
|
39
|
+
}
|
|
15
40
|
if (filesToBeRemoved.length !== 0) {
|
|
16
41
|
if (isConfigFileNeedToBeRemoved) {
|
|
17
42
|
arrayOfFilesToBeFiltered.filter(file => {
|
|
@@ -31,7 +56,7 @@ function filterFiles(arrayOfFilesToBeFiltered, filesToBeRemoved, isConfigFileNee
|
|
|
31
56
|
return false;
|
|
32
57
|
}
|
|
33
58
|
});
|
|
34
|
-
return filteredArrayofFilesWithoutConfigFile;
|
|
59
|
+
return filterFilesByExtension(filteredArrayofFilesWithoutConfigFile);
|
|
35
60
|
} else if (filesToBeRemoved.length === 0) {
|
|
36
61
|
return arrayOfFilesToBeFiltered;
|
|
37
62
|
}
|
|
@@ -18,6 +18,7 @@ const {
|
|
|
18
18
|
* @function getTimeStampInfo - to fetch various timestamp details
|
|
19
19
|
* @returns {object} - each property of the object denotes various timestamp details
|
|
20
20
|
*/
|
|
21
|
+
|
|
21
22
|
function getTimeStampInfo() {
|
|
22
23
|
const date = new Date();
|
|
23
24
|
return {
|
|
@@ -34,6 +35,7 @@ function getTimeStampInfo() {
|
|
|
34
35
|
* @function getEnv - to fetch the os type
|
|
35
36
|
* @returns {string} - indicates the os
|
|
36
37
|
*/
|
|
38
|
+
|
|
37
39
|
function getEnv() {
|
|
38
40
|
return os.type();
|
|
39
41
|
}
|
|
@@ -42,6 +44,7 @@ function getEnv() {
|
|
|
42
44
|
* @function getConfigPath - get a path of lint configuration path
|
|
43
45
|
* @returns {string}
|
|
44
46
|
*/
|
|
47
|
+
|
|
45
48
|
function getConfigPath() {
|
|
46
49
|
const configPath = path.resolve(process.cwd(), 'lint.config.js');
|
|
47
50
|
const defaultConfigPath = path.resolve(__dirname, '..', '..', 'setup', 'sample.config.js');
|
|
@@ -52,27 +55,29 @@ function getConfigPath() {
|
|
|
52
55
|
* @function getConfiguration - get configuration object of lint configuration
|
|
53
56
|
* @returns
|
|
54
57
|
*/
|
|
58
|
+
|
|
55
59
|
function getConfigurationPrecommit() {
|
|
56
60
|
return require(getConfigPath());
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
/**
|
|
60
|
-
* @function
|
|
61
|
-
* @returns {
|
|
64
|
+
* @function getRunningEnv - Retrieves the current running environment by executing the `npm config get lint_env` command.
|
|
65
|
+
* @returns {string} The current lint environment value set in the npm config.
|
|
62
66
|
*/
|
|
67
|
+
|
|
63
68
|
function getSupportedLanguage() {
|
|
64
69
|
const {
|
|
65
70
|
supportedExtensions
|
|
66
71
|
} = getConfigurationPrecommit();
|
|
67
72
|
const _language = supportedExtensions;
|
|
73
|
+
_language.push('.js');
|
|
74
|
+
_language.push('.jsx');
|
|
75
|
+
_language.push('.ts');
|
|
76
|
+
_language.push('.tsx');
|
|
77
|
+
_language.push('.css');
|
|
78
|
+
_language.push('.scss');
|
|
68
79
|
return _language;
|
|
69
80
|
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* @function getRunningEnv - Retrieves the current running environment by executing the `npm config get lint_env` command.
|
|
73
|
-
* @returns {string} The current lint environment value set in the npm config.
|
|
74
|
-
*/
|
|
75
|
-
|
|
76
81
|
function getRunningEnv() {
|
|
77
82
|
const command = "npm config get lint_env";
|
|
78
83
|
return execSync(command, {
|
|
@@ -91,7 +96,7 @@ function getRunningEnv() {
|
|
|
91
96
|
function getLastCommitHash() {
|
|
92
97
|
try {
|
|
93
98
|
const cmd = `curl --header "PRIVATE-TOKEN: ${readOnlyToken}" --url ${commitHashEndPoint}`;
|
|
94
|
-
return JSON.parse(execSync(cmd))[0]
|
|
99
|
+
return JSON.parse(execSync(cmd))[0].id;
|
|
95
100
|
} catch (err) {
|
|
96
101
|
Logger.log(Logger.FAILURE_TYPE, err);
|
|
97
102
|
return null;
|
|
@@ -3,15 +3,18 @@
|
|
|
3
3
|
const {
|
|
4
4
|
Worker
|
|
5
5
|
} = require('worker_threads');
|
|
6
|
+
const {
|
|
7
|
+
Logger
|
|
8
|
+
} = require('../../Logger/Logger');
|
|
6
9
|
async function installPluginsByWorker(plugins) {
|
|
7
10
|
try {
|
|
8
11
|
const results = await Promise.all(plugins.map(pkg => runWorker({
|
|
9
12
|
packageName: pkg.packageName,
|
|
10
13
|
version: pkg.version
|
|
11
14
|
})));
|
|
12
|
-
|
|
15
|
+
Logger.log(Logger.SUCCESS_TYPE, 'Package are installed By from workers:', results.join('\n'));
|
|
13
16
|
} catch (error) {
|
|
14
|
-
|
|
17
|
+
Logger.log(Logger.FAILURE_TYPE, 'Error:', error);
|
|
15
18
|
}
|
|
16
19
|
}
|
|
17
20
|
function runWorker(data) {
|
|
@@ -19,7 +19,7 @@ const {
|
|
|
19
19
|
} = require('../General/wrapperFunctionToExecuteAFunction');
|
|
20
20
|
const {
|
|
21
21
|
getServicePathElseCommon
|
|
22
|
-
} = require('../
|
|
22
|
+
} = require('../ConfigFileUtils/getLintConfiguration');
|
|
23
23
|
function getAllPlugins() {
|
|
24
24
|
let serviceSpecificPlugins = [];
|
|
25
25
|
const pathToCommonPluginsFile = path.join(getLibraryInstalledLocation(), commonLinterRepoName, 'common', 'pluginVersion.js');
|
|
@@ -58,7 +58,10 @@ function checkIfPluginsAreInstalled() {
|
|
|
58
58
|
if (isPluginPresent && checkPluginHasProperVersion(packageName, pluginPath, version)) {
|
|
59
59
|
return false;
|
|
60
60
|
}
|
|
61
|
-
return
|
|
61
|
+
return {
|
|
62
|
+
packageName,
|
|
63
|
+
version
|
|
64
|
+
};
|
|
62
65
|
}).filter(Boolean);
|
|
63
66
|
if (uninstalledPlugins.length > 0) {
|
|
64
67
|
plugin.noPluginMessage = '';
|
|
@@ -23,6 +23,7 @@ const {
|
|
|
23
23
|
* @function installPlugins - installs uninstalled plugins for the project
|
|
24
24
|
* @returns {boolean} - indicating if plugins to be installed are installed successfully or not
|
|
25
25
|
*/
|
|
26
|
+
|
|
26
27
|
function installPlugins(pluginsToBeInstalled) {
|
|
27
28
|
if (pluginsToBeInstalled.length === 0) {
|
|
28
29
|
Logger.log(Logger.INFO_TYPE, 'Plugins are already installed');
|
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { getLintConfigurationUtil } = require("./build/utils/
|
|
1
|
+
const { getLintConfigurationUtil } = require("./build/utils/ConfigFileUtils/getLintConfiguration");
|
|
2
2
|
const { rulesConfig, plugins, extendPlugins } = getLintConfigurationUtil();
|
|
3
3
|
|
|
4
4
|
module.exports = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zohodesk/codestandard-validator",
|
|
3
|
-
"version": "0.0.6-exp-
|
|
3
|
+
"version": "0.0.6-exp-20",
|
|
4
4
|
"description": "library to enforce code standard using eslint",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"@babel/core": "7.24.7",
|
|
23
23
|
"@babel/plugin-transform-runtime": "7.24.7",
|
|
24
24
|
"@babel/preset-env": "7.24.7",
|
|
25
|
-
"husky": "7.0.4"
|
|
25
|
+
"husky": "7.0.4",
|
|
26
|
+
"stylelint": "^16.0.0"
|
|
26
27
|
}
|
|
27
28
|
}
|