anchor.diff:    print("polymer build done");
   }
   
  +// Transpile dart sources to JS.
  +// It will create spark.html_bootstrap.dart.precompiled.js.
   void dart2JSBuild(GrinderContext context) {
     // We remove the symlink and replace it with a copy.
     runCommandSync(context, 'rm -rf web/packages');
  
positive.code:       joinDir(Directory.current, ['app', 'packages']));
  }
  
  void prepareBuild(GrinderContext context) {
    context.log('prepare build');
    // Copy files to build directory.
  
negative.code:   context.log("Created ${filename}");
  }
  
  // Increase the build number in the manifest.json file. Returns the full
  // version.
  String increaseBuildNumber(GrinderContext context) {
    // Tweaking build version in manifest.
    File file = new File('app/manifest.json');
    String content = file.readAsStringSync();
    Object manifestDict = JSON.decode(content);
    String version = manifestDict['version'];
    RegExp exp = new RegExp(r"(\d+\.\d+)\.(\d+)");
    Iterable<Match> matches = exp.allMatches(version);
    assert(matches.length > 0);
  
    Match m = matches.first;
    String majorVersion = m.group(1);
    int buildVersion = int.parse(m.group(2));
    buildVersion ++;
  
    version = '${majorVersion}.${buildVersion}';
    manifestDict['version'] = version;
    file.writeAsStringSync(JSON.encode(manifestDict));
  
    // It needs to be copied to compile result directory.
    copyFile(
        joinFile(Directory.current, ['app', 'manifest.json']),
        joinDir(Directory.current, ['build', 'polymer-build', 'web']));
    return version;
  }
  
  // Creates a release build to be uploaded to Chrome Web Store.
  // It will perform the following steps:
  // - Sources will be compiled in Javascript using "compile" task
  // - If the current branch/repo is not releasable, we just create an archive
  //   tagged with a revision number.
  // - Using increaseBuildNumber, for a given revision number a.b.c where a, b
  //   and c are integers, we increase c, the build number and write it to the
  //   manifest.json file.
  // - We duplicate the manifest.json file to build/polymer-build/web since we'll
  //   create the Chrome App from here.
  // - "archive" task will create a spark.zip file in dist/, based on the content
  //   of build/polymer-build/web.
  // - If everything is successful and no exception interrupted the process,
  //   we'll commit the new manifest.json containing the updated version number
  //   to the repository. The developer still needs to push it to the remote
  //   repository.
  // - We eventually rename dist/spark.zip to dist/spark-a.b.c.zip to reflect the
  //   new version number.
  //
  void release(GrinderContext context) {
    // If repository is not original repository of Spark and the branch is not
    // master.
    if (!canReleaseFromHere()) {
      archiveWithRevision(context);
      return;
    }
  
    String version = increaseBuildNumber(context);
    // Creating an archive of the Chrome App.
    context.log('Creating build ${version}');
  
    archive(context);
  
    runCommandSync(
      context,
      'git commit -m "Build version ${version}" app/manifest.json');
    File file = new File('dist/spark.zip');
    String filename = 'spark-${version}.zip';
    file.renameSync('dist/${filename}');
    context.log('Created ${filename}');
    context.log('** A commit has been created, you need to push it. ***');
  }
  