@zohodesk/codestandard-validator 0.0.7 → 1.0.0-exp-2
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/.babelrc +1 -1
- package/bin/execute.js +1 -1
- package/build/hooks/Precommit/commit.js +50 -0
- package/build/hooks/Precommit/errorhelpers.js +39 -0
- package/build/hooks/Precommit/guard.js +50 -0
- package/build/hooks/Precommit/lint.js +96 -174
- package/build/hooks/Precommit/pre-commit.js +88 -29
- package/build/hooks/Precommit/utils.js +56 -0
- package/build/hooks/hook.js +40 -0
- package/build/lib/cli.js +2 -2
- package/build/lib/postinstall.js +3 -3
- package/build/utils/CloneCommonLinterRepo/cloneViaCdt.js +39 -26
- package/build/utils/ConfigFileUtils/createConfigFile.js +63 -0
- package/build/utils/ConfigFileUtils/getLintConfiguration.js +2 -2
- package/build/utils/FileAndFolderOperations/filterFiles.js +27 -2
- package/build/utils/General/getGeneralInfo.js +64 -3
- package/build/utils/General/getNodeModulesPath.js +4 -1
- package/build/utils/General/writeProjectDetailsToJson.js +5 -1
- package/build/utils/PluginsInstallation/arePluginsInstalled.js +2 -6
- package/build/utils/PluginsInstallation/checkIfPluginsAreInstalled.js +32 -59
- package/build/utils/PluginsInstallation/installPlugins.js +12 -65
- package/build/utils/PrecommitUsingGitSetup/update-git-precommithook.js +42 -35
- package/changeLog.md +7 -1
- package/index.js +1 -1
- package/jsonUtils/commonLinterRepoDetails.js +1 -1
- package/package.json +4 -2
- package/build/hooks/PrePush/pre-push.js +0 -247
- package/build/hooks/Precommit/filterUtils.js +0 -42
- package/build/utils/ConfigFileUtils/createConfigFiles.js +0 -68
- package/build/utils/EslintConfigFileUtils/createEslintConfigFile.js +0 -54
- package/build/utils/EslintConfigFileUtils/getEslintExecutablePath.js +0 -24
- package/build/utils/EslintConfigFileUtils/getLintConfiguration.js +0 -52
- package/build/utils/PluginsInstallation/Worker/installPluginsByWoker.js +0 -38
- package/build/utils/PluginsInstallation/Worker/worker.js +0 -33
package/.babelrc
CHANGED
package/bin/execute.js
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
filterFiles
|
|
6
|
+
} = require("../../utils/FileAndFolderOperations/filterFiles");
|
|
7
|
+
const {
|
|
8
|
+
Logger
|
|
9
|
+
} = require("../../utils/Logger/Logger");
|
|
10
|
+
const {
|
|
11
|
+
handleMergeCommit,
|
|
12
|
+
ensurePluginsInstalled,
|
|
13
|
+
safeGetStagedFiles,
|
|
14
|
+
safeGetBranch
|
|
15
|
+
} = require("./guard");
|
|
16
|
+
const {
|
|
17
|
+
runLintWorkflow
|
|
18
|
+
} = require("./lint");
|
|
19
|
+
process.env.DECRYPT_SONARQUBE = 7;
|
|
20
|
+
process.env.DECRYPT_TOKEN = 12;
|
|
21
|
+
global.analytics = {
|
|
22
|
+
status: "SUCCESS",
|
|
23
|
+
sonarQubeStatus: false,
|
|
24
|
+
message: "No issues are found, your code adheres to the required standards.",
|
|
25
|
+
isExemptionApproved: false,
|
|
26
|
+
totalIssues: 0
|
|
27
|
+
};
|
|
28
|
+
async function preCommitHook() {
|
|
29
|
+
Logger.log(Logger.INFO_TYPE, "Executing pre commit hook...");
|
|
30
|
+
Logger.log(Logger.INFO_TYPE, `working dir: ${process.cwd()}`);
|
|
31
|
+
if (await handleMergeCommit()) return;
|
|
32
|
+
if (!(await ensurePluginsInstalled())) return;
|
|
33
|
+
const stagedFiles = await safeGetStagedFiles();
|
|
34
|
+
if (stagedFiles.length === 0) {
|
|
35
|
+
Logger.log(Logger.INFO_TYPE, "No staged files. Commit skipped.");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const {
|
|
39
|
+
JsFiles
|
|
40
|
+
} = filterFiles(stagedFiles, [".eslintrc.js"], true);
|
|
41
|
+
const branch = await safeGetBranch();
|
|
42
|
+
const shouldAbort = await runLintWorkflow(JsFiles, branch);
|
|
43
|
+
if (shouldAbort) {
|
|
44
|
+
Logger.log(Logger.FAILURE_TYPE, "There are linter errors/warnings. Commit aborted.");
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
Logger.log(Logger.SUCCESS_TYPE, "Commit Successful");
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
preCommitHook();
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
Logger
|
|
5
|
+
} = require("../../utils/Logger/Logger");
|
|
6
|
+
const {
|
|
7
|
+
calculateGitDiffForFile
|
|
8
|
+
} = require("./lint");
|
|
9
|
+
function parseDiffHunks(diff) {
|
|
10
|
+
return diff.filter(line => line.startsWith("@@")).map(hunk => {
|
|
11
|
+
const [start, count = 1] = hunk.split(" ")[2].slice(1).split(",").map(Number);
|
|
12
|
+
return [start, start + (count - 1)];
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
async function filterErrorsByChangedLines(errors, branch, file) {
|
|
16
|
+
const diff = await calculateGitDiffForFile(branch, file);
|
|
17
|
+
const changedRanges = parseDiffHunks(diff);
|
|
18
|
+
return errors.filter(err => {
|
|
19
|
+
const line = parseInt(err.split(" ")[0].split(":")[0], 10);
|
|
20
|
+
return changedRanges.some(([s, e]) => line >= s && line <= e);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async function createBranchDiff(diff) {
|
|
24
|
+
// const diff = await calculateGitDiffForFile(branch, file);
|
|
25
|
+
// const changeset = extractDiffHunks(diff)
|
|
26
|
+
}
|
|
27
|
+
function filterFileLevelErrors(errors) {
|
|
28
|
+
return errors.slice(1, -2); // strip ESLint summary lines
|
|
29
|
+
}
|
|
30
|
+
function logErrors(file, errors) {
|
|
31
|
+
Logger.log(Logger.FAILURE_TYPE, `\x1b[1m${file}\x1b[0m`);
|
|
32
|
+
errors.forEach(err => Logger.log(Logger.FAILURE_TYPE, `\x1b[37m${err.trimEnd()}\x1b[0m`));
|
|
33
|
+
}
|
|
34
|
+
module.exports = {
|
|
35
|
+
filterErrorsByChangedLines,
|
|
36
|
+
filterFileLevelErrors,
|
|
37
|
+
logErrors,
|
|
38
|
+
parseDiffHunks
|
|
39
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
getBranchName
|
|
5
|
+
} = require("../../utils/GitActions/gitActions");
|
|
6
|
+
const {
|
|
7
|
+
Logger
|
|
8
|
+
} = require("../../utils/Logger/Logger");
|
|
9
|
+
const {
|
|
10
|
+
isMergeCommit,
|
|
11
|
+
areAllPluginsInstalled,
|
|
12
|
+
getStagedFiles
|
|
13
|
+
} = require("./utils");
|
|
14
|
+
async function handleMergeCommit() {
|
|
15
|
+
if (await isMergeCommit()) {
|
|
16
|
+
Logger.log(Logger.INFO_TYPE, "Merge detected. Skipping pre-commit check.");
|
|
17
|
+
process.exit(0);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
async function ensurePluginsInstalled() {
|
|
23
|
+
if (areAllPluginsInstalled()) return true;
|
|
24
|
+
Logger.log(Logger.FAILURE_TYPE, "Commit failed since some lint plugins are not installed");
|
|
25
|
+
Logger.log(Logger.INFO_TYPE, `Run \x1b[37mnpx ZDPrecommit setupPlugins \x1b[33m in the project root to install them.`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
async function safeGetStagedFiles() {
|
|
30
|
+
try {
|
|
31
|
+
return await getStagedFiles();
|
|
32
|
+
} catch {
|
|
33
|
+
Logger.log(Logger.INFO_TYPE, "Error fetching staged files");
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function safeGetBranch() {
|
|
38
|
+
try {
|
|
39
|
+
return await getBranchName();
|
|
40
|
+
} catch {
|
|
41
|
+
Logger.log(Logger.INFO_TYPE, "Error fetching current branch");
|
|
42
|
+
return "";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
module.exports = {
|
|
46
|
+
safeGetBranch,
|
|
47
|
+
safeGetStagedFiles,
|
|
48
|
+
handleMergeCommit,
|
|
49
|
+
ensurePluginsInstalled
|
|
50
|
+
};
|
|
@@ -3,209 +3,131 @@
|
|
|
3
3
|
const {
|
|
4
4
|
exec
|
|
5
5
|
} = require('child_process');
|
|
6
|
+
const {
|
|
7
|
+
promisify
|
|
8
|
+
} = require('util');
|
|
6
9
|
const fs = require('fs');
|
|
7
10
|
const path = require('path');
|
|
11
|
+
const {
|
|
12
|
+
getNodeModulesPath
|
|
13
|
+
} = require('../../utils/General/getNodeModulesPath');
|
|
8
14
|
const {
|
|
9
15
|
getEslintExecutablePath
|
|
10
16
|
} = require('../../utils/ConfigFileUtils/getEslintExecutablePath');
|
|
11
17
|
const {
|
|
12
|
-
|
|
13
|
-
} = require('../../utils/General/
|
|
18
|
+
getRootDirectory
|
|
19
|
+
} = require('../../utils/General/RootDirectoryUtils/getRootDirectory');
|
|
14
20
|
const {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} = require('../../utils/FileAndFolderOperations/filterFiles');
|
|
21
|
+
getSupportedLanguage
|
|
22
|
+
} = require('../../utils/General/getGeneralInfo');
|
|
18
23
|
const {
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
filterFileLevelErrors,
|
|
25
|
+
filterErrorsByChangedLines,
|
|
26
|
+
logErrors
|
|
27
|
+
} = require('./errorhelpers');
|
|
21
28
|
const {
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
Execution,
|
|
30
|
+
SonarQube,
|
|
31
|
+
EsLint
|
|
32
|
+
} = require('@zohodesk/codestandard-analytics');
|
|
24
33
|
const {
|
|
25
34
|
getBranchName
|
|
26
35
|
} = require('../../utils/GitActions/gitActions');
|
|
27
36
|
const {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
getRootDirectory
|
|
33
|
-
} = require('../../utils/General/RootDirectoryUtils/getRootDirectory');
|
|
34
|
-
const {
|
|
35
|
-
impactBasedPrecommit,
|
|
36
|
-
shouldWarningsAbortCommit
|
|
37
|
-
} = getConfigurationPrecommit();
|
|
38
|
-
|
|
39
|
-
/* ------------------------------------------
|
|
40
|
-
Git Helpers
|
|
41
|
-
------------------------------------------ */
|
|
42
|
-
|
|
43
|
-
function isMergeCommit() {
|
|
44
|
-
return new Promise((resolve, reject) => {
|
|
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());
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
function getStagedFiles() {
|
|
52
|
-
return new Promise((resolve, reject) => {
|
|
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')));
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
function filterDeletedFiles(files) {
|
|
62
|
-
return files.filter(file => fs.existsSync(path.resolve(getRootDirectory(), file)));
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/* ------------------------------------------
|
|
66
|
-
Lint Helpers
|
|
67
|
-
------------------------------------------ */
|
|
68
|
-
|
|
69
|
-
function lintFiles(filePath) {
|
|
37
|
+
extractDiffHunks
|
|
38
|
+
} = require('./utils');
|
|
39
|
+
const execAsync = promisify(exec);
|
|
40
|
+
async function lintFiles(filePath) {
|
|
70
41
|
const ext = path.extname(filePath);
|
|
71
|
-
if (['.js', '.ts', '.tsx', '.jsx'].includes(ext)) {
|
|
42
|
+
if (['.js', '.ts', '.tsx', '.jsx', '.properties'].includes(ext)) {
|
|
72
43
|
return findEslintErrors(filePath);
|
|
73
44
|
}
|
|
74
45
|
if (['.css', '.scss'].includes(ext)) {
|
|
75
46
|
return findStyleLintErrors(filePath);
|
|
76
47
|
}
|
|
77
|
-
return
|
|
48
|
+
return [];
|
|
78
49
|
}
|
|
79
|
-
function
|
|
80
|
-
const config = path.resolve(getNodeModulesPath(), '.stylelintrc.js');
|
|
81
|
-
const absolutePath = path.join(getRootDirectory(), filePath);
|
|
82
|
-
return new Promise((resolve, reject) => {
|
|
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');
|
|
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();
|
|
50
|
+
async function findEslintErrors(file) {
|
|
100
51
|
const nodeModulesPath = getNodeModulesPath();
|
|
52
|
+
const eslintPath = getEslintExecutablePath();
|
|
101
53
|
const eslintConfig = `${nodeModulesPath}/.eslintrc.js`;
|
|
54
|
+
var rulesArrayReport = [];
|
|
55
|
+
if (!fs.existsSync(nodeModulesPath)) {
|
|
56
|
+
Logger.log(Logger.INFO_TYPE, 'node_modules not found');
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
102
59
|
if (!fs.existsSync(eslintPath)) {
|
|
103
|
-
Logger.log(Logger.INFO_TYPE, 'Eslint executable not found.
|
|
104
|
-
return
|
|
60
|
+
Logger.log(Logger.INFO_TYPE, 'Eslint executable not found. Make sure eslint plugin is installed');
|
|
61
|
+
return [];
|
|
105
62
|
}
|
|
106
|
-
return
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
Logger.log(Logger.FAILURE_TYPE, err);
|
|
112
|
-
return reject('Error executing eslint command');
|
|
113
|
-
}
|
|
114
|
-
resolve([]);
|
|
115
|
-
});
|
|
63
|
+
return execAsync(`npx --ignore-existing "${eslintPath}" --config "${eslintConfig}" --no-inline-config --resolve-plugins-relative-to="${nodeModulesPath}/node_modules" ${file}`).then(({
|
|
64
|
+
stderr
|
|
65
|
+
}) => stderr ? stderr.trim().split('\n') : []).catch(err => {
|
|
66
|
+
Logger.log(Logger.FAILURE_TYPE, err);
|
|
67
|
+
throw new Error('Error executing eslint command');
|
|
116
68
|
});
|
|
117
69
|
}
|
|
118
|
-
function
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
70
|
+
function findStyleLintErrors(filePath) {
|
|
71
|
+
const configFile = path.resolve(getNodeModulesPath(), '.stylelintrc.js');
|
|
72
|
+
const absolutePath = path.join(getRootDirectory(), filePath);
|
|
73
|
+
return execAsync(`npx stylelint ${absolutePath} --config ${configFile}`, {
|
|
74
|
+
cwd: getNodeModulesPath()
|
|
75
|
+
}).then(({
|
|
76
|
+
stdout
|
|
77
|
+
}) => stdout ? stdout.trim().split('\n') : []).catch(err => {
|
|
78
|
+
Logger.log(Logger.FAILURE_TYPE, err);
|
|
79
|
+
return [];
|
|
124
80
|
});
|
|
125
81
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
console.log('unInstalledPlugins', uninstalledPlugins);
|
|
136
|
-
return uninstalledPlugins.length === 0;
|
|
137
|
-
}
|
|
138
|
-
function isOnlyWarningsPresent(errors) {
|
|
139
|
-
const severities = errors.map(e => e.split(' ').find(w => w === 'error' || w === 'warning'));
|
|
140
|
-
return !severities.includes('error');
|
|
82
|
+
async function calculateGitDiffForFile(branch, file) {
|
|
83
|
+
try {
|
|
84
|
+
const {
|
|
85
|
+
stdout
|
|
86
|
+
} = await execAsync(`git diff -U0 ${branch.trim()} ${file}`);
|
|
87
|
+
return stdout;
|
|
88
|
+
} catch (err) {
|
|
89
|
+
throw err;
|
|
90
|
+
}
|
|
141
91
|
}
|
|
92
|
+
async function runLintWorkflow(files, branch) {
|
|
93
|
+
const branchDiff = {
|
|
94
|
+
diffs: []
|
|
95
|
+
};
|
|
96
|
+
let shouldAbort = false;
|
|
97
|
+
var branchName = getBranchName();
|
|
98
|
+
for (const file of files) {
|
|
99
|
+
if (!getSupportedLanguage().includes(path.extname(file))) continue;
|
|
100
|
+
const changeset = extractDiffHunks(await calculateGitDiffForFile(branchName, file));
|
|
101
|
+
const diff = {
|
|
102
|
+
old_path: file,
|
|
103
|
+
new_path: file,
|
|
104
|
+
diff: changeset
|
|
105
|
+
};
|
|
106
|
+
branchDiff.diffs.push(diff);
|
|
107
|
+
// const filteredErrors = impactBasedPrecommit
|
|
108
|
+
// ? await filterErrorsByChangedLines(errors, branch, file)
|
|
109
|
+
// : filterFileLevelErrors(errors);
|
|
142
110
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
async function preCommitHook() {
|
|
148
|
-
Logger.log(Logger.INFO_TYPE, 'Executing pre commit hook...');
|
|
149
|
-
Logger.log(Logger.INFO_TYPE, `Working directory: ${process.cwd()}`);
|
|
150
|
-
try {
|
|
151
|
-
await isMergeCommit();
|
|
152
|
-
Logger.log(Logger.INFO_TYPE, 'Looks like you have merged. So skipping pre-commit check');
|
|
153
|
-
process.exit(0);
|
|
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;
|
|
170
|
-
try {
|
|
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);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
} else {
|
|
189
|
-
relevantErrors = lintResults.slice(1, -2);
|
|
190
|
-
}
|
|
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);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
if (shouldAbort) {
|
|
204
|
-
Logger.log(Logger.FAILURE_TYPE, 'There are eslint errors/warnings. Aborting commit.');
|
|
205
|
-
process.exit(1);
|
|
206
|
-
}
|
|
207
|
-
Logger.log(Logger.SUCCESS_TYPE, 'Commit Successful');
|
|
208
|
-
process.exit(0);
|
|
111
|
+
// if (filteredErrors.length > 0) {
|
|
112
|
+
// logErrors(file, filteredErrors);
|
|
113
|
+
// shouldAbort ||= shouldWarningsAbortCommit || !isOnlyWarnings(filteredErrors);
|
|
114
|
+
// }
|
|
209
115
|
}
|
|
116
|
+
const diffPath = path.resolve(getNodeModulesPath(), 'diffBranch.json');
|
|
117
|
+
fs.writeFileSync(diffPath, JSON.stringify(diffPath));
|
|
118
|
+
const cliobj = {
|
|
119
|
+
env: 'ci',
|
|
120
|
+
cmdExecuted: 'dev-ci'
|
|
121
|
+
};
|
|
122
|
+
const execute = new Execution(EsLint, SonarQube, cliobj);
|
|
123
|
+
await execute.executeLintHandler();
|
|
124
|
+
await execute.executeMetricHandler();
|
|
125
|
+
return global.analytics.status == 'FAILURE' ? true : false;
|
|
210
126
|
}
|
|
211
|
-
|
|
127
|
+
module.exports = {
|
|
128
|
+
runLintWorkflow,
|
|
129
|
+
lintFiles,
|
|
130
|
+
findEslintErrors,
|
|
131
|
+
findStyleLintErrors,
|
|
132
|
+
calculateGitDiffForFile
|
|
133
|
+
};
|
|
@@ -7,13 +7,12 @@ 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
|
|
16
|
-
filterWarningInFile
|
|
15
|
+
filterFiles
|
|
17
16
|
} = require('../../utils/FileAndFolderOperations/filterFiles');
|
|
18
17
|
const {
|
|
19
18
|
Logger
|
|
@@ -87,6 +86,27 @@ function filterDeltedFileFromStagedFiles(files) {
|
|
|
87
86
|
return false;
|
|
88
87
|
});
|
|
89
88
|
}
|
|
89
|
+
async function lintFiles(filePath) {
|
|
90
|
+
switch (String(path.extname(filePath))) {
|
|
91
|
+
case '.js':
|
|
92
|
+
case '.ts':
|
|
93
|
+
case '.tsx':
|
|
94
|
+
case '.jsx':
|
|
95
|
+
case '.properties':
|
|
96
|
+
{
|
|
97
|
+
return await findEslintErrors(filePath);
|
|
98
|
+
}
|
|
99
|
+
case '.css':
|
|
100
|
+
case '.scss':
|
|
101
|
+
{
|
|
102
|
+
return await findStyleLintErrors(filePath);
|
|
103
|
+
}
|
|
104
|
+
default:
|
|
105
|
+
{
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
90
110
|
|
|
91
111
|
/**
|
|
92
112
|
* @function findEslintErrors - method Lint given file based on given configuration
|
|
@@ -94,7 +114,7 @@ function filterDeltedFileFromStagedFiles(files) {
|
|
|
94
114
|
* @returns {Array<string>} - array of command line report as a string
|
|
95
115
|
*/
|
|
96
116
|
|
|
97
|
-
|
|
117
|
+
function findEslintErrors(file) {
|
|
98
118
|
let nodeModulesPathOfProject = `${getNodeModulesPath()}`;
|
|
99
119
|
let eslintExecutablePath = getEslintExecutablePath();
|
|
100
120
|
let eslintConfigurationFilePath = `${nodeModulesPathOfProject}/.eslintrc.js`;
|
|
@@ -121,6 +141,39 @@ async function findEslintErrors(file) {
|
|
|
121
141
|
Logger.log(Logger.INFO_TYPE, 'node_modules not found');
|
|
122
142
|
}
|
|
123
143
|
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
*
|
|
147
|
+
* @param {*} params
|
|
148
|
+
*/
|
|
149
|
+
function findStyleLintErrors(filePath) {
|
|
150
|
+
const configFilePath = path.resolve(getNodeModulesPath(), '.stylelintrc.js');
|
|
151
|
+
const absolutePath = path.join(getRootDirectory(), filePath);
|
|
152
|
+
try {
|
|
153
|
+
return new Promise((resolve, reject) => {
|
|
154
|
+
exec(`npx stylelint ${absolutePath} --config ${configFilePath}`, {
|
|
155
|
+
cwd: getNodeModulesPath()
|
|
156
|
+
}, (error, stderr, stdout) => {
|
|
157
|
+
if (stdout) {
|
|
158
|
+
resolve(stdout.trim().split('\n'));
|
|
159
|
+
}
|
|
160
|
+
// if(stderr){
|
|
161
|
+
// resolve(stderr.trim().split('\n'))
|
|
162
|
+
// }
|
|
163
|
+
else if (error) {
|
|
164
|
+
Logger.log(Logger.FAILURE_TYPE, error);
|
|
165
|
+
reject("Error executing stylelint command");
|
|
166
|
+
} else {
|
|
167
|
+
resolve([]);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
} catch (error) {
|
|
172
|
+
Logger.log(Logger.FAILURE_TYPE, `Issue is lint css files`);
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
124
177
|
/**
|
|
125
178
|
* @function {calculateGitDiffForFile} - method calculate diff of file
|
|
126
179
|
* @param {*} branch_name - branch name
|
|
@@ -157,10 +210,10 @@ function isOnlyWarningsPresentInFile(eslintErrorsPresent) {
|
|
|
157
210
|
let severityOfEachErrorInFile = [];
|
|
158
211
|
eslintErrorsPresent.map(error => {
|
|
159
212
|
let partsInString = error.split(" ");
|
|
160
|
-
let severityOfError = partsInString.find(word => word === 'error' || word === 'warning');
|
|
213
|
+
let severityOfError = partsInString.find(word => word === 'error' || word === 'warning' || word === '✖');
|
|
161
214
|
severityOfEachErrorInFile.push(severityOfError);
|
|
162
215
|
});
|
|
163
|
-
return !severityOfEachErrorInFile.includes('error');
|
|
216
|
+
return !(severityOfEachErrorInFile.includes('✖') || severityOfEachErrorInFile.includes('error'));
|
|
164
217
|
}
|
|
165
218
|
|
|
166
219
|
/**
|
|
@@ -193,29 +246,35 @@ async function preCommitHook() {
|
|
|
193
246
|
try {
|
|
194
247
|
staged_files = await getStagedFiles();
|
|
195
248
|
if (!staged_files.length == 0) {
|
|
196
|
-
|
|
249
|
+
const {
|
|
250
|
+
JsFiles: staged_filesJS,
|
|
251
|
+
CssFiles
|
|
252
|
+
} = filterFiles(staged_files, eslintConfigFiles, true);
|
|
197
253
|
|
|
198
|
-
//
|
|
199
|
-
// if(
|
|
254
|
+
// staged_filesJS = filterFiles(staged_filesJS,exemptionFiles) //this is the code for giving exemption to a file during pre commit
|
|
255
|
+
// if(staged_filesJS.length === 0){
|
|
200
256
|
// Logger.log(Logger.SUCCESS_TYPE,`Commit Successful`)
|
|
201
257
|
// process.exit(0)
|
|
202
258
|
// }
|
|
259
|
+
|
|
260
|
+
// CssFiles not Enabled For while
|
|
203
261
|
areFilesStaged = true;
|
|
204
|
-
|
|
205
|
-
|
|
262
|
+
var stagedFiles = [...staged_filesJS];
|
|
263
|
+
for (let file in stagedFiles) {
|
|
264
|
+
let currentFileName = stagedFiles[file];
|
|
206
265
|
let changedLinesArray = [];
|
|
207
266
|
let eslintErrorsInChangedLines = [];
|
|
208
267
|
let isOnlyEslintWarningsPresentInFile = false;
|
|
209
|
-
if (getSupportedLanguage().includes(path.extname(
|
|
268
|
+
if (getSupportedLanguage().includes(path.extname(stagedFiles[file]))) {
|
|
210
269
|
try {
|
|
211
|
-
var
|
|
212
|
-
// eslintErrorsInFile = impactBasedPrecommit == false ? filterWarningInFile(
|
|
213
|
-
if (
|
|
214
|
-
if (!
|
|
270
|
+
var errorsInFile = await lintFiles(stagedFiles[file]);
|
|
271
|
+
// eslintErrorsInFile = impactBasedPrecommit == false ? filterWarningInFile(errorsInFile) : errorsInFile
|
|
272
|
+
if (stagedFiles[file] && typeof stagedFiles[file] == 'string') {
|
|
273
|
+
if (!errorsInFile.length == 0) {
|
|
215
274
|
//Calculating changed lines in a file and storing them in respective arrays
|
|
216
275
|
if (impactBasedPrecommit) {
|
|
217
276
|
//git diff is computed and stored in an array
|
|
218
|
-
let git_diff = await calculateGitDiffForFile(current_branch,
|
|
277
|
+
let git_diff = await calculateGitDiffForFile(current_branch, stagedFiles[file]);
|
|
219
278
|
changedLinesArray = git_diff.filter(line => line.startsWith('@@'));
|
|
220
279
|
let changedLinesStartArray = [];
|
|
221
280
|
let changedLinesEndArray = [];
|
|
@@ -229,15 +288,15 @@ async function preCommitHook() {
|
|
|
229
288
|
changedLinesEndArray.push(changesStartLine + parseInt(changesEndLine) - 1);
|
|
230
289
|
}
|
|
231
290
|
}
|
|
232
|
-
for (let error = 1; error <
|
|
233
|
-
//
|
|
234
|
-
//
|
|
235
|
-
//
|
|
291
|
+
for (let error = 1; error < errorsInFile.length - 2; error++) {
|
|
292
|
+
//errorsInFile[error].trim() - 69:26 error => Do not hardcode content. Use I18N key instead no-hardcoding/no-hardcoding,
|
|
293
|
+
//errorsInFile[error].trim().split(' ')[0] => 69:26
|
|
294
|
+
//errorsInFile[error].trim().split(' ')[0].split(':')[0] => 69
|
|
236
295
|
|
|
237
|
-
let eslintErrorLineNumber =
|
|
296
|
+
let eslintErrorLineNumber = errorsInFile[error].trim().split(' ')[0].split(':')[0];
|
|
238
297
|
for (let lineNumber in changedLinesStartArray) {
|
|
239
298
|
if (eslintErrorLineNumber >= changedLinesStartArray[lineNumber] && eslintErrorLineNumber <= changedLinesEndArray[lineNumber]) {
|
|
240
|
-
eslintErrorsInChangedLines.push(
|
|
299
|
+
eslintErrorsInChangedLines.push(errorsInFile[error]);
|
|
241
300
|
}
|
|
242
301
|
}
|
|
243
302
|
}
|
|
@@ -258,10 +317,10 @@ async function preCommitHook() {
|
|
|
258
317
|
}
|
|
259
318
|
}
|
|
260
319
|
} else {
|
|
261
|
-
if (
|
|
320
|
+
if (errorsInFile.length > 0) {
|
|
262
321
|
let startIndex = 1;
|
|
263
|
-
let endIndex =
|
|
264
|
-
let listOsEslintErrors =
|
|
322
|
+
let endIndex = errorsInFile.length - 2;
|
|
323
|
+
let listOsEslintErrors = errorsInFile.slice(startIndex, endIndex);
|
|
265
324
|
isOnlyEslintWarningsPresentInFile = isOnlyWarningsPresentInFile(listOsEslintErrors);
|
|
266
325
|
Logger.log(Logger.FAILURE_TYPE, `\x1b[1m${currentFileName}\x1b[0m`);
|
|
267
326
|
for (let eslintError of listOsEslintErrors) {
|
|
@@ -282,7 +341,7 @@ async function preCommitHook() {
|
|
|
282
341
|
}
|
|
283
342
|
} catch (err) {
|
|
284
343
|
Logger.log(Logger.FAILURE_TYPE, err);
|
|
285
|
-
Logger.log(Logger.FAILURE_TYPE, "Error in executing
|
|
344
|
+
Logger.log(Logger.FAILURE_TYPE, "Error in executing lint command");
|
|
286
345
|
}
|
|
287
346
|
}
|
|
288
347
|
}
|
|
@@ -293,14 +352,14 @@ async function preCommitHook() {
|
|
|
293
352
|
Logger.log(Logger.INFO_TYPE, 'Error executing pre commit hook');
|
|
294
353
|
}
|
|
295
354
|
if (shouldAbortCommit) {
|
|
296
|
-
Logger.log(Logger.FAILURE_TYPE, `There are
|
|
355
|
+
Logger.log(Logger.FAILURE_TYPE, `There are linter errors/warnings present. So commit is aborted.`);
|
|
297
356
|
process.exit(1);
|
|
298
357
|
} else if (shouldAbortCommit === false && staged_files.length !== 0) {
|
|
299
358
|
Logger.log(Logger.SUCCESS_TYPE, `Commit Successful`);
|
|
300
359
|
process.exit(0);
|
|
301
360
|
}
|
|
302
361
|
} else {
|
|
303
|
-
Logger.log(Logger.FAILURE_TYPE, 'Commit failed since some
|
|
362
|
+
Logger.log(Logger.FAILURE_TYPE, 'Commit failed since some lint plugins are not installed');
|
|
304
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`);
|
|
305
364
|
Logger.log(Logger.INFO_TYPE, 'Execute the command and kindly try committing again.');
|
|
306
365
|
process.exit(1);
|