@codacy/tools-bandit-1 0.14.0 → 0.16.0
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/dist/index.js +82 -58
- package/dist/metadata.js +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -753,7 +753,7 @@ var descriptor = {
|
|
|
753
753
|
preferredVersion: "1.8.3",
|
|
754
754
|
languages: ["Python"],
|
|
755
755
|
filePatterns: ["**/*.py"],
|
|
756
|
-
supportedOS: ["linux", "darwin"],
|
|
756
|
+
supportedOS: ["linux", "darwin", "win32"],
|
|
757
757
|
supportedArch: ["x64", "arm64"],
|
|
758
758
|
supportedRunners: ["local", "container"]
|
|
759
759
|
};
|
|
@@ -786,9 +786,18 @@ function mapConfidence(confidence) {
|
|
|
786
786
|
}
|
|
787
787
|
}
|
|
788
788
|
var CONFIG_FILE_CANDIDATES = [".bandit", "bandit.yml", "pyproject.toml"];
|
|
789
|
+
var PYPROJECT_BANDIT_SECTION = /^\[tool\.bandit(\.[\w-]+)*\]/m;
|
|
790
|
+
async function pyprojectHasBanditSection(pyprojectPath) {
|
|
791
|
+
try {
|
|
792
|
+
const content = await import_promises.default.readFile(pyprojectPath, "utf-8");
|
|
793
|
+
return PYPROJECT_BANDIT_SECTION.test(content);
|
|
794
|
+
} catch {
|
|
795
|
+
return false;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
789
798
|
async function resolveBinaryPath(ctx) {
|
|
790
799
|
const venvDir = (0, import_tooling.getVenvDir)(ctx.globalDir, ADAPTER_ID);
|
|
791
|
-
const venvBin =
|
|
800
|
+
const venvBin = (0, import_tooling.resolveVenvBinary)((0, import_tooling.getVenvPaths)(venvDir), "bandit");
|
|
792
801
|
try {
|
|
793
802
|
await import_promises.default.access(venvBin);
|
|
794
803
|
return venvBin;
|
|
@@ -844,14 +853,8 @@ var adapter = {
|
|
|
844
853
|
];
|
|
845
854
|
const venvDir = (0, import_tooling.getVenvDir)(ctx.globalDir, ADAPTER_ID);
|
|
846
855
|
try {
|
|
847
|
-
const
|
|
848
|
-
await import_promises.default.access(
|
|
849
|
-
const venv = {
|
|
850
|
-
root: venvDir,
|
|
851
|
-
binDir: import_path.default.join(venvDir, "bin"),
|
|
852
|
-
python: venvPython,
|
|
853
|
-
pip: import_path.default.join(venvDir, "bin", "pip")
|
|
854
|
-
};
|
|
856
|
+
const venv = (0, import_tooling.getVenvPaths)(venvDir);
|
|
857
|
+
await import_promises.default.access(venv.python);
|
|
855
858
|
const version = await (0, import_tooling.checkVenvTool)(
|
|
856
859
|
venv,
|
|
857
860
|
"bandit",
|
|
@@ -948,7 +951,9 @@ var adapter = {
|
|
|
948
951
|
* Checks for bandit configuration files in the repository root.
|
|
949
952
|
*
|
|
950
953
|
* Looks for `.bandit`, `bandit.yml`, or `pyproject.toml` (in that order).
|
|
951
|
-
*
|
|
954
|
+
* `pyproject.toml` only counts if it actually has a `[tool.bandit]` table —
|
|
955
|
+
* unlike the other two candidates, its mere existence says nothing about
|
|
956
|
+
* whether Bandit is configured (see {@link pyprojectHasBanditSection}).
|
|
952
957
|
*/
|
|
953
958
|
async checkLocalConfigurationFile(ctx) {
|
|
954
959
|
ctx.logger.debug("Checking for local config", { toolId: TOOL_ID });
|
|
@@ -956,6 +961,9 @@ var adapter = {
|
|
|
956
961
|
const candidatePath = import_path.default.join(ctx.repositoryRoot, candidate);
|
|
957
962
|
try {
|
|
958
963
|
await import_promises.default.access(candidatePath);
|
|
964
|
+
if (candidate === "pyproject.toml" && !await pyprojectHasBanditSection(candidatePath)) {
|
|
965
|
+
continue;
|
|
966
|
+
}
|
|
959
967
|
ctx.logger.debug("Found local config", { toolId: TOOL_ID, path: candidatePath });
|
|
960
968
|
return { found: true, path: candidatePath };
|
|
961
969
|
} catch {
|
|
@@ -1002,54 +1010,80 @@ var adapter = {
|
|
|
1002
1010
|
args.push("-c", configPath);
|
|
1003
1011
|
}
|
|
1004
1012
|
}
|
|
1005
|
-
|
|
1013
|
+
const fileChunks = (0, import_tooling.chunkFilesForArgv)(absoluteFiles);
|
|
1006
1014
|
try {
|
|
1007
|
-
const
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
errors.push({
|
|
1013
|
-
toolId: TOOL_ID,
|
|
1014
|
-
phase: "toolInvoke",
|
|
1015
|
-
kind: "NonZeroExit",
|
|
1016
|
-
message: `bandit exited with code ${exitCode}${stderr ? `: ${stderr.trim()}` : ""}`,
|
|
1017
|
-
level: "error"
|
|
1018
|
-
});
|
|
1019
|
-
return (0, import_tooling.buildResult)(TOOL_ID, startedAt, /* @__PURE__ */ new Date(), issues, errors, ctx.targetFiles.length);
|
|
1020
|
-
}
|
|
1021
|
-
if (!stdout.trim()) {
|
|
1022
|
-
return (0, import_tooling.buildResult)(TOOL_ID, startedAt, /* @__PURE__ */ new Date(), issues, errors, ctx.targetFiles.length);
|
|
1023
|
-
}
|
|
1024
|
-
const jsonStart = stdout.indexOf("{");
|
|
1025
|
-
const jsonPayload = jsonStart === -1 ? stdout : stdout.slice(jsonStart);
|
|
1026
|
-
let banditOutput;
|
|
1027
|
-
try {
|
|
1028
|
-
banditOutput = JSON.parse(jsonPayload);
|
|
1029
|
-
} catch (err) {
|
|
1030
|
-
errors.push({
|
|
1031
|
-
toolId: TOOL_ID,
|
|
1032
|
-
phase: "outputParse",
|
|
1033
|
-
kind: "MalformedOutput",
|
|
1034
|
-
message: `Failed to parse bandit JSON output: ${err instanceof Error ? err.message : String(err)}`,
|
|
1035
|
-
level: "error"
|
|
1015
|
+
const results = [];
|
|
1016
|
+
for (const chunk of fileChunks) {
|
|
1017
|
+
const { stdout, stderr, exitCode } = await (0, import_tooling.spawnTool)(binary, [...args, ...chunk], {
|
|
1018
|
+
cwd: ctx.repositoryRoot,
|
|
1019
|
+
logger: ctx.logger
|
|
1036
1020
|
});
|
|
1037
|
-
|
|
1038
|
-
}
|
|
1039
|
-
if (banditOutput.errors && banditOutput.errors.length > 0) {
|
|
1040
|
-
for (const banditError of banditOutput.errors) {
|
|
1021
|
+
if (exitCode > 1) {
|
|
1041
1022
|
errors.push({
|
|
1042
1023
|
toolId: TOOL_ID,
|
|
1043
1024
|
phase: "toolInvoke",
|
|
1044
|
-
kind: "
|
|
1045
|
-
message:
|
|
1025
|
+
kind: "NonZeroExit",
|
|
1026
|
+
message: `bandit exited with code ${exitCode}${stderr ? `: ${stderr.trim()}` : ""}`,
|
|
1027
|
+
level: "error"
|
|
1028
|
+
});
|
|
1029
|
+
return (0, import_tooling.buildResult)(
|
|
1030
|
+
TOOL_ID,
|
|
1031
|
+
startedAt,
|
|
1032
|
+
/* @__PURE__ */ new Date(),
|
|
1033
|
+
issues,
|
|
1034
|
+
errors,
|
|
1035
|
+
ctx.targetFiles.length
|
|
1036
|
+
);
|
|
1037
|
+
}
|
|
1038
|
+
const stderrFiltered = stderr.split("\n").filter((line) => !/^\[.*\]\s+INFO\s+/.test(line.trim())).join("\n").trim();
|
|
1039
|
+
if (stderrFiltered) {
|
|
1040
|
+
errors.push({
|
|
1041
|
+
toolId: TOOL_ID,
|
|
1042
|
+
phase: "outputParse",
|
|
1043
|
+
kind: "ParseWarning",
|
|
1044
|
+
message: `bandit stderr: ${stderrFiltered}`,
|
|
1046
1045
|
level: "warning"
|
|
1047
1046
|
});
|
|
1048
1047
|
}
|
|
1048
|
+
if (!stdout.trim()) continue;
|
|
1049
|
+
const jsonStart = stdout.indexOf("{");
|
|
1050
|
+
const jsonPayload = jsonStart === -1 ? stdout : stdout.slice(jsonStart);
|
|
1051
|
+
let banditOutput;
|
|
1052
|
+
try {
|
|
1053
|
+
banditOutput = JSON.parse(jsonPayload);
|
|
1054
|
+
} catch (err) {
|
|
1055
|
+
errors.push({
|
|
1056
|
+
toolId: TOOL_ID,
|
|
1057
|
+
phase: "outputParse",
|
|
1058
|
+
kind: "MalformedOutput",
|
|
1059
|
+
message: `Failed to parse bandit JSON output: ${err instanceof Error ? err.message : String(err)}`,
|
|
1060
|
+
level: "error"
|
|
1061
|
+
});
|
|
1062
|
+
return (0, import_tooling.buildResult)(
|
|
1063
|
+
TOOL_ID,
|
|
1064
|
+
startedAt,
|
|
1065
|
+
/* @__PURE__ */ new Date(),
|
|
1066
|
+
issues,
|
|
1067
|
+
errors,
|
|
1068
|
+
ctx.targetFiles.length
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
if (banditOutput.errors && banditOutput.errors.length > 0) {
|
|
1072
|
+
for (const banditError of banditOutput.errors) {
|
|
1073
|
+
errors.push({
|
|
1074
|
+
toolId: TOOL_ID,
|
|
1075
|
+
phase: "toolInvoke",
|
|
1076
|
+
kind: "FileError",
|
|
1077
|
+
message: `${banditError.filename}: ${banditError.reason}`,
|
|
1078
|
+
level: "warning"
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
results.push(...banditOutput.results);
|
|
1049
1083
|
}
|
|
1050
1084
|
const enabledPatterns = new Set(codacyConfig.patterns.map((p) => p.patternId));
|
|
1051
1085
|
const resultsByFile = /* @__PURE__ */ new Map();
|
|
1052
|
-
for (const result2 of
|
|
1086
|
+
for (const result2 of results) {
|
|
1053
1087
|
const list = resultsByFile.get(result2.filename) ?? [];
|
|
1054
1088
|
list.push(result2);
|
|
1055
1089
|
resultsByFile.set(result2.filename, list);
|
|
@@ -1085,16 +1119,6 @@ var adapter = {
|
|
|
1085
1119
|
issues.push(issue);
|
|
1086
1120
|
}
|
|
1087
1121
|
}
|
|
1088
|
-
const stderrFiltered = stderr.split("\n").filter((line) => !/^\[.*\]\s+INFO\s+/.test(line.trim())).join("\n").trim();
|
|
1089
|
-
if (stderrFiltered) {
|
|
1090
|
-
errors.push({
|
|
1091
|
-
toolId: TOOL_ID,
|
|
1092
|
-
phase: "outputParse",
|
|
1093
|
-
kind: "ParseWarning",
|
|
1094
|
-
message: `bandit stderr: ${stderrFiltered}`,
|
|
1095
|
-
level: "warning"
|
|
1096
|
-
});
|
|
1097
|
-
}
|
|
1098
1122
|
} catch (err) {
|
|
1099
1123
|
errors.push({
|
|
1100
1124
|
toolId: TOOL_ID,
|
package/dist/metadata.js
CHANGED
|
@@ -29,7 +29,7 @@ var descriptor = {
|
|
|
29
29
|
preferredVersion: "1.8.3",
|
|
30
30
|
languages: ["Python"],
|
|
31
31
|
filePatterns: ["**/*.py"],
|
|
32
|
-
supportedOS: ["linux", "darwin"],
|
|
32
|
+
supportedOS: ["linux", "darwin", "win32"],
|
|
33
33
|
supportedArch: ["x64", "arm64"],
|
|
34
34
|
supportedRunners: ["local", "container"]
|
|
35
35
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codacy/tools-bandit-1",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Bandit adapter — CLI-mode Python security linter",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"dist"
|
|
9
9
|
],
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@codacy/tooling": "0.
|
|
11
|
+
"@codacy/tooling": "0.16.0"
|
|
12
12
|
},
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"author": "Codacy <support@codacy.com> (https://www.codacy.com)",
|