@zohodesk/codestandard-validator 1.4.0 → 1.4.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/build/hooks/Precommit/lint.js +4 -3
- package/build/hooks/Precommit/pre-commit-default.js +4 -3
- package/build/hooks/hook.js +9 -4
- package/build/utils/ConfigFileUtils/getEslintExecutablePath.js +9 -3
- package/build/utils/General/getGeneralInfo.js +8 -2
- package/build/utils/General/writeProjectDetailsToJson.js +13 -2
- package/build/utils/PluginsInstallation/checkIfPluginsAreInstalled.js +27 -13
- package/build/utils/PluginsInstallation/installPlugins.js +1 -1
- package/changeLog.md +11 -0
- package/package.json +1 -1
|
@@ -45,9 +45,10 @@ async function lintFiles(filePath) {
|
|
|
45
45
|
return [];
|
|
46
46
|
}
|
|
47
47
|
async function findEslintErrors(file) {
|
|
48
|
-
const nodeModulesPath = getNodeModulesPath();
|
|
48
|
+
const nodeModulesPath = path.resolve(getNodeModulesPath());
|
|
49
49
|
const eslintPath = getEslintExecutablePath();
|
|
50
|
-
const eslintConfig =
|
|
50
|
+
const eslintConfig = path.join(nodeModulesPath, '.eslintrc.js');
|
|
51
|
+
const resolvePluginsPath = path.join(nodeModulesPath, 'node_modules');
|
|
51
52
|
if (!fs.existsSync(nodeModulesPath)) {
|
|
52
53
|
Logger.log(Logger.INFO_TYPE, 'node_modules not found');
|
|
53
54
|
return [];
|
|
@@ -56,7 +57,7 @@ async function findEslintErrors(file) {
|
|
|
56
57
|
Logger.log(Logger.INFO_TYPE, 'Eslint executable not found. Make sure eslint plugin is installed');
|
|
57
58
|
return [];
|
|
58
59
|
}
|
|
59
|
-
return execSync(`npx --ignore-existing "${eslintPath}" --config "${eslintConfig}" --no-inline-config --resolve-plugins-relative-to="${
|
|
60
|
+
return execSync(`npx --ignore-existing "${eslintPath}" --config "${eslintConfig}" --no-inline-config --resolve-plugins-relative-to="${resolvePluginsPath}" ${path.resolve(getRootDirectory(), file)}`).then(({
|
|
60
61
|
stderr
|
|
61
62
|
}) => stderr ? stderr.toString().trim().split('\n') : []).catch(err => {
|
|
62
63
|
Logger.log(Logger.FAILURE_TYPE, err);
|
|
@@ -113,15 +113,16 @@ async function lintFiles(filePath) {
|
|
|
113
113
|
*/
|
|
114
114
|
|
|
115
115
|
function findEslintErrors(file) {
|
|
116
|
-
let nodeModulesPathOfProject =
|
|
116
|
+
let nodeModulesPathOfProject = path.resolve(getNodeModulesPath());
|
|
117
117
|
let eslintExecutablePath = getEslintExecutablePath();
|
|
118
|
-
let eslintConfigurationFilePath =
|
|
118
|
+
let eslintConfigurationFilePath = path.join(nodeModulesPathOfProject, '.eslintrc.js');
|
|
119
|
+
let resolvePluginsPath = path.join(nodeModulesPathOfProject, 'node_modules');
|
|
119
120
|
let isEslintExecutablePresent = fs.existsSync(eslintExecutablePath) ? true : false;
|
|
120
121
|
let isNodeModulesPresent = fs.existsSync(nodeModulesPathOfProject);
|
|
121
122
|
if (isNodeModulesPresent) {
|
|
122
123
|
if (isEslintExecutablePresent) {
|
|
123
124
|
return new Promise((resolve, reject) => {
|
|
124
|
-
exec(`npx --ignore-existing "${eslintExecutablePath}" --config "${eslintConfigurationFilePath}" --no-inline-config --resolve-plugins-relative-to="${
|
|
125
|
+
exec(`npx --ignore-existing "${eslintExecutablePath}" --config "${eslintConfigurationFilePath}" --no-inline-config --resolve-plugins-relative-to="${resolvePluginsPath}" ${path.resolve(getRootDirectory(), file)}`, (error, stderr, stdout) => {
|
|
125
126
|
if (stderr) {
|
|
126
127
|
resolve(stderr.trim().split('\n'));
|
|
127
128
|
} else if (error) {
|
package/build/hooks/hook.js
CHANGED
|
@@ -54,8 +54,13 @@ async function hooks() {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
(async function () {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
try {
|
|
58
|
+
await initConfig(getConfigPathExecute());
|
|
59
|
+
await Promise.resolve(postInstallExecution());
|
|
60
|
+
require("../chunk/chunk_Restriction");
|
|
61
|
+
await hooks();
|
|
62
|
+
} catch (error) {
|
|
63
|
+
Logger.log(Logger.FAILURE_TYPE, `Pre-commit initialization failed: ${error.message}`);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
61
66
|
})();
|
|
@@ -13,12 +13,18 @@ const {
|
|
|
13
13
|
const {
|
|
14
14
|
getLibraryInstalledLocation
|
|
15
15
|
} = require('../General/getLibraryInstalledLocation');
|
|
16
|
+
function getProjectNodeModulesPath(projectPath) {
|
|
17
|
+
const normalizedPath = path.resolve(projectPath);
|
|
18
|
+
return path.basename(normalizedPath) === 'node_modules' ? normalizedPath : path.join(normalizedPath, 'node_modules');
|
|
19
|
+
}
|
|
16
20
|
function getEslintExecutablePath() {
|
|
17
21
|
let eslintLibraryName = 'eslint';
|
|
18
|
-
let
|
|
22
|
+
let nodeModulesPath = getProjectNodeModulesPath(getNodeModulesPath());
|
|
23
|
+
let librariesInNodeModulesOfProject = executeSynchronizedCommands(readdirSync, [nodeModulesPath], '', 'Unable to get the plugins inside node_modules', true, false);
|
|
19
24
|
let isEslintInstalledinProject = librariesInNodeModulesOfProject.some(library => library === eslintLibraryName);
|
|
20
|
-
return isEslintInstalledinProject ? path.join(
|
|
25
|
+
return isEslintInstalledinProject ? path.join(nodeModulesPath, eslintLibraryName, 'bin', 'eslint.js') : path.join(getLibraryInstalledLocation(), 'node_modules', eslintLibraryName, 'bin', 'eslint.js');
|
|
21
26
|
}
|
|
22
27
|
module.exports = {
|
|
23
|
-
getEslintExecutablePath
|
|
28
|
+
getEslintExecutablePath,
|
|
29
|
+
getProjectNodeModulesPath
|
|
24
30
|
};
|
|
@@ -103,7 +103,11 @@ function getRunningEnv() {
|
|
|
103
103
|
function getLastCommitHash() {
|
|
104
104
|
try {
|
|
105
105
|
const cmd = `curl --header "PRIVATE-TOKEN: ${process.env.TOOL_TOKEN}" --url ${commitHashEndPoint}`;
|
|
106
|
-
|
|
106
|
+
const response = execSync(cmd, {
|
|
107
|
+
encoding: 'utf-8',
|
|
108
|
+
timeout: 10000
|
|
109
|
+
});
|
|
110
|
+
return JSON.parse(response)[0]?.id;
|
|
107
111
|
} catch (err) {
|
|
108
112
|
Logger.log(Logger.FAILURE_TYPE, err);
|
|
109
113
|
return null;
|
|
@@ -129,7 +133,9 @@ function updateJsonFile(filePath, modifier) {
|
|
|
129
133
|
const rawData = fs.readFileSync(absolutePath, "utf-8");
|
|
130
134
|
const jsonData = JSON.parse(rawData);
|
|
131
135
|
const updatedData = modifier(jsonData);
|
|
132
|
-
|
|
136
|
+
const tempPath = `${absolutePath}.${process.pid}.${Date.now()}.tmp`;
|
|
137
|
+
fs.writeFileSync(tempPath, JSON.stringify(updatedData, null, 2), "utf-8");
|
|
138
|
+
fs.renameSync(tempPath, absolutePath);
|
|
133
139
|
} catch (error) {
|
|
134
140
|
Logger.log(Logger.FAILURE_TYPE, "Error updating JSON file");
|
|
135
141
|
}
|
|
@@ -10,13 +10,24 @@ const {
|
|
|
10
10
|
const {
|
|
11
11
|
getLastCommitHash
|
|
12
12
|
} = require('./getGeneralInfo');
|
|
13
|
+
function getProjectRootFromInstallPath(currentPath) {
|
|
14
|
+
const isWindowsAbsolutePath = /^[A-Za-z]:[\\/]/.test(String(currentPath));
|
|
15
|
+
const normalizedPath = (isWindowsAbsolutePath ? String(currentPath) : path.resolve(currentPath)).replace(/\\/g, '/');
|
|
16
|
+
const packageSuffix = '/node_modules/@zohodesk/codestandard-validator';
|
|
17
|
+
const suffixIndex = normalizedPath.lastIndexOf(packageSuffix);
|
|
18
|
+
if (suffixIndex !== -1) {
|
|
19
|
+
return path.normalize(normalizedPath.slice(0, suffixIndex));
|
|
20
|
+
}
|
|
21
|
+
return path.resolve(currentPath, '..', '..', '..');
|
|
22
|
+
}
|
|
13
23
|
function writeFsPaths() {
|
|
14
24
|
var fileContent = {
|
|
15
|
-
nodeModulesPath:
|
|
25
|
+
nodeModulesPath: getProjectRootFromInstallPath(process.cwd()),
|
|
16
26
|
commitHash: getLastCommitHash()
|
|
17
27
|
};
|
|
18
28
|
return executeSynchronizedCommands(writeFileSync, [path.join(process.cwd(), 'jsonUtils', 'fsUtils.json'), JSON.stringify(fileContent), 'utf-8'], 'node_modules path updated in json file', 'Unable to write node_modules path to json file', false, true);
|
|
19
29
|
}
|
|
20
30
|
module.exports = {
|
|
21
|
-
writeFsPaths
|
|
31
|
+
writeFsPaths,
|
|
32
|
+
getProjectRootFromInstallPath
|
|
22
33
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
|
-
existsSync
|
|
4
|
+
existsSync,
|
|
5
|
+
readFileSync
|
|
5
6
|
} = require('fs');
|
|
6
7
|
const path = require('path');
|
|
7
8
|
const {
|
|
@@ -59,7 +60,8 @@ function checkIfPluginsAreInstalled() {
|
|
|
59
60
|
isPluginPresent,
|
|
60
61
|
pluginPath
|
|
61
62
|
} = checkPluginsPresentInNodemodules(packageName); // circular installation loop so comment out
|
|
62
|
-
|
|
63
|
+
// checkPluginHasProperVersion(packageName,pluginPath,version) remove version check due to unnecess
|
|
64
|
+
if (isPluginPresent) {
|
|
63
65
|
return false;
|
|
64
66
|
}
|
|
65
67
|
return `${packageName}@${version}`;
|
|
@@ -110,7 +112,7 @@ function getPluginsToInstall() {
|
|
|
110
112
|
* @returns {string} - which represents exactPluginVersion
|
|
111
113
|
*/
|
|
112
114
|
function returnExactPluginVersion(pluginVersion) {
|
|
113
|
-
return pluginVersion.replace(/[\^~]/, '');
|
|
115
|
+
return String(pluginVersion || '').replace(/[\^~]/, '');
|
|
114
116
|
}
|
|
115
117
|
|
|
116
118
|
/**
|
|
@@ -120,16 +122,24 @@ function returnExactPluginVersion(pluginVersion) {
|
|
|
120
122
|
*/
|
|
121
123
|
function checkPluginsPresentInNodemodules(rulePluginName) {
|
|
122
124
|
try {
|
|
123
|
-
const pluginPath = require.resolve(rulePluginName.toString());
|
|
125
|
+
const pluginPath = require.resolve(path.join(rulePluginName.toString(), 'package.json'));
|
|
124
126
|
return {
|
|
125
127
|
pluginPath: pluginPath,
|
|
126
128
|
isPluginPresent: existsSync(pluginPath)
|
|
127
129
|
};
|
|
128
130
|
} catch (error) {
|
|
129
|
-
|
|
130
|
-
pluginPath
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
try {
|
|
132
|
+
const pluginPath = require.resolve(rulePluginName.toString());
|
|
133
|
+
return {
|
|
134
|
+
pluginPath: path.join(path.dirname(pluginPath), 'package.json'),
|
|
135
|
+
isPluginPresent: existsSync(pluginPath)
|
|
136
|
+
};
|
|
137
|
+
} catch (_innerError) {
|
|
138
|
+
return {
|
|
139
|
+
pluginPath: "",
|
|
140
|
+
isPluginPresent: false
|
|
141
|
+
};
|
|
142
|
+
}
|
|
133
143
|
}
|
|
134
144
|
}
|
|
135
145
|
|
|
@@ -142,11 +152,15 @@ function checkPluginsPresentInNodemodules(rulePluginName) {
|
|
|
142
152
|
*/
|
|
143
153
|
|
|
144
154
|
function checkPluginHasProperVersion(rulePluginName, installationPath, remotePluginVersion) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
155
|
+
try {
|
|
156
|
+
const rulePluginPackageJSONPath = installationPath || require.resolve(path.join(rulePluginName.toString(), 'package.json'));
|
|
157
|
+
const remotePluginExactVersion = returnExactPluginVersion(remotePluginVersion);
|
|
158
|
+
const packageJsonPluginExactVersion = returnExactPluginVersion(JSON.parse(readFileSync(rulePluginPackageJSONPath, 'utf-8')).version);
|
|
159
|
+
return remotePluginExactVersion === packageJsonPluginExactVersion;
|
|
160
|
+
} catch (error) {
|
|
161
|
+
Logger.log(Logger.FAILURE_TYPE, `Unable to check plugin version for ${rulePluginName}`);
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
150
164
|
}
|
|
151
165
|
module.exports = {
|
|
152
166
|
getPluginsToInstall,
|
|
@@ -29,7 +29,7 @@ async function installPlugins(pluginsToBeInstalled) {
|
|
|
29
29
|
Logger.log(Logger.INFO_TYPE, `Install command being executed: npm ${args.join(' ')}`);
|
|
30
30
|
const result = spawnSync('npm', args, {
|
|
31
31
|
cwd: getNodeModulesPath(),
|
|
32
|
-
shell:
|
|
32
|
+
shell: true,
|
|
33
33
|
encoding: 'utf8'
|
|
34
34
|
});
|
|
35
35
|
if (result.stdout) {
|
package/changeLog.md
CHANGED
|
@@ -72,3 +72,14 @@
|
|
|
72
72
|
4. Add `.feature` file support in `getSupportedLanguage()` and include feature files in pre-commit hook linting
|
|
73
73
|
5. Update `@zohodesk/codestandard-analytics` dependency to `1.1.6-node-18`
|
|
74
74
|
6. Update unit tests for mutation modules to match refactored API
|
|
75
|
+
|
|
76
|
+
# 1.4.1 - Windows Path and Pre-commit Stability Fixes
|
|
77
|
+
|
|
78
|
+
1. Fix plugin discovery path handling for scoped packages by resolving `package.json` directly, preventing malformed module paths on Windows.
|
|
79
|
+
2. Improve plugin version parsing and error handling to avoid hard failures during plugin validation when metadata is unavailable.
|
|
80
|
+
3. Harden pre-commit initialization flow by adding deterministic async ordering and centralized startup error handling.
|
|
81
|
+
4. Add timeout protection for remote commit-hash fetch to prevent long blocking in hook execution.
|
|
82
|
+
5. Improve fsUtils update safety using temporary file write + rename to reduce partial-write risk.
|
|
83
|
+
6. Derive project root from install path suffix instead of fixed directory traversal for cross-platform compatibility.
|
|
84
|
+
7. Normalize ESLint config and plugin resolution paths in pre-commit lint flows for Windows/macOS/Linux parity.
|
|
85
|
+
8. Add and update unit tests for plugin checks, install-path derivation, JSON update flow, and ESLint path resolution.
|