Skip to content

Commit

Permalink
annotate pedantic lint benchmarks (#1840)
Browse files Browse the repository at this point in the history
* annotate pedantic lint benchmarks

* fmt

* fix dep
  • Loading branch information
pq committed Nov 14, 2019
1 parent d998626 commit dc99900
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 115 deletions.
11 changes: 8 additions & 3 deletions lib/src/formatter.dart
Expand Up @@ -8,6 +8,7 @@ import 'dart:math';
import 'package:analyzer/error/error.dart';

import 'analyzer.dart';
import 'util/score_utils.dart';

const benchmarkRuns = 10;
final int _pipeCodeUnit = '|'.codeUnitAt(0);
Expand Down Expand Up @@ -58,7 +59,11 @@ Future writeBenchmarks(
});
}

List<_Stat> stats = timings.keys.map((t) => _Stat(t, timings[t])).toList();
final pedanticRuleset = await pedanticRules;
final stats = timings.keys.map((t) {
final details = pedanticRuleset.contains(t) ? ' [pedantic]' : '';
return _Stat('$t$details', timings[t]);
}).toList();
_writeTimings(out, stats, 0);
}

Expand Down Expand Up @@ -293,8 +298,8 @@ class SimpleFormatter implements ReportFormatter {
}

void writeTimings() {
Map<String, Stopwatch> timers = lintRegistry.timers;
List<_Stat> timings = timers.keys
final timers = lintRegistry.timers;
final timings = timers.keys
.map((t) => _Stat(t, timers[t].elapsedMilliseconds))
.toList();
_writeTimings(out, timings, _summaryLength);
Expand Down
41 changes: 41 additions & 0 deletions lib/src/util/score_utils.dart
@@ -0,0 +1,41 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analyzer/src/lint/config.dart'; // ignore: implementation_imports
import 'package:http/http.dart' as http;

const _pedanticOptionsRootUrl =
'https://raw.githubusercontent.com/dart-lang/pedantic/master/lib';
const _pedanticOptionsUrl = '$_pedanticOptionsRootUrl/analysis_options.yaml';

List<String> _pedanticRules;
Future<List<String>> get pedanticRules async =>
_pedanticRules ??= await _fetchPedanticRules();

Future<List<String>> fetchRules(String optionsUrl) async {
final config = await _fetchConfig(optionsUrl);
if (config == null) {
print('no config found for: $optionsUrl (SKIPPED)');
return <String>[];
}
final rules = <String>[];
for (var ruleConfig in config.ruleConfigs) {
rules.add(ruleConfig.name);
}
return rules;
}

Future<LintConfig> _fetchConfig(String url) async {
final client = http.Client();
final req = await client.get(url);
return processAnalysisOptionsFile(req.body);
}

Future<List<String>> _fetchPedanticRules() async {
final client = http.Client();
final req = await client.get(_pedanticOptionsUrl);
final includedOptions =
req.body.split('include: package:pedantic/')[1].trim();
return fetchRules('$_pedanticOptionsRootUrl/$includedOptions');
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Expand Up @@ -17,6 +17,7 @@ dependencies:
analyzer: ^0.39.1
args: '>=1.4.0 <2.0.0'
glob: ^1.0.3
http: ^0.12.0
meta: ^1.0.2
source_span: ^1.0.2
yaml: ^2.1.2
Expand All @@ -27,7 +28,6 @@ dev_dependencies:
dart_style: ^1.3.3
github: ^5.0.0
grinder: ^0.8.0
http: ^0.12.0
markdown: ^2.0.0
matcher: ^0.12.0
path: ^1.2.0
Expand Down
192 changes: 81 additions & 111 deletions tool/crawl.dart
Expand Up @@ -4,104 +4,61 @@

import 'dart:io';

import 'package:analyzer/src/lint/config.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:github/server.dart';
import 'package:http/http.dart' as http;
import 'package:linter/src/analyzer.dart';
import 'package:linter/src/rules.dart';
import 'package:linter/src/util/score_utils.dart' as score_utils;
import 'package:pub_semver/pub_semver.dart';
import 'package:yaml/yaml.dart';

const _allPathSuffix = '/example/all.yaml';
const _repoPathPrefix = 'https://raw.githubusercontent.com/dart-lang/linter/';
const _rulePathPrefix = 'https://raw.githubusercontent.com/dart-lang/linter';
const _effectiveDartOptionsRootUrl =
'https://raw.githubusercontent.com/tenhobi/effective_dart/master/lib';
const _effectiveDartOptionsUrl =
'$_effectiveDartOptionsRootUrl/analysis_options.yaml';

const _flutterOptionsUrl =
'https://raw.githubusercontent.com/flutter/flutter/master/packages/flutter/lib/analysis_options_user.yaml';
const _flutterRepoOptionsUrl =
'https://raw.githubusercontent.com/flutter/flutter/master/analysis_options.yaml';
const _pedanticOptionsRootUrl =
'https://raw.githubusercontent.com/dart-lang/pedantic/master/lib';
const _pedanticOptionsUrl = '$_pedanticOptionsRootUrl/analysis_options.yaml';
const _effectiveDartOptionsRootUrl =
'https://raw.githubusercontent.com/tenhobi/effective_dart/master/lib';
const _effectiveDartOptionsUrl =
'$_effectiveDartOptionsRootUrl/analysis_options.yaml';
const _repoPathPrefix = 'https://raw.githubusercontent.com/dart-lang/linter/';
const _rulePathPrefix = 'https://raw.githubusercontent.com/dart-lang/linter';
const _stagehandOptionsUrl =
'https://raw.githubusercontent.com/dart-lang/stagehand/master/templates/analysis_options.yaml';

int _latestMinor;
/// We don't care about SDKs previous to this bottom.
final Version bottomDartSdk = Version(2, 0, 0);

Map<String, List<String>> _sinceMap = <String, List<String>>{};
Map<String, String> _dartSdkToLinterMap = <String, String>{};

List<String> _flutterRules;
List<String> _flutterRepoRules;
List<String> _pedanticRules;
List<String> _effectiveDartRules;
List<String> _stagehandRules;
List<String> _flutterRepoRules;
List<String> _flutterRules;
int _latestMinor;

Future<List<String>> get flutterRules async =>
_flutterRules ??= await _fetchRules(_flutterOptionsUrl);
Iterable<LintRule> _registeredLints;

Future<List<String>> get flutterRepoRules async =>
_flutterRepoRules ??= await _fetchRules(_flutterRepoOptionsUrl);
List<String> _sdkTags;

Future<List<String>> get pedanticRules async =>
_pedanticRules ??= await _fetchPedanticRules();
Map<String, List<String>> _sinceMap = <String, List<String>>{};

Future<List<String>> _fetchPedanticRules() async {
var client = http.Client();
var req = await client.get(_pedanticOptionsUrl);
var includedOptions = req.body.split('include: package:pedantic/')[1].trim();
return _fetchRules('$_pedanticOptionsRootUrl/$includedOptions');
}
List<String> _stagehandRules;

Future<List<String>> get effectiveDartRules async =>
_effectiveDartRules ??= await _fetchEffectiveDartRules();

Future<List<String>> _fetchEffectiveDartRules() async {
var client = http.Client();
var req = await client.get(_effectiveDartOptionsUrl);
var includedOptions =
req.body.split('include: package:effective_dart/')[1].trim();
return _fetchRules('$_effectiveDartOptionsRootUrl/$includedOptions');
}
Future<List<String>> get flutterRepoRules async =>
_flutterRepoRules ??= await score_utils.fetchRules(_flutterRepoOptionsUrl);

Future<List<String>> get stagehandRules async =>
_stagehandRules ??= await _fetchRules(_stagehandOptionsUrl);
Future<List<String>> get flutterRules async =>
_flutterRules ??= await score_utils.fetchRules(_flutterOptionsUrl);

Future<int> get latestMinor async =>
_latestMinor ??= await _readLatestMinorVersion();

List<String> _sdkTags;

Future<List<String>> get sdkTags async => _sdkTags ??= await _fetchSdkTags();

/// We don't care about SDKs previous to this bottom.
final Version bottomDartSdk = Version(2, 0, 0);

Future<List<String>> _fetchSdkTags() {
var github = createGitHubClient();
var slug = RepositorySlug('dart-lang', 'sdk');

return github.repositories.listTags(slug).map((t) => t.name).where((t) {
// Filter on numeric release tags.
if (!t.startsWith(RegExp(r'\d+'))) {
return false;
}

// Filter on bottom.
try {
var version = Version.parse(t);
return version.compareTo(bottomDartSdk) >= 0;
} on FormatException {
return false;
}
}).toList();
}

Iterable<LintRule> _registeredLints;
Future<List<String>> get pedanticRules async => score_utils.pedanticRules;

Iterable<LintRule> get registeredLints {
if (_registeredLints == null) {
Expand All @@ -111,8 +68,10 @@ Iterable<LintRule> get registeredLints {
return _registeredLints;
}

Future<String> findSinceDartSdk(String linterVersion) async =>
await dartSdkForLinter(linterVersion);
Future<List<String>> get sdkTags async => _sdkTags ??= await _fetchSdkTags();

Future<List<String>> get stagehandRules async =>
_stagehandRules ??= await score_utils.fetchRules(_stagehandOptionsUrl);

Future<String> dartSdkForLinter(String version) async {
var sdkVersions = <String>[];
Expand All @@ -128,6 +87,9 @@ Future<String> dartSdkForLinter(String version) async {
return sdkVersions.isNotEmpty ? sdkVersions.first : null;
}

Future<String> findSinceDartSdk(String linterVersion) async =>
await dartSdkForLinter(linterVersion);

Future<String> findSinceLinter(String lint) async {
// History recorded in `all.yaml` starts in minor 31.
var rules_31 = await rulesForVersion(31);
Expand All @@ -151,17 +113,16 @@ Future<String> findSinceLinter(String lint) async {
return null;
}

Future<int> _readLatestMinorVersion() async {
var contents = await File('pubspec.yaml').readAsString();
YamlMap pubspec = loadYamlNode(contents) as YamlMap;
// 0.1.79 or 0.1.79-dev or 0.1.97+1
return int.parse((pubspec['version'] as String)
.split('.')
.last
.split('-')
.first
.split('+')
.first);
Future<String> linterForDartSdk(String sdk) async =>
_dartSdkToLinterMap[sdk] ??= await _fetchLinterForVersion(sdk);

Future<List<String>> rulesForVersion(int minor) async {
var version = '0.1.$minor';
if (minor >= 31) {
return _sinceMap[version] ??=
await score_utils.fetchRules('$_repoPathPrefix$version$_allPathSuffix');
}
return null;
}

Future<String> _crawlForVersion(String lint) async {
Expand All @@ -177,19 +138,22 @@ Future<String> _crawlForVersion(String lint) async {
return null;
}

Future<List<String>> rulesForVersion(int minor) async {
var version = '0.1.$minor';
if (minor >= 31) {
return _sinceMap[version] ??=
await _fetchRules('$_repoPathPrefix$version$_allPathSuffix');
}
return null;
Future<String> _fetchDEPSforVersion(String version) async {
var client = http.Client();
//https://raw.githubusercontent.com/dart-lang/sdk/2.1.0-dev.1.0/DEPS
var req = await client
.get('https://raw.githubusercontent.com/dart-lang/sdk/$version/DEPS');
return req.body;
}

Map<String, String> _dartSdkToLinterMap = <String, String>{};

Future<String> linterForDartSdk(String sdk) async =>
_dartSdkToLinterMap[sdk] ??= await _fetchLinterForVersion(sdk);
Future<List<String>> _fetchEffectiveDartRules() async {
var client = http.Client();
var req = await client.get(_effectiveDartOptionsUrl);
var includedOptions =
req.body.split('include: package:effective_dart/')[1].trim();
return score_utils
.fetchRules('$_effectiveDartOptionsRootUrl/$includedOptions');
}

Future<String> _fetchLinterForVersion(String version) async {
var deps = await _fetchDEPSforVersion(version);
Expand All @@ -208,29 +172,35 @@ Future<String> _fetchLinterForVersion(String version) async {
return null;
}

Future<String> _fetchDEPSforVersion(String version) async {
var client = http.Client();
//https://raw.githubusercontent.com/dart-lang/sdk/2.1.0-dev.1.0/DEPS
var req = await client
.get('https://raw.githubusercontent.com/dart-lang/sdk/$version/DEPS');
return req.body;
}
Future<List<String>> _fetchSdkTags() {
var github = createGitHubClient();
var slug = RepositorySlug('dart-lang', 'sdk');

Future<LintConfig> _fetchConfig(String url) async {
var client = http.Client();
var req = await client.get(url);
return processAnalysisOptionsFile(req.body);
return github.repositories.listTags(slug).map((t) => t.name).where((t) {
// Filter on numeric release tags.
if (!t.startsWith(RegExp(r'\d+'))) {
return false;
}

// Filter on bottom.
try {
var version = Version.parse(t);
return version.compareTo(bottomDartSdk) >= 0;
} on FormatException {
return false;
}
}).toList();
}

Future<List<String>> _fetchRules(String optionsUrl) async {
var config = await _fetchConfig(optionsUrl);
if (config == null) {
print('no config found for: $optionsUrl (SKIPPED)');
return <String>[];
}
var rules = <String>[];
for (var ruleConfig in config.ruleConfigs) {
rules.add(ruleConfig.name);
}
return rules;
Future<int> _readLatestMinorVersion() async {
var contents = await File('pubspec.yaml').readAsString();
YamlMap pubspec = loadYamlNode(contents) as YamlMap;
// 0.1.79 or 0.1.79-dev or 0.1.97+1
return int.parse((pubspec['version'] as String)
.split('.')
.last
.split('-')
.first
.split('+')
.first);
}

0 comments on commit dc99900

Please sign in to comment.