anchor.diff:  
     print('Copy and paste this into your console:\n');
     print('open http://localhost:7334');
  -  print(
  -      'dart --pause-isolates-on-exit --enable-vm-service=7334 --profile bin/dartdoc.dart --output ${DOCS_DIR.path}');
  +  print('dart --pause-isolates-on-exit --enable-vm-service=7334 '
  +      '--profile bin/dartdoc.dart --output ${docsDir.path}');
   }
   
   @Task('publish to pub.dartlang')
   @Depends(bumpVersionBuild)
  -publish(GrinderContext context) async {
  +publish() async {
     Dart.run('pub', arguments: ['publish']);
   }
   
   @Task('Bump pubspec version and version number in lib/dartdoc.dart')
  -bumpVersionBuild(GrinderContext context) async {
  +bumpVersionBuild() async {
     Pubspec pubspec = (await Pubspec.load())
       ..bump(ReleaseType.build)
       ..save();
   
     var libCode = new File('lib/dartdoc.dart');
     if (!libCode.existsSync()) {
  -    stderr.write('Cannot find lib/dartdoc.dart');
  -    exit(1);
  +    fail('Cannot find lib/dartdoc.dart');
     }
     String libCodeContents = libCode.readAsStringSync();
     libCodeContents = libCodeContents.replaceFirst(
  
positive.code:       "const String VERSION = '${pubspec.version}';");
    libCode.writeAsString(libCodeContents);
  
    context.log('Version set to ${pubspec.version}');
  }
  
  @Task('Generate docs for dartdoc')
  testDartdoc(GrinderContext context) {
    if (DOCS_DIR.existsSync()) DOCS_DIR.deleteSync(recursive: true);
  
    try {
      context.log('running dartdoc');
      Dart.run('bin/dartdoc.dart', arguments: ['--output', '${DOCS_DIR.path}']);
  
      File indexHtml = joinFile(DOCS_DIR, ['index.html']);
      if (!indexHtml.existsSync()) context.fail('docs not generated');
      File docFile = joinFile(DOCS_DIR, ['dartdoc/index.html']);
      if (!docFile.existsSync()) context.fail('docs not generated');
    } catch (e) {
      rethrow;
    }
  }
  
  @Task('Analyze dartdoc to ensure there are no errors and warnings')
  analyze(GrinderContext context) {
    Analyzer.analyzeFiles(
        ['bin/dartdoc.dart', 'lib/dartdoc.dart', 'test/all.dart'],
        fatalWarnings: true);
  }
  
  @Task('Generate docs for the Dart SDK')
  Future buildSdkDocs(GrinderContext context) async {
    if (DOCS_DIR.existsSync()) DOCS_DIR.deleteSync(recursive: true);
    context.log('building SDK docs');
    try {
      int sdkDocsGenTime = _runTimed(() {
        Dart.run('bin/dartdoc.dart',
            arguments: ['--output', '${DOCS_DIR.path}', '--sdk-docs']);
      });
      var indexHtml = joinFile(DOCS_DIR, ['index.html']);
      if (!indexHtml.existsSync()) {
        context.fail('no index.html found for SDK docs');
      }
      // check for the existance of certain files/dirs
      var libsLength =
          DOCS_DIR.listSync().where((fs) => fs.path.contains('dart_')).length;
      if (libsLength != 17) {
        context.fail(
            'docs not generated for all the SDK libraries, expected 17 directories, generated $libsLength directories');
      }
      var futureConstFile = joinFile(DOCS_DIR, ['dart_async/Future/Future.html']);
      if (!futureConstFile.existsSync()) {
        context.fail('no Future.html found for dart:async Future constructor');
      }
  
      return _uploadStats(context, sdkDocsGenTime);
    } catch (e) {
      rethrow;
    }
  }
  
  @Task('Make sure all the resource files are present')
  indexResources(GrinderContext context) {
    var sourcePath = path.join('lib', 'resources');
    if (!new Directory(sourcePath).existsSync()) {
      throw new StateError('lib/resources directory not found');
  
negative.code:         description: 'Commit ${commit}', links: [link]);
      return librato.createAnnotation('build_ui', annotation);
    } else {
      return new Future.value();
    }
  }
  