Skip to content

Instantly share code, notes, and snippets.

@blalor
Created October 4, 2013 02:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blalor/6820261 to your computer and use it in GitHub Desktop.
Save blalor/6820261 to your computer and use it in GitHub Desktop.
Grunt task to update a Node.js dependency referenced by git URL.
/* jshint -W064 */
"use strict";
var path = require("path");
var url = require("url");
var assert = require("assert");
var semver = require("semver");
var Q = require("q");
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON("package.json"),
});
// use version if specified
grunt.registerTask("update-deployer-dep", "update hubot-deployer dependency to the latest tag", function(newVer) {
var DEP_NAME = "hubot-deployer";
var nowrite = grunt.option("no-write");
var pkg = grunt.config.get("pkg");
var gitDepUrl = url.parse(pkg.dependencies[DEP_NAME]);
// sanity check; should be "git+ssh:" or "git+http(s):"
assert(gitDepUrl.protocol.indexOf("git+") === 0, "unexpected protocol " + gitDepUrl.protocol);
var oldVer = gitDepUrl.hash.substr(2);
grunt.log.writeln("Existing version of " + DEP_NAME + " is " + oldVer);
var done = this.async();
var newVerPromise;
if (newVer) {
newVerPromise = Q(newVer);
} else {
// need to remove the hash in order for "git ls-remote" to work
delete gitDepUrl.hash;
// strip off "git+"
var gitRemoteUrl = url.format(gitDepUrl).substr(4);
grunt.log.writeln((nowrite ? "Not " :"") + "Retrieving tags from " + gitRemoteUrl);
if (nowrite) {
newVerPromise = Q(oldVer);
} else {
// find published tags
newVerPromise = Q
.ninvoke(grunt.util, "spawn", {
cmd: "git",
args: [
"ls-remote",
"--tags",
gitRemoteUrl
]
})
.spread(function(result) {
var versions = [];
// stdout is lines of the form "sha<tab>refs/tags/v0.0.3", plus
// some other stuff. Just strip off the semantic version from
// the tag. Assume we're using "v<version>" format.
result.stdout.split("\n").forEach(function(line) {
if (line.match(/v(\d+\.?){2,3}$/)) {
versions.push(line.split("/v")[1]);
}
});
// sort versions in descending order
versions.sort(semver.rcompare);
return versions[0];
});
}
}
newVerPromise
.then(function(newVer) {
// replace the hash in the parsed url
gitDepUrl.hash = "#v" + newVer;
// regenerate the dependency version
pkg.dependencies[DEP_NAME] = url.format(gitDepUrl);
grunt.file.write(
path.resolve("package.json"),
JSON.stringify(pkg, null, " ") + "\n"
);
grunt.log.ok("Set version of " + DEP_NAME + " to " + newVer);
})
.done(done, done);
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment