grunt-nexus-deployer
Version:
Deploy artifacts with classifiers to release/snapshot maven repository.
187 lines (153 loc) • 7.1 kB
JavaScript
;
var handlebars = require('handlebars')
, exec
, dateformat = require('dateformat')
, crypto = require('crypto')
, async = require('async')
, grunt = require('grunt')
, fs = require('fs')
, mkdirp = require('mkdirp')
, file = grunt.file
, log = grunt.log;
var cwd = __dirname;
var createFile = function (template, options) {
var outerMetadata = file.read(cwd + '/../template/' + template);
var template = handlebars.compile(outerMetadata);
var metadata = template(options);
return metadata;
};
var md5 = function (str) {
var hash = crypto.createHash('md5');
return hash.update(str).digest('hex');
};
var sha1 = function (str) {
var hash = crypto.createHash('sha1');
return hash.update(str).digest('hex');
};
var save = function (fileContent, pomDir, fileName) {
file.write(pomDir + '/' + fileName, fileContent);
file.write(pomDir + '/' + fileName + '.md5', md5(fileContent));
file.write(pomDir + '/' + fileName + '.sha1', sha1(fileContent));
};
var directoryExists = function(dir) {
try {
return fs.statSync(dir).isDirectory();
} catch (e) {
// error is thrown by statSync when path does not exist
if (e.code === 'ENOENT') {
return false
}
throw e;
}
};
var isFunction = function(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
};
var createAndUploadArtifacts = function (options, done) {
var pomDir = options.pomDir || 'test/poms';
options.parallel = options.parallel === undefined ? false : options.parallel;
if (!directoryExists(pomDir)) {
mkdirp(pomDir);
}
save(createFile('project-metadata.xml', options), pomDir, 'outer.xml');
save(createFile('latest-metadata.xml', options), pomDir, 'inner.xml');
save(createFile('pom.xml', options), pomDir, 'pom.xml');
var artifact = isFunction(options.artifact) ? options.artifact() : options.artifact;
var artifactData = file.read(artifact, {encoding: null});
file.write(pomDir + '/artifact.' + options.packaging + '.md5', md5(artifactData));
file.write(pomDir + '/artifact.' + options.packaging + '.sha1', sha1(artifactData));
var upload = function (fileLocation, targetFile) {
var uploadArtifact = function (cb) {
var targetUri = options.url + '/' + targetFile, status;
if (!options.quiet) {
log.write('Uploading to ' + targetUri + "\n\n");
}
var curlOptions = [
'--silent',
'--fail',
'--show-error',
'--write-out', '"%{http_code}"',
'--upload-file', fileLocation,
'--noproxy', options.noproxy ? options.noproxy : '127.0.0.1'
];
if (options.auth) {
curlOptions.push('-u');
var authString = options.auth.username + ':' + options.auth.password;
authString.replace(/'/g, '\\\'');
curlOptions.push("\"" + authString + "\"");
}
if (options.insecure) {
curlOptions.push('--insecure');
}
var execOptions = {};
options.cwd && (execOptions.cwd = options.cwd);
var curlCmd = ['curl', curlOptions.join(' '), targetUri].join(' ');
var childProcess = exec(curlCmd, execOptions, function (error) {
if (error) {
log.error(error);
}
});
childProcess.stdout.on('data', function (data) {
status = data;
});
childProcess.on('close', function (code) {
if (code !== 0 || (status !== "200" && status !== "201" && status !== "202")) {
cb("Status code " + status + " for " + targetUri, null);
} else {
cb(null, "Ok");
}
});
};
return uploadArtifact;
};
var uploads = {};
var groupIdAsPath = options.groupId.replace(/\./g, "/");
var groupArtifactPath = groupIdAsPath + '/' + options.artifactId;
uploads[pomDir + "/outer.xml"] = groupArtifactPath + '/' + 'maven-metadata.xml';
uploads[pomDir + "/outer.xml.sha1"] = groupArtifactPath + '/' + 'maven-metadata.xml.sha1';
uploads[pomDir + "/outer.xml.md5"] = groupArtifactPath + '/' + 'maven-metadata.xml.md5';
var SNAPSHOT_VER = /.*SNAPSHOT$/i;
var version = isFunction(options.version) ? options.version() : options.version;
var groupArtifactVersionPath = groupArtifactPath + '/' + version;
if (SNAPSHOT_VER.test(version)) {
uploads[pomDir + "/inner.xml"] = groupArtifactVersionPath + '/' + 'maven-metadata.xml';
uploads[pomDir + "/inner.xml.sha1"] = groupArtifactVersionPath + '/' + 'maven-metadata.xml.sha1';
uploads[pomDir + "/inner.xml.md5"] = groupArtifactVersionPath + '/' + 'maven-metadata.xml.md5';
}
var remoteArtifactName = options.artifactId + '-' + version;
uploads[pomDir + "/pom.xml"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.pom';
uploads[pomDir + "/pom.xml.sha1"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.pom.sha1';
uploads[pomDir + "/pom.xml.md5"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.pom.md5';
if(options.classifier) {
remoteArtifactName = remoteArtifactName + "-" + options.classifier;
}
uploads[artifact] = groupArtifactVersionPath + '/' + remoteArtifactName + '.' + options.packaging;
uploads[pomDir + "/artifact." + options.packaging + ".sha1"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.' + options.packaging + '.sha1';
uploads[pomDir + "/artifact." + options.packaging + ".md5"] = groupArtifactVersionPath + '/' + remoteArtifactName + '.' + options.packaging + '.md5';
var fns = [];
for (var u in uploads) {
if (uploads.hasOwnProperty(u)) {
fns.push(upload(u, uploads[u]));
}
}
var asyncFn = options.parallel ? async.parallel : async.series;
asyncFn(fns, function (err) {
if (!options.quiet) {
log.write('-------------------------------------------\n');
if (err) {
log.error('Artifact Upload failed\n' + String(err));
} else {
log.ok('Artifacts uploaded successfully');
}
}
done(err ? false : true);
});
};
module.exports = function (options, cb) {
if (!options) {
throw {name: "IllegalArgumentException", message: "upload artifact options required."};
}
exec = process.env.MOCK_NEXUS ? require('./mockexec') : require('child_process').exec;
options.lastUpdated = process.env.MOCK_NEXUS ? '11111111111111': dateformat(new Date(), "yyyymmddHHMMss", true);
createAndUploadArtifacts(options, cb);
};