@@ -6,9 +6,11 @@ import 'dart:io';
6
6
7
7
import 'package:analyzer/src/lint/config.dart' ;
8
8
import 'package:analyzer/src/lint/registry.dart' ;
9
+ import 'package:github/server.dart' ;
9
10
import 'package:http/http.dart' as http;
10
11
import 'package:linter/src/analyzer.dart' ;
11
12
import 'package:linter/src/rules.dart' ;
13
+ import 'package:pub_semver/pub_semver.dart' ;
12
14
import 'package:yaml/yaml.dart' ;
13
15
14
16
const _allPathSuffix = '/example/all.yaml' ;
@@ -48,6 +50,33 @@ Future<List<String>> get stagehandRules async =>
48
50
Future <int > get latestMinor async =>
49
51
_latestMinor ?? = await _readLatestMinorVersion ();
50
52
53
+ List <String > _sdkTags;
54
+
55
+ Future <List <String >> get sdkTags async => _sdkTags ?? = await _fetchSdkTags ();
56
+
57
+ /// We don't care about SDKs previous to this bottom.
58
+ final Version bottomDartSdk = new Version (2 , 0 , 0 );
59
+
60
+ Future <List <String >> _fetchSdkTags () {
61
+ var github = createGitHubClient ();
62
+ var slug = RepositorySlug ('dart-lang' , 'sdk' );
63
+
64
+ return github.repositories.listTags (slug).map ((t) => t.name).where ((t) {
65
+ // Filter on numeric release tags.
66
+ if (! t.startsWith (new RegExp (r'\d+' ))) {
67
+ return false ;
68
+ }
69
+
70
+ // Filter on bottom.
71
+ try {
72
+ var version = Version .parse (t);
73
+ return version.compareTo (bottomDartSdk) >= 0 ;
74
+ } on FormatException {
75
+ return false ;
76
+ }
77
+ }).toList ();
78
+ }
79
+
51
80
Iterable <LintRule > _registeredLints;
52
81
53
82
Iterable <LintRule > get registeredLints {
@@ -58,10 +87,27 @@ Iterable<LintRule> get registeredLints {
58
87
return _registeredLints;
59
88
}
60
89
61
- Future <String > findSinceLinter (LintRule lint) async {
90
+ Future <String > findSinceDartSdk (String linterVersion) async =>
91
+ await dartSdkForLinter (linterVersion);
92
+
93
+ Future <String > dartSdkForLinter (String version) async {
94
+ var sdkVersions = < String > [];
95
+ var sdks = await sdkTags;
96
+ for (var sdk in sdks) {
97
+ var linterVersion = await linterForDartSdk (sdk);
98
+ if (linterVersion == version) {
99
+ sdkVersions.add (sdk);
100
+ }
101
+ }
102
+
103
+ sdkVersions.sort ();
104
+ return sdkVersions.isNotEmpty ? sdkVersions.first : null ;
105
+ }
106
+
107
+ Future <String > findSinceLinter (String lint) async {
62
108
// History recorded in `all.yaml` starts in minor 31.
63
109
var rules_31 = await rulesForVersion (31 );
64
- if (rules_31.contains (lint.name )) {
110
+ if (rules_31.contains (lint)) {
65
111
var version = await _crawlForVersion (lint);
66
112
if (version != null ) {
67
113
return version;
@@ -72,7 +118,7 @@ Future<String> findSinceLinter(LintRule lint) async {
72
118
for (var minor = 31 ; minor <= latest; ++ minor) {
73
119
var rules = await rulesForVersion (minor);
74
120
if (rules != null ) {
75
- if (rules.contains (lint.name )) {
121
+ if (rules.contains (lint)) {
76
122
return '0.1.$minor ' ;
77
123
}
78
124
}
@@ -87,12 +133,12 @@ Future<int> _readLatestMinorVersion() async {
87
133
return int .parse (pubspec['version' ].split ('.' ).last);
88
134
}
89
135
90
- Future <String > _crawlForVersion (LintRule lint) async {
136
+ Future <String > _crawlForVersion (String lint) async {
91
137
var client = new http.Client ();
92
138
for (int minor = 1 ; minor < 31 ; ++ minor) {
93
139
var version = '0.1.$minor ' ;
94
- var req = await client
95
- .get ('$_rulePathPrefix /$version /lib/src/rules/${ lint . name } .dart' );
140
+ var req =
141
+ await client .get ('$_rulePathPrefix /$version /lib/src/rules/$lint .dart' );
96
142
if (req.statusCode == 200 ) {
97
143
return version;
98
144
}
@@ -109,6 +155,36 @@ Future<List<String>> rulesForVersion(int minor) async {
109
155
return null ;
110
156
}
111
157
158
+ Map <String , String > _dartSdkToLinterMap = < String , String > {};
159
+
160
+ Future <String > linterForDartSdk (String sdk) async =>
161
+ _dartSdkToLinterMap[sdk] ?? = await _fetchLinterForVersion (sdk);
162
+
163
+ Future <String > _fetchLinterForVersion (String version) async {
164
+ var deps = await _fetchDEPSforVersion (version);
165
+ if (deps != null ) {
166
+ for (var line in deps.split ('\n ' )) {
167
+ if (line.trim ().startsWith ('"lint' )) {
168
+ // "linter_tag": "0.1.59",
169
+ var split = line.trim ().split ('"linter_tag":' );
170
+ if (split.length == 2 ) {
171
+ // "0.1.59",
172
+ return split[1 ].split ('"' )[1 ];
173
+ }
174
+ }
175
+ }
176
+ }
177
+ return null ;
178
+ }
179
+
180
+ Future <String > _fetchDEPSforVersion (String version) async {
181
+ var client = new http.Client ();
182
+ //https://raw.githubusercontent.com/dart-lang/sdk/2.1.0-dev.1.0/DEPS
183
+ var req = await client
184
+ .get ('https://raw.githubusercontent.com/dart-lang/sdk/$version /DEPS' );
185
+ return req.body;
186
+ }
187
+
112
188
Future <LintConfig > _fetchConfig (String url) async {
113
189
var client = new http.Client ();
114
190
var req = await client.get (url);
@@ -117,6 +193,10 @@ Future<LintConfig> _fetchConfig(String url) async {
117
193
118
194
Future <List <String >> _fetchRules (String optionsUrl) async {
119
195
var config = await _fetchConfig (optionsUrl);
196
+ if (config == null ) {
197
+ print ('no config found for: $optionsUrl (SKIPPED)' );
198
+ return < String > [];
199
+ }
120
200
var rules = < String > [];
121
201
for (var ruleConfig in config.ruleConfigs) {
122
202
rules.add (ruleConfig.name);
0 commit comments