Skip to content

Commit

Permalink
Estimate health score penalties. (dart-lang#417)
Browse files Browse the repository at this point in the history
* Estimate health score penalties.

* Updating generated version
  • Loading branch information
isoos authored Sep 26, 2018
1 parent a8e903b commit 86dcb16
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 24 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.12.4

* Documented how scoring works.

* Estimate health score penalties.

## 0.12.3

* Increased `dartfmt` timeout to 5 minutes.
Expand Down
11 changes: 11 additions & 0 deletions lib/src/health.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,18 @@ Health calcHealth({
.map((cp) => '\n\nline ${cp.line} col ${cp.col}: ${cp.description}')
.join();

// Calculating the maximum impact on the score. The sum of these penalties
// will add up more than the multiplied calculation of the health score,
// but we'll display a disclaimer on the pub site for it.
final score = calculateBaseHealth(errorCount, warningCount, hintCount);
final penalty = (10000.0 * (1.0 - score)).roundToDouble() / 100.0;
suggestions.add(new Suggestion(
SuggestionCode.dartanalyzerWarning,
maxLevel,
'Fix `$path`.',
'Analysis of `$path` $failedWith $issueCounts$including:$issueList',
file: path,
score: penalty == 0.0 ? null : penalty,
));
}
}
Expand Down Expand Up @@ -147,12 +153,17 @@ List<Suggestion> _compact(
? SuggestionLevel.error
: (hasWarning ? SuggestionLevel.warning : SuggestionLevel.hint);

final bulkScore = restSuggestions
.map((s) => s.score)
.where((d) => d != null)
.fold<double>(0.0, (a, b) => a + b);
suggestions.add(
new Suggestion(
SuggestionCode.bulk,
level,
'Fix additional ${restSuggestions.length} files with analysis or formatting issues.',
sb.toString(),
score: bulkScore == 0.0 ? null : bulkScore,
),
);
}
Expand Down
24 changes: 19 additions & 5 deletions lib/src/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ import 'utils.dart' show toRelativePath;

part 'model.g.dart';

/// NOTE: In case these change, update README.md
const healthErrorMultiplier = 0.75;
const healthWarningMultiplier = 0.95;
const healthHintMultiplier = 0.995;

@JsonSerializable()
class Summary extends Object with _$SummarySerializerMixin {
@JsonKey(nullable: false)
Expand Down Expand Up @@ -658,21 +663,30 @@ class Health extends Object with _$HealthSerializerMixin {

/// Returns a health score between 0.0 and 1.0 (1.0 being the top score it can get).
///
/// NOTE: In case this changes, update README.md
/// NOTE: In case these change, update README.md
double get healthScore {
if (anyProcessFailed) {
// can't reliably determine the score if we can't parse and analyze the sources
return 0.0;
}
double score = math.pow(0.75, analyzerErrorCount) *
math.pow(0.95, analyzerWarningCount) *
math.pow(0.995, analyzerHintCount);
// TODO: document why and how platform conflict influence the score
var score = calculateBaseHealth(
analyzerErrorCount, analyzerWarningCount, analyzerHintCount);
score -= 0.25 * platformConflictCount;
return math.max(0.0, score);
}
}

/// Returns the part of the health score that is calculated from the number of
/// `dartanalyzer` items. Other penalties will be deduced from this base score
/// (e.g. platform conflict, dartdoc coverage).
double calculateBaseHealth(
int analyzerErrorCount, int analyzerWarningCount, int analyzerHintCount) {
final score = math.pow(healthErrorMultiplier, analyzerErrorCount) *
math.pow(healthWarningMultiplier, analyzerWarningCount) *
math.pow(healthHintMultiplier, analyzerHintCount);
return score.toDouble();
}

/// Describes the maintenance status of the package.
@JsonSerializable()
class Maintenance extends Object with _$MaintenanceSerializerMixin {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/version.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: pana
description: Evaluate the health and quality of a Dart package
version: 0.12.3
version: 0.12.4
homepage: https://github.com/dart-lang/pana
author: Dart Team <misc@dartlang.org>

Expand Down
6 changes: 4 additions & 2 deletions test/end2end/dartdoc-0.20.3.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,16 @@
"level": "error",
"title": "Fix `lib/src/model.dart`.",
"description": "Analysis of `lib/src/model.dart` failed with 1 error, 4 hints:\n\nline 4855 col 21: The class 'Canonicalization' can't be used as a mixin because it extends a class other than Object.\n\nline 1064 col 17: Always override `hashCode` if overriding `==`.\n\nline 2118 col 25: Invocation of Iterable<E>.contains with references of unrelated types.\n\nline 5228 col 37: 'element' is deprecated and shouldn't be used.\n\nline 5229 col 25: 'element' is deprecated and shouldn't be used.",
"file": "lib/src/model.dart"
"file": "lib/src/model.dart",
"score": 26.49
},
{
"code": "dartanalyzer.warning",
"level": "hint",
"title": "Fix `lib/src/third_party/pkg/mustache4dart/lib/src/tmpl.dart`.",
"description": "Analysis of `lib/src/third_party/pkg/mustache4dart/lib/src/tmpl.dart` reported 2 hints:\n\nline 274 col 12: Equality operator `==` invocation with references of unrelated types.\n\nline 274 col 23: Equality operator `==` invocation with references of unrelated types.",
"file": "lib/src/third_party/pkg/mustache4dart/lib/src/tmpl.dart"
"file": "lib/src/third_party/pkg/mustache4dart/lib/src/tmpl.dart",
"score": 1.0
}
]
},
Expand Down
15 changes: 8 additions & 7 deletions test/end2end/http-0.11.3-17.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@
"analyzerHintCount": 2,
"platformConflictCount": 0,
"suggestions": [
{
"code": "dartanalyzer.warning",
"level": "hint",
"title": "Fix `lib/src/base_client.dart`.",
"description": "Analysis of `lib/src/base_client.dart` reported 2 hints:\n\nline 163 col 44: 'typed' is deprecated and shouldn't be used.\n\nline 165 col 44: 'typed' is deprecated and shouldn't be used.",
"file": "lib/src/base_client.dart",
"score": 1.0
},
{
"code": "dartfmt.warning",
"level": "hint",
Expand All @@ -64,13 +72,6 @@
"description": "Run `dartfmt` to format `lib/http.dart`.",
"file": "lib/http.dart"
},
{
"code": "dartanalyzer.warning",
"level": "hint",
"title": "Fix `lib/src/base_client.dart`.",
"description": "Analysis of `lib/src/base_client.dart` reported 2 hints:\n\nline 163 col 44: 'typed' is deprecated and shouldn't be used.\n\nline 165 col 44: 'typed' is deprecated and shouldn't be used.",
"file": "lib/src/base_client.dart"
},
{
"code": "bulk",
"level": "hint",
Expand Down
17 changes: 9 additions & 8 deletions test/end2end/stream-2.0.1.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@
"analyzerHintCount": 1,
"platformConflictCount": 0,
"suggestions": [
{
"code": "dartanalyzer.warning",
"level": "hint",
"title": "Fix `lib/src/plugin/loader.dart`.",
"description": "Analysis of `lib/src/plugin/loader.dart` reported 1 hint:\n\nline 83 col 16: Always override `hashCode` if overriding `==`.",
"file": "lib/src/plugin/loader.dart",
"score": 0.5
},
{
"code": "dartfmt.warning",
"level": "hint",
Expand All @@ -69,18 +77,11 @@
"description": "Run `dartfmt` to format `lib/src/connect.dart`.",
"file": "lib/src/connect.dart"
},
{
"code": "dartfmt.warning",
"level": "hint",
"title": "Format `lib/src/connect_impl.dart`.",
"description": "Run `dartfmt` to format `lib/src/connect_impl.dart`.",
"file": "lib/src/connect_impl.dart"
},
{
"code": "bulk",
"level": "hint",
"title": "Fix additional 11 files with analysis or formatting issues.",
"description": "Additional issues in the following files:\n\n- `lib/src/plugin/loader.dart` (1 hint)\n- `lib/src/plugin/loader_impl.dart` (Run `dartfmt` to format `lib/src/plugin/loader_impl.dart`.)\n- `lib/src/plugin/router.dart` (Run `dartfmt` to format `lib/src/plugin/router.dart`.)\n- `lib/src/rsp_util.dart` (Run `dartfmt` to format `lib/src/rsp_util.dart`.)\n- `lib/src/rspc/build.dart` (Run `dartfmt` to format `lib/src/rspc/build.dart`.)\n- `lib/src/rspc/compiler.dart` (Run `dartfmt` to format `lib/src/rspc/compiler.dart`.)\n- `lib/src/rspc/main.dart` (Run `dartfmt` to format `lib/src/rspc/main.dart`.)\n- `lib/src/rspc/tag.dart` (Run `dartfmt` to format `lib/src/rspc/tag.dart`.)\n- `lib/src/rspc/tag_util.dart` (Run `dartfmt` to format `lib/src/rspc/tag_util.dart`.)\n- `lib/src/server.dart` (Run `dartfmt` to format `lib/src/server.dart`.)\n- `lib/src/server_impl.dart` (Run `dartfmt` to format `lib/src/server_impl.dart`.)\n"
"description": "Additional issues in the following files:\n\n- `lib/src/connect_impl.dart` (Run `dartfmt` to format `lib/src/connect_impl.dart`.)\n- `lib/src/plugin/loader_impl.dart` (Run `dartfmt` to format `lib/src/plugin/loader_impl.dart`.)\n- `lib/src/plugin/router.dart` (Run `dartfmt` to format `lib/src/plugin/router.dart`.)\n- `lib/src/rsp_util.dart` (Run `dartfmt` to format `lib/src/rsp_util.dart`.)\n- `lib/src/rspc/build.dart` (Run `dartfmt` to format `lib/src/rspc/build.dart`.)\n- `lib/src/rspc/compiler.dart` (Run `dartfmt` to format `lib/src/rspc/compiler.dart`.)\n- `lib/src/rspc/main.dart` (Run `dartfmt` to format `lib/src/rspc/main.dart`.)\n- `lib/src/rspc/tag.dart` (Run `dartfmt` to format `lib/src/rspc/tag.dart`.)\n- `lib/src/rspc/tag_util.dart` (Run `dartfmt` to format `lib/src/rspc/tag_util.dart`.)\n- `lib/src/server.dart` (Run `dartfmt` to format `lib/src/server.dart`.)\n- `lib/src/server_impl.dart` (Run `dartfmt` to format `lib/src/server_impl.dart`.)\n"
}
]
},
Expand Down

0 comments on commit 86dcb16

Please sign in to comment.