Skip to content

Commit

Permalink
Add Ruff Python SCA
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/main/java/de/tum/cit/aet/artemis/programming/domain/StaticCodeAnalysisTool.java
#	src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseFactory.java
  • Loading branch information
magaupp committed Oct 27, 2024
1 parent 8521f2b commit 26d20ca
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,73 @@
*/
public class StaticCodeAnalysisConfigurer {

// @formatter:off
private static final List<String> CATEGORY_NAMES_PYTHON = List.of(
"Pyflakes",
"pycodestyle",
"mccabe",
"isort",
"pep8-naming",
"pydocstyle",
"pyupgrade",
"flake8-2020",
"flake8-annotations",
"flake8-async",
"flake8-bandit",
"flake8-blind-except",
"flake8-boolean-trap",
"flake8-bugbear",
"flake8-builtins",
"flake8-commas",
"flake8-copyright",
"flake8-comprehensions",
"flake8-datetimez",
"flake8-debugger",
"flake8-django",
"flake8-errmsg",
"flake8-executable",
"flake8-future-annotations",
"flake8-implicit-str-concat",
"flake8-import-conventions",
"flake8-logging",
"flake8-logging-format",
"flake8-no-pep420",
"flake8-pie",
"flake8-print",
"flake8-pyi",
"flake8-pytest-style",
"flake8-quotes",
"flake8-raise",
"flake8-return",
"flake8-self",
"flake8-slots",
"flake8-simplify",
"flake8-tidy-imports",
"flake8-type-checking",
"flake8-gettext",
"flake8-unused-arguments",
"flake8-use-pathlib",
"flake8-todos",
"flake8-fixme",
"eradicate",
"pandas-vet",
"pygrep-hooks",
"Pylint",
"tryceratops",
"flynt",
"NumPy-specific rules",
"FastAPI",
"Airflow",
"Perflint",
"refurb",
"pydoclint",
"Ruff-specific rules"
);
// @formatter:on

private static final Map<ProgrammingLanguage, List<StaticCodeAnalysisDefaultCategory>> languageToDefaultCategories = Map.of(ProgrammingLanguage.JAVA,
createDefaultCategoriesForJava(), ProgrammingLanguage.SWIFT, createDefaultCategoriesForSwift(), ProgrammingLanguage.C, createDefaultCategoriesForC());
createDefaultCategoriesForJava(), ProgrammingLanguage.SWIFT, createDefaultCategoriesForSwift(), ProgrammingLanguage.C, createDefaultCategoriesForC(),
ProgrammingLanguage.PYTHON, createDefaultCategoriesForPython());

/**
* Create an unmodifiable List of default static code analysis categories for Java
Expand Down Expand Up @@ -85,6 +150,11 @@ private static List<StaticCodeAnalysisDefaultCategory> createDefaultCategoriesFo
new StaticCodeAnalysisDefaultCategory("Miscellaneous", 0.2D, 2D, CategoryState.INACTIVE, List.of(createMapping(StaticCodeAnalysisTool.GCC, "Misc"))));
}

private static List<StaticCodeAnalysisDefaultCategory> createDefaultCategoriesForPython() {
return CATEGORY_NAMES_PYTHON.stream()
.map(name -> new StaticCodeAnalysisDefaultCategory(name, 0.0, 1.0, CategoryState.FEEDBACK, List.of(createMapping(StaticCodeAnalysisTool.RUFF, name)))).toList();
}

public static Map<ProgrammingLanguage, List<StaticCodeAnalysisDefaultCategory>> staticCodeAnalysisConfiguration() {
return languageToDefaultCategories;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public enum StaticCodeAnalysisTool {
PMD_CPD("cpd.xml"),
SWIFTLINT("swiftlint-result.xml"),
GCC("gcc.xml"),
RUFF("ruff.sarif"),
OTHER(null),
;
// @formatter:on
Expand All @@ -26,7 +27,8 @@ public enum StaticCodeAnalysisTool {
private static final Map<ProgrammingLanguage, List<StaticCodeAnalysisTool>> TOOLS_OF_PROGRAMMING_LANGUAGE = new EnumMap<>(Map.of(
ProgrammingLanguage.JAVA, List.of(SPOTBUGS, CHECKSTYLE, PMD, PMD_CPD),
ProgrammingLanguage.SWIFT, List.of(SWIFTLINT),
ProgrammingLanguage.C, List.of(GCC)
ProgrammingLanguage.C, List.of(GCC),
ProgrammingLanguage.PYTHON, List.of(RUFF)
));
// @formatter:on

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public LocalCIProgrammingLanguageFeatureService() {
programmingLanguageFeatures.put(JAVASCRIPT, new ProgrammingLanguageFeature(JAVASCRIPT, false, false, true, false, false, List.of(), false, true));
programmingLanguageFeatures.put(KOTLIN, new ProgrammingLanguageFeature(KOTLIN, false, false, true, true, false, List.of(), false, true));
programmingLanguageFeatures.put(OCAML, new ProgrammingLanguageFeature(OCAML, false, false, false, false, true, List.of(), false, true));
programmingLanguageFeatures.put(PYTHON, new ProgrammingLanguageFeature(PYTHON, false, false, true, false, false, List.of(), false, true));
programmingLanguageFeatures.put(PYTHON, new ProgrammingLanguageFeature(PYTHON, false, true, true, false, false, List.of(), false, true));
programmingLanguageFeatures.put(R, new ProgrammingLanguageFeature(R, false, false, true, false, false, List.of(), false, true));
programmingLanguageFeatures.put(RUST, new ProgrammingLanguageFeature(RUST, false, false, true, false, false, List.of(), false, true));
programmingLanguageFeatures.put(SWIFT, new ProgrammingLanguageFeature(SWIFT, false, false, true, true, false, List.of(PLAIN), false, true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import de.tum.cit.aet.artemis.programming.domain.StaticCodeAnalysisTool;
import de.tum.cit.aet.artemis.programming.service.localci.scaparser.exception.UnsupportedToolException;
import de.tum.cit.aet.artemis.programming.service.localci.scaparser.strategy.sarif.RuffCategorizer;
import de.tum.cit.aet.artemis.programming.service.localci.scaparser.strategy.sarif.SarifParser;

/**
* Policy class for the parser strategies.
Expand All @@ -27,7 +29,7 @@ public ParserStrategy configure(String fileName) {
case CHECKSTYLE -> new CheckstyleParser();
case PMD -> new PMDParser();
case PMD_CPD -> new PMDCPDParser();
// so far, we do not support swiftlint and gcc only SCA for Java
case RUFF -> new SarifParser(StaticCodeAnalysisTool.RUFF, new RuffCategorizer());
default -> throw new UnsupportedToolException("Tool " + tool + " is not supported");
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package de.tum.cit.aet.artemis.programming.service.localci.scaparser.strategy.sarif;

public class RuffCategorizer implements RuleCategorizer {

@Override
public String categorizeRule(ReportingDescriptor rule) {
return rule.getProperties().getAdditionalProperties().getOrDefault("kind", "Unknown").toString();
}
}
2 changes: 1 addition & 1 deletion src/main/resources/config/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ artemis:
empty:
default: "ubuntu:24.04"
python:
default: "ls1tum/artemis-python-docker:latest"
default: "ls1tum/artemis-python-docker:pr-3"
c:
# possible overrides: gcc, fact
default: "ls1tum/artemis-c-docker:latest"
Expand Down
30 changes: 30 additions & 0 deletions src/main/resources/templates/aeolus/python/default_static.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -e
export AEOLUS_INITIAL_DIRECTORY=${PWD}
static_code_analysis () {
echo '⚙️ executing static_code_analysis'
ruff check --output-format=sarif --output-file=ruff.sarif --exit-zero --select=ALL "${studentParentWorkingDirectoryName}"
}

build_and_test_the_code () {
echo '⚙️ executing build_and_test_the_code'
python3 -m compileall . -q || error=true
if [ ! $error ]
then
pytest --junitxml=test-reports/results.xml
fi
}

main () {
if [[ "${1}" == "aeolus_sourcing" ]]; then
return 0 # just source to use the methods in the subshell, no execution
fi
local _script_name
_script_name=${BASH_SOURCE[0]:-$0}
cd "${AEOLUS_INITIAL_DIRECTORY}"
bash -c "source ${_script_name} aeolus_sourcing; static_code_analysis"
cd "${AEOLUS_INITIAL_DIRECTORY}"
bash -c "source ${_script_name} aeolus_sourcing; build_and_test_the_code"
}

main "${@}"
21 changes: 21 additions & 0 deletions src/main/resources/templates/aeolus/python/default_static.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
api: v0.0.1
actions:
- name: static_code_analysis
script: ruff check --output-format=sarif --output-file=ruff.sarif --exit-zero --select=ALL "${studentParentWorkingDirectoryName}"
results:
- name: ruff
path: ruff.sarif
type: sca
- name: build_and_test_the_code
script: |-
python3 -m compileall . -q || error=true
if [ ! $error ]
then
pytest --junitxml=test-reports/results.xml
fi
runAlways: false
results:
- name: junit_test-reports/*results.xml
path: test-reports/*results.xml
type: junit
before: true
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ private static StaticCodeAnalysisIssue generateStaticCodeAnalysisIssue(StaticCod
case PMD_CPD -> "Copy/Paste Detection";
case SWIFTLINT -> "swiftLint"; // TODO: rene: set better value after categories are better defined
case GCC -> "Memory";
case RUFF -> "Pylint";
case OTHER -> "Other";
};

Expand Down

0 comments on commit 26d20ca

Please sign in to comment.