blob: 72f65d1b3249e1630c79d4f2897e98e65b7b7748 [file] [log] [blame]
// Copyright (c) 2012, 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.
library validator;
import 'dart:async';
import 'entrypoint.dart';
import 'log.dart' as log;
import 'io.dart';
import 'system_cache.dart';
import 'utils.dart';
import 'validator/compiled_dartdoc.dart';
import 'validator/dependency.dart';
import 'validator/directory.dart';
import 'validator/lib.dart';
import 'validator/license.dart';
import 'validator/name.dart';
import 'validator/pubspec_field.dart';
import 'validator/size.dart';
import 'validator/utf8_readme.dart';
/// The base class for validators that check whether a package is fit for
/// uploading. Each validator should override [errors], [warnings], or both to
/// return lists of errors or warnings to display to the user. Errors will cause
/// the package not to be uploaded; warnings will require the user to confirm
/// the upload.
abstract class Validator {
/// The entrypoint that's being validated.
final Entrypoint entrypoint;
/// The accumulated errors for this validator. Filled by calling [validate].
final errors = <String>[];
/// The accumulated warnings for this validator. Filled by calling [validate].
final warnings = <String>[];
Validator(this.entrypoint);
/// Validates the entrypoint, adding any errors and warnings to [errors] and
/// [warnings], respectively.
Future validate();
/// Run all validators on the [entrypoint] package and print their results.
/// The future will complete with the error and warning messages,
/// respectively.
///
/// [packageSize], if passed, should complete to the size of the tarred
/// package, in bytes. This is used to validate that it's not too big to
/// upload to the server.
static Future<Pair<List<String>, List<String>>> runAll(
Entrypoint entrypoint, [Future<int> packageSize]) {
var validators = [
new LibValidator(entrypoint),
new LicenseValidator(entrypoint),
new NameValidator(entrypoint),
new PubspecFieldValidator(entrypoint),
new DependencyValidator(entrypoint),
new DirectoryValidator(entrypoint),
new CompiledDartdocValidator(entrypoint),
new Utf8ReadmeValidator(entrypoint)
];
if (packageSize != null) {
validators.add(new SizeValidator(entrypoint, packageSize));
}
return Future.wait(validators.map((validator) => validator.validate()))
.then((_) {
var errors =
flatten(validators.map((validator) => validator.errors));
var warnings =
flatten(validators.map((validator) => validator.warnings));
if (!errors.isEmpty) {
log.error("Missing requirements:");
for (var error in errors) {
log.error("* ${Strings.join(error.split('\n'), '\n ')}");
}
log.error("");
}
if (!warnings.isEmpty) {
log.warning("Suggestions:");
for (var warning in warnings) {
log.warning("* ${Strings.join(warning.split('\n'), '\n ')}");
}
log.warning("");
}
return new Pair<List<String>, List<String>>(errors, warnings);
});
}
}