Skip to content

Commit e260653

Browse files
committed
Collect tooling/config/runtime issues, instead of throwing on the first one that breaks. Fixes #19.
1 parent e570cdb commit e260653

File tree

5 files changed

+71
-17
lines changed

5 files changed

+71
-17
lines changed

lib/pana.dart

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class PackageAnalyzer {
3434

3535
Future<Summary> inspectPackage(String package,
3636
{String version, bool keepTransitiveLibs: false}) async {
37+
List<AnalyzerIssue> issues = [];
3738
var sdkVersion = _dartSdk.version;
3839
log.info("SDK: $sdkVersion");
3940

@@ -65,8 +66,8 @@ class PackageAnalyzer {
6566
log.info("Checking pubspec.yaml...");
6667
var pubspec = new Pubspec.parseFromDir(pkgDir);
6768
if (pubspec.hasUnknownSdks) {
68-
throw new Exception(
69-
'Unknown SDKs in pubspec.yaml: ${pubspec.dependentSdks}');
69+
issues.add(new AnalyzerIssue(AnalyzerScopes.pubspec,
70+
'Unknown SDKs: ${pubspec.unknownSdks}', 'unknown-sdks'));
7071
}
7172

7273
log.info("Pub upgrade...");
@@ -85,18 +86,24 @@ class PackageAnalyzer {
8586
libraryScanner = new LibraryScanner(package, pkgDir, isFlutter);
8687
} on StateError catch (e, stack) {
8788
log.severe("Could not create LibraryScanner", e, stack);
89+
issues.add(new AnalyzerIssue(
90+
AnalyzerScopes.libraryScanner, e.toString(), 'init'));
8891
}
8992

9093
if (libraryScanner != null) {
9194
try {
9295
allDirectLibs = await libraryScanner.scanDirectLibs();
9396
} catch (e, st) {
9497
log.severe('Error scanning direct librariers', e, st);
98+
issues.add(new AnalyzerIssue(
99+
AnalyzerScopes.libraryScanner, e.toString(), 'direct'));
95100
}
96101
try {
97102
allTransitiveLibs = await libraryScanner.scanTransitiveLibs();
98103
} catch (e, st) {
99104
log.severe('Error scanning transitive librariers', e, st);
105+
issues.add(new AnalyzerIssue(
106+
AnalyzerScopes.libraryScanner, e.toString(), 'transient'));
100107
}
101108
libraryScanner.clearCaches();
102109
}
@@ -108,7 +115,8 @@ class PackageAnalyzer {
108115
if (e.toString().contains("No dart files found at: .")) {
109116
log.warning("No files to analyze...");
110117
} else {
111-
rethrow;
118+
issues
119+
.add(new AnalyzerIssue(AnalyzerScopes.dartAnalyzer, e.toString()));
112120
}
113121
}
114122

@@ -148,25 +156,34 @@ class PackageAnalyzer {
148156
}
149157
}
150158

151-
return new Summary(
152-
sdkVersion, package, new Version.parse(pkgInfo.version), summary, files,
159+
return new Summary(sdkVersion, package, new Version.parse(pkgInfo.version),
160+
summary, files, issues,
153161
flutterVersion: flutterVersion);
154162
}
155163

156164
Future<Set<AnalyzerOutput>> _pkgAnalyze(String pkgPath) async {
157165
log.info('Running `dartanalyzer`...');
158166
var proc = await _dartSdk.runAnalyzer(pkgPath);
159167

168+
String output = proc.stderr;
169+
if ('\n$output'.contains('\nUnhandled exception:\n')) {
170+
log.severe("Bad input?");
171+
log.severe(output);
172+
String errorMessage =
173+
'\n$output'.split('\nUnhandled exception:\n')[1].split('\n').first;
174+
throw new ArgumentError('dartanalyzer exception: $errorMessage');
175+
}
176+
160177
try {
161178
return new SplayTreeSet.from(LineSplitter
162-
.split(proc.stderr)
179+
.split(output)
163180
.map((s) => AnalyzerOutput.parse(s, projectDir: pkgPath))
164181
.where((e) => e != null));
165182
} on ArgumentError {
166183
// TODO: we should figure out a way to succeed here, right?
167184
// Or at least do partial results and not blow up
168185
log.severe("Bad input?");
169-
log.severe(proc.stderr);
186+
log.severe(output);
170187
rethrow;
171188
}
172189
}

lib/src/pubspec.dart

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,11 @@ class Pubspec {
5656
return _dependentSdks;
5757
}
5858

59-
bool get hasUnknownSdks {
60-
Set<String> sdks = new Set.from(dependentSdks);
61-
sdks.remove('flutter');
62-
return sdks.isNotEmpty;
59+
Set<String> get unknownSdks {
60+
Set<String> unknowns = new Set.from(dependentSdks);
61+
unknowns.remove('flutter');
62+
return unknowns;
6363
}
64+
65+
bool get hasUnknownSdks => unknownSdks.isNotEmpty;
6466
}

lib/src/summary.dart

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,10 @@ class Summary {
7575
final Version packageVersion;
7676
final PubSummary pubSummary;
7777
final Map<String, DartFileSummary> dartFiles;
78+
final List<AnalyzerIssue> issues;
7879

7980
Summary(this.sdkVersion, this.packageName, this.packageVersion,
80-
this.pubSummary, this.dartFiles,
81+
this.pubSummary, this.dartFiles, this.issues,
8182
{this.flutterVersion});
8283

8384
factory Summary.fromJson(Map<String, dynamic> json) {
@@ -90,9 +91,12 @@ class Summary {
9091
Map<String, DartFileSummary> dartFiles = new SplayTreeMap.fromIterable(
9192
filesMap.keys,
9293
value: (key) => new DartFileSummary.fromJson(filesMap[key]));
94+
List issuesRaw = json['issues'];
95+
List<AnalyzerIssue> issues =
96+
issuesRaw?.map((Map map) => new AnalyzerIssue.fromJson(map))?.toList();
9397

9498
return new Summary(
95-
sdkVersion, packageName, packageVersion, pubSummary, dartFiles,
99+
sdkVersion, packageName, packageVersion, pubSummary, dartFiles, issues,
96100
flutterVersion: json['flutterVersion']);
97101
}
98102

@@ -116,6 +120,37 @@ class Summary {
116120
'dartFiles': dartFiles,
117121
});
118122

123+
if (issues != null && issues.isNotEmpty) {
124+
map['issues'] = issues;
125+
}
126+
119127
return map;
120128
}
121129
}
130+
131+
class AnalyzerIssue {
132+
final String scope;
133+
final String message;
134+
final dynamic code;
135+
136+
AnalyzerIssue(this.scope, this.message, [this.code]);
137+
138+
factory AnalyzerIssue.fromJson(Map<String, dynamic> json) =>
139+
new AnalyzerIssue(
140+
json['scope'],
141+
json['message'],
142+
json['code'],
143+
);
144+
145+
Map<String, dynamic> toJson() {
146+
var map = <String, dynamic>{'scope': scope, 'message': message};
147+
if (code != null) map['code'] = code;
148+
return map;
149+
}
150+
}
151+
152+
abstract class AnalyzerScopes {
153+
static const String pubspec = 'pubspec';
154+
static const String dartAnalyzer = 'dart-analyzer';
155+
static const String libraryScanner = 'library-scanner';
156+
}

test/end2end/http_data.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ final data = {
3030
"charcode": "1.1.1",
3131
"collection": "1.14.1",
3232
"http_parser": "3.1.1",
33-
"path": "1.4.1",
33+
"path": startsWith("1.4."),
3434
"source_span": "1.4.0",
3535
"stack_trace": "1.7.3",
3636
"string_scanner": "1.0.2",
@@ -42,7 +42,7 @@ final data = {
4242
"charcode": "1.1.1",
4343
"collection": "1.14.1",
4444
"http_parser": "3.1.1",
45-
"path": "1.4.1",
45+
"path": startsWith("1.4."),
4646
"source_span": "1.4.0",
4747
"stack_trace": "1.7.3",
4848
"string_scanner": "1.0.2",

test/end2end/pub_server_data.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ final data = {
3636
"mime": "0.9.3",
3737
"package_config": "1.0.1",
3838
"package_resolver": "1.0.2",
39-
"path": "1.4.1",
39+
"path": startsWith("1.4."),
4040
"plugin": "0.2.0",
4141
"pool": "1.3.1",
4242
"pub_semver": "1.3.2",
@@ -86,7 +86,7 @@ final data = {
8686
"mime": "0.9.3",
8787
"package_config": "1.0.1",
8888
"package_resolver": "1.0.2",
89-
"path": "1.4.1",
89+
"path": startsWith("1.4."),
9090
"plugin": "0.2.0",
9191
"pool": "1.3.1",
9292
"pub_semver": "1.3.2",

0 commit comments

Comments
 (0)