Skip to content

Commit

Permalink
Implement the score for pylint, mypy
Browse files Browse the repository at this point in the history
Part of SAP#730
  • Loading branch information
sourabhsparkala committed Sep 6, 2022
1 parent e78e1b7 commit 4981975
Show file tree
Hide file tree
Showing 21 changed files with 1,689 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ private OssFeatures() {
public static final Feature<Boolean> USES_GOSEC_WITH_RULES
= new BooleanFeature("If a project runs GoSec scans with rules");

/*
/**
* Shows if an open-source project runs Pylint scans.
*
* @see <a href="https://pylint.pycqa.org/en/latest/user_guide/installation/index.html">Trigger
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.sap.oss.phosphor.fosstars.model.score.oss;

import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.LANGUAGES;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.RUNS_MYPY_SCANS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_MYPY_SCAN_CHECKS;
import static com.sap.oss.phosphor.fosstars.model.other.Utils.findValue;
import static com.sap.oss.phosphor.fosstars.model.value.Language.PYTHON;

import com.sap.oss.phosphor.fosstars.model.Value;
import com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures;
import com.sap.oss.phosphor.fosstars.model.score.FeatureBasedScore;
import com.sap.oss.phosphor.fosstars.model.value.Languages;
import com.sap.oss.phosphor.fosstars.model.value.ScoreValue;

/**
* <p>The score shows if and how a project uses static analysis with MyPy.
* The score is based on the following features.</p>
* <ul>
* <li>{@link OssFeatures#USES_MYPY_SCAN_CHECKS}</li>
* <li>{@link OssFeatures#RUNS_MYPY_SCANS}</li>
* <li>{@link OssFeatures#LANGUAGES}</li>
* </ul>
*/
public class MyPyScore extends FeatureBasedScore {

/**
* Programming languages supported by MyPy.
*
* @see <a href="http://www.mypy-lang.org/">MyPy
* overview</a>
*/
private static final Languages SUPPORTED_LANGUAGES = Languages.of(PYTHON);

/**
* Defines how the score value is increased if a project runs MyPy scans.
*/
private static final double MYPY_SCANS_POINTS = 6.0;

/**
* Defines how the score value is increased if a project runs MyPy checks for commits.
*/
private static final double MYPY_CHECKS_POINTS = 7.0;

/**
* Initializes a new {@link MyPyScore}.
*/
MyPyScore() {
super("How a project uses MyPy", USES_MYPY_SCAN_CHECKS, RUNS_MYPY_SCANS, LANGUAGES);
}

@Override
public ScoreValue calculate(Value<?>... values) {
Value<Boolean> usesMyPyChecks = findValue(values, USES_MYPY_SCAN_CHECKS,
"Hey! You have to tell me if the project uses MyPy checks!");
Value<Boolean> runsMyPyScans = findValue(values, RUNS_MYPY_SCANS,
"Hey! You have to tell me if the project runs MyPy scans!");
Value<Languages> languages = findValue(values, LANGUAGES,
"Hey! You have to tell me which languages the project uses!");

ScoreValue scoreValue = scoreValue(MIN,
usesMyPyChecks, runsMyPyScans, languages);

if (allUnknown(usesMyPyChecks, runsMyPyScans, languages)) {
return scoreValue.makeUnknown().explain(
"The score value is unknown because all required features are unknown.");
}

if (languages.isUnknown()) {
return scoreValue.makeNotApplicable().explain(
"The score is N/A because the project does not confirm which languages are used.");
}

if (!languages.isUnknown() && !SUPPORTED_LANGUAGES.containsAnyOf(languages.get())) {
return scoreValue.makeNotApplicable().explain(
"The score is N/A because the project uses languages that are not supported by MyPy.");
}

if (usesMyPyChecks.orElse(false)) {
scoreValue.increase(MYPY_CHECKS_POINTS);
}

if (runsMyPyScans.orElse(false)) {
scoreValue.increase(MYPY_SCANS_POINTS);
}

return scoreValue;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.sap.oss.phosphor.fosstars.model.score.oss;

import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.LANGUAGES;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.RUNS_PYLINT_SCANS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_PYLINT_SCAN_CHECKS;
import static com.sap.oss.phosphor.fosstars.model.other.Utils.findValue;
import static com.sap.oss.phosphor.fosstars.model.value.Language.PYTHON;

import com.sap.oss.phosphor.fosstars.model.Value;
import com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures;
import com.sap.oss.phosphor.fosstars.model.score.FeatureBasedScore;
import com.sap.oss.phosphor.fosstars.model.value.Languages;
import com.sap.oss.phosphor.fosstars.model.value.ScoreValue;

/**
* <p>The score shows if and how a project uses static analysis with Pylint.
* The score is based on the following features.</p>
* <ul>
* <li>{@link OssFeatures#USES_PYLINT_SCAN_CHECKS}</li>
* <li>{@link OssFeatures#RUNS_PYLINT_SCANS}</li>
* <li>{@link OssFeatures#LANGUAGES}</li>
* </ul>
*/
public class PylintScore extends FeatureBasedScore {

/**
* Programming languages supported by Pylint.
*
* @see <a href="https://pylint.pycqa.org/en/latest/index.html">Pylint
* overview</a>
*/
private static final Languages SUPPORTED_LANGUAGES = Languages.of(PYTHON);

/**
* Defines how the score value is increased if a project runs Pylint scans.
*/
private static final double PYLINT_SCANS_POINTS = 6.0;

/**
* Defines how the score value is increased if a project runs Pylint checks for commits.
*/
private static final double PYLINT_CHECKS_POINTS = 7.0;

/**
* Initializes a new {@link PylintScore}.
*/
PylintScore() {
super("How a project uses Pylint", USES_PYLINT_SCAN_CHECKS, RUNS_PYLINT_SCANS, LANGUAGES);
}

@Override
public ScoreValue calculate(Value<?>... values) {
Value<Boolean> usesPylintChecks = findValue(values, USES_PYLINT_SCAN_CHECKS,
"Hey! You have to tell me if the project uses Pylint checks!");
Value<Boolean> runsPylintScans = findValue(values, RUNS_PYLINT_SCANS,
"Hey! You have to tell me if the project runs Pylint scans!");
Value<Languages> languages = findValue(values, LANGUAGES,
"Hey! You have to tell me which languages the project uses!");

ScoreValue scoreValue = scoreValue(MIN,
usesPylintChecks, runsPylintScans, languages);

if (allUnknown(usesPylintChecks, runsPylintScans, languages)) {
return scoreValue.makeUnknown().explain(
"The score value is unknown because all required features are unknown.");
}

if (languages.isUnknown()) {
return scoreValue.makeNotApplicable().explain(
"The score is N/A because the project does not confirm which languages are used.");
}

if (!languages.isUnknown() && !SUPPORTED_LANGUAGES.containsAnyOf(languages.get())) {
return scoreValue.makeNotApplicable().explain(
"The score is N/A because the project uses languages that are not supported by Pylint.");
}

if (usesPylintChecks.orElse(false)) {
scoreValue.increase(PYLINT_CHECKS_POINTS);
}

if (runsPylintScans.orElse(false)) {
scoreValue.increase(PYLINT_SCANS_POINTS);
}

return scoreValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* <li>{@link LgtmScore}</li>
* <li>{@link FindSecBugsScore}</li>
* <li>{@link BanditScore}</li>
* <li>{@link PylintScore}</li>
* <li>{@link MyPyScore}</li>
* <li>{@link GoSecScore}</li>
* </ul>
* <p>The above sub-scores may not apply to all projects. The score considers only the sub-scores
Expand All @@ -32,6 +34,8 @@ private static ScoreWeights initWeights() {
.set(LgtmScore.class, new ImmutableWeight(1.0))
.set(FindSecBugsScore.class, new ImmutableWeight(0.5))
.set(BanditScore.class, new ImmutableWeight(0.5))
.set(PylintScore.class, new ImmutableWeight(0.4))
.set(MyPyScore.class, new ImmutableWeight(0.3))
.set(GoSecScore.class, new ImmutableWeight(0.5));
}

Expand All @@ -41,6 +45,7 @@ private static ScoreWeights initWeights() {
public StaticAnalysisScore() {
super("How a project uses static analysis for security testing",
setOf(new CodeqlScore(), new LgtmScore(), new FindSecBugsScore(), new BanditScore(),
new GoSecScore()), initWeights());
new PylintScore(), new MyPyScore(), new GoSecScore()),
initWeights());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.REGISTERED_IN_REUSE;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.RUNS_CODEQL_SCANS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.RUNS_GOSEC_SCANS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.RUNS_MYPY_SCANS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.RUNS_PYLINT_SCANS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.SCANS_FOR_VULNERABLE_DEPENDENCIES;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.SECURITY_REVIEWS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.SIGNS_ARTIFACTS;
Expand All @@ -48,10 +50,12 @@
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_GOSEC_WITH_RULES;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_LGTM_CHECKS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_MEMORY_SANITIZER;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_MYPY_SCAN_CHECKS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_NOHTTP;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_OWASP_ESAPI;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_OWASP_JAVA_ENCODER;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_OWASP_JAVA_HTML_SANITIZER;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_PYLINT_SCAN_CHECKS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_REUSE;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_SIGNED_COMMITS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_SNYK;
Expand All @@ -72,6 +76,7 @@
import com.sap.oss.phosphor.fosstars.model.Confidence;
import com.sap.oss.phosphor.fosstars.model.Feature;
import com.sap.oss.phosphor.fosstars.model.Value;
import com.sap.oss.phosphor.fosstars.model.score.oss.BanditScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.CommunityCommitmentScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.DependabotScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.DependencyScanScore;
Expand Down Expand Up @@ -136,6 +141,7 @@ public abstract class CommonFormatter implements Formatter {
add(FuzzingScore.class, "Fuzzing");
add(StaticAnalysisScore.class, "Static analysis");
add(NoHttpToolScore.class, "nohttp tool");
add(BanditScore.class, "Bandit score");
add(LgtmScore.class, "LGTM score");
add(GoSecScore.class, "GoSec score");
add(FindSecBugsScore.class, "FindSecBugs score");
Expand Down Expand Up @@ -240,6 +246,10 @@ private static void add(Class<? extends Feature<?>> clazz, String caption) {
add(AVAILABILITY_IMPACT,
"What is potential availability impact in case of a security problem?");
add(HAS_EXECUTABLE_BINARIES, "Does it have executable binaries?");
add(RUNS_PYLINT_SCANS, "Does it run Pylint scans?");
add(USES_PYLINT_SCAN_CHECKS, "Does it run Pylint scans on all commits?");
add(RUNS_MYPY_SCANS, "Does it run MyPy scans?");
add(USES_MYPY_SCAN_CHECKS, "Does it run MyPy scans on all commits?");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import com.sap.oss.phosphor.fosstars.model.score.oss.GoSecScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.LgtmScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.MemorySafetyTestingScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.MyPyScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.NoHttpToolScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.OssArtifactSecurityScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.OssRulesOfPlayScore;
Expand All @@ -68,6 +69,7 @@
import com.sap.oss.phosphor.fosstars.model.score.oss.ProjectPopularityScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.ProjectSecurityAwarenessScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.ProjectSecurityTestingScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.PylintScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.SecurityReviewScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.SnykDependencyScanScore;
import com.sap.oss.phosphor.fosstars.model.score.oss.StaticAnalysisScore;
Expand Down Expand Up @@ -316,7 +318,9 @@ static ObjectMapper registerSubTypesIn(ObjectMapper mapper) {
RiskImpactScore.AvailabilityRiskImpactFactor.class,
CalculatedSecurityRiskIntroducedByOss.class,
BanditScore.class,
GoSecScore.class
GoSecScore.class,
PylintScore.class,
MyPyScore.class
);

// ratings
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/com/sap/oss/phosphor/fosstars/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.RUNS_BANDIT_SCANS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.RUNS_CODEQL_SCANS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.RUNS_GOSEC_SCANS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.RUNS_MYPY_SCANS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.RUNS_PYLINT_SCANS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.SECURITY_REVIEWS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.SIGNS_ARTIFACTS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.SUPPORTED_BY_COMPANY;
Expand All @@ -35,10 +37,12 @@
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_GOSEC_WITH_RULES;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_LGTM_CHECKS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_MEMORY_SANITIZER;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_MYPY_SCAN_CHECKS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_NOHTTP;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_OWASP_ESAPI;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_OWASP_JAVA_ENCODER;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_OWASP_JAVA_HTML_SANITIZER;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_PYLINT_SCAN_CHECKS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_SIGNED_COMMITS;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_SNYK;
import static com.sap.oss.phosphor.fosstars.model.feature.oss.OssFeatures.USES_UNDEFINED_BEHAVIOR_SANITIZER;
Expand Down Expand Up @@ -203,6 +207,10 @@ public static Set<Value<?>> getDefaultValues() {
RUNS_GOSEC_SCANS.value(false),
USES_GOSEC_WITH_RULES.value(false),
USES_GOSEC_SCAN_CHECKS.value(false),
RUNS_PYLINT_SCANS.value(false),
USES_PYLINT_SCAN_CHECKS.value(false),
RUNS_MYPY_SCANS.value(false),
USES_MYPY_SCAN_CHECKS.value(false),
USES_LGTM_CHECKS.value(true),
WORST_LGTM_GRADE.value(LgtmGrade.B),
USES_NOHTTP.value(true),
Expand Down Expand Up @@ -282,6 +290,10 @@ public static Set<Value<?>> getBestValues() {
RUNS_GOSEC_SCANS.value(true),
USES_GOSEC_WITH_RULES.value(true),
USES_GOSEC_SCAN_CHECKS.value(true),
RUNS_PYLINT_SCANS.value(true),
USES_PYLINT_SCAN_CHECKS.value(true),
RUNS_MYPY_SCANS.value(true),
USES_MYPY_SCAN_CHECKS.value(true),
USES_LGTM_CHECKS.value(true),
WORST_LGTM_GRADE.value(LgtmGrade.A_PLUS),
USES_NOHTTP.value(true),
Expand Down
Loading

0 comments on commit 4981975

Please sign in to comment.