182 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			182 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								'use strict';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var fs = require('fs');
							 | 
						||
| 
								 | 
							
								var path = require('path');
							 | 
						||
| 
								 | 
							
								var shell = require('shelljs');
							 | 
						||
| 
								 | 
							
								var semver = require('semver');
							 | 
						||
| 
								 | 
							
								var _ = require('lodash');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var currentPackage, previousVersions, gitRepoInfo;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Load information about this project from the package.json
							 | 
						||
| 
								 | 
							
								 * @return {Object} The package information
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var getPackage = function() {
							 | 
						||
| 
								 | 
							
								  // Search up the folder hierarchy for the first package.json
							 | 
						||
| 
								 | 
							
								  var packageFolder = path.resolve('.');
							 | 
						||
| 
								 | 
							
								  while (!fs.existsSync(path.join(packageFolder, 'package.json'))) {
							 | 
						||
| 
								 | 
							
								    var parent = path.dirname(packageFolder);
							 | 
						||
| 
								 | 
							
								    if (parent === packageFolder) { break; }
							 | 
						||
| 
								 | 
							
								    packageFolder = parent;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return JSON.parse(fs.readFileSync(path.join(packageFolder,'package.json'), 'UTF-8'));
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Parse the github URL for useful information
							 | 
						||
| 
								 | 
							
								 * @return {Object} An object containing the github owner and repository name
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var getGitRepoInfo = function() {
							 | 
						||
| 
								 | 
							
								  var GITURL_REGEX = /^https:\/\/github.com\/([^\/]+)\/(.+).git$/;
							 | 
						||
| 
								 | 
							
								  var match = GITURL_REGEX.exec(currentPackage.repository.url);
							 | 
						||
| 
								 | 
							
								  var git = {
							 | 
						||
| 
								 | 
							
								    owner: match[1],
							 | 
						||
| 
								 | 
							
								    repo: match[2]
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								  return git;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Extract the code name from the tagged commit's message - it should contain the text of the form:
							 | 
						||
| 
								 | 
							
								 * "codename(some-code-name)"
							 | 
						||
| 
								 | 
							
								 * @param  {String} tagName Name of the tag to look in for the codename
							 | 
						||
| 
								 | 
							
								 * @return {String}         The codename if found, otherwise null/undefined
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var getCodeName = function(tagName) {
							 | 
						||
| 
								 | 
							
								  var gitCatOutput = shell.exec('git cat-file -p ' + tagName, {silent:true}).output;
							 | 
						||
| 
								 | 
							
								  var tagMessage = gitCatOutput.match(/^.*codename.*$/mg)[0];
							 | 
						||
| 
								 | 
							
								  var codeName = tagMessage && tagMessage.match(/codename\((.*)\)/)[1];
							 | 
						||
| 
								 | 
							
								  if (!codeName) {
							 | 
						||
| 
								 | 
							
								    throw new Error("Could not extract release code name. The message of tag " + tagName +
							 | 
						||
| 
								 | 
							
								      " must match '*codename(some release name)*'");
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return codeName;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Compute a build segment for the version, from the Jenkins build number and current commit SHA
							 | 
						||
| 
								 | 
							
								 * @return {String} The build segment of the version
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function getBuild() {
							 | 
						||
| 
								 | 
							
								  var hash = shell.exec('git rev-parse --short HEAD', {silent: true}).output.replace('\n', '');
							 | 
						||
| 
								 | 
							
								  return 'sha.' + hash;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * If the current commit is tagged as a version get that version
							 | 
						||
| 
								 | 
							
								 * @return {SemVer} The version or null
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var getTaggedVersion = function() {
							 | 
						||
| 
								 | 
							
								  var gitTagResult = shell.exec('git describe --exact-match', {silent:true});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (gitTagResult.code === 0) {
							 | 
						||
| 
								 | 
							
								    var tag = gitTagResult.output.trim();
							 | 
						||
| 
								 | 
							
								    var version = semver.parse(tag);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (version && semver.satisfies(version, currentPackage.version)) {
							 | 
						||
| 
								 | 
							
								      version.codeName = getCodeName(tag);
							 | 
						||
| 
								 | 
							
								      version.full = version.version;
							 | 
						||
| 
								 | 
							
								      version.branch = 'v' + currentPackage.branchPattern.replace('*', 'x');
							 | 
						||
| 
								 | 
							
								      return version;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return null;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Get a collection of all the previous versions sorted by semantic version
							 | 
						||
| 
								 | 
							
								 * @return {Array.<SemVer>} The collection of previous versions
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var getPreviousVersions =  function() {
							 | 
						||
| 
								 | 
							
								  // always use the remote tags as the local clone might
							 | 
						||
| 
								 | 
							
								  // not contain all commits when cloned with git clone --depth=...
							 | 
						||
| 
								 | 
							
								  // Needed e.g. for Travis
							 | 
						||
| 
								 | 
							
								  var repo_url = currentPackage.repository.url;
							 | 
						||
| 
								 | 
							
								  var tagResults = shell.exec('git ls-remote --tags ' + repo_url,
							 | 
						||
| 
								 | 
							
								                              {silent: true});
							 | 
						||
| 
								 | 
							
								  if (tagResults.code === 0) {
							 | 
						||
| 
								 | 
							
								    return _(tagResults.output.match(/v[0-9].*[0-9]$/mg))
							 | 
						||
| 
								 | 
							
								      .map(function(tag) {
							 | 
						||
| 
								 | 
							
								        var version = semver.parse(tag);
							 | 
						||
| 
								 | 
							
								        return version;
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								      .filter()
							 | 
						||
| 
								 | 
							
								      .map(function(version) {
							 | 
						||
| 
								 | 
							
								        // angular.js didn't follow semantic version until 1.20rc1
							 | 
						||
| 
								 | 
							
								        if ((version.major === 1 && version.minor === 0 && version.prerelease.length > 0) || (version.major === 1 && version.minor === 2 && version.prerelease[0] === 'rc1')) {
							 | 
						||
| 
								 | 
							
								          version.version = [version.major, version.minor, version.patch].join('.') + version.prerelease.join('');
							 | 
						||
| 
								 | 
							
								          version.raw = 'v' + version.version;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        version.docsUrl = 'http://code.angularjs.org/' + version.version + '/docs';
							 | 
						||
| 
								 | 
							
								        // Versions before 1.0.2 had a different docs folder name
							 | 
						||
| 
								 | 
							
								        if (version.major < 1 || (version.major === 1 && version.minor === 0 && version.patch < 2)) {
							 | 
						||
| 
								 | 
							
								          version.docsUrl += '-' + version.version;
							 | 
						||
| 
								 | 
							
								          version.isOldDocsUrl = true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return version;
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								      .sort(semver.compare)
							 | 
						||
| 
								 | 
							
								      .value();
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    return [];
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Get the unstable snapshot version
							 | 
						||
| 
								 | 
							
								 * @return {SemVer} The snapshot version
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var getSnapshotVersion = function() {
							 | 
						||
| 
								 | 
							
								  var version = _(previousVersions)
							 | 
						||
| 
								 | 
							
								    .filter(function(tag) {
							 | 
						||
| 
								 | 
							
								      return semver.satisfies(tag, currentPackage.version);
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								    .last();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!version) {
							 | 
						||
| 
								 | 
							
								    // a snapshot version before the first tag on the branch
							 | 
						||
| 
								 | 
							
								    version = semver(currentPackage.branchPattern.replace('*','0-alpha.1'));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // We need to clone to ensure that we are not modifying another version
							 | 
						||
| 
								 | 
							
								  version = semver(version.raw);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var jenkinsBuild = process.env.TRAVIS_BUILD_NUMBER || process.env.BUILD_NUMBER;
							 | 
						||
| 
								 | 
							
								  if (!version.prerelease || !version.prerelease.length) {
							 | 
						||
| 
								 | 
							
								    // last release was a non beta release. Increment the patch level to
							 | 
						||
| 
								 | 
							
								    // indicate the next release that we will be doing.
							 | 
						||
| 
								 | 
							
								    // E.g. last release was 1.3.0, then the snapshot will be
							 | 
						||
| 
								 | 
							
								    // 1.3.1-build.1, which is lesser than 1.3.1 accorind the semver!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // If the last release was a beta release we don't update the
							 | 
						||
| 
								 | 
							
								    // beta number by purpose, as otherwise the semver comparison
							 | 
						||
| 
								 | 
							
								    // does not work any more when the next beta is released.
							 | 
						||
| 
								 | 
							
								    // E.g. don't generate 1.3.0-beta.2.build.1
							 | 
						||
| 
								 | 
							
								    // as this is bigger than 1.3.0-beta.2 according to semver
							 | 
						||
| 
								 | 
							
								    version.patch++;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  version.prerelease = jenkinsBuild ? ['build', jenkinsBuild] : ['local'];
							 | 
						||
| 
								 | 
							
								  version.build = getBuild();
							 | 
						||
| 
								 | 
							
								  version.codeName = 'snapshot';
							 | 
						||
| 
								 | 
							
								  version.isSnapshot = true;
							 | 
						||
| 
								 | 
							
								  version.format();
							 | 
						||
| 
								 | 
							
								  version.full = version.version + '+' + version.build;
							 | 
						||
| 
								 | 
							
								  version.branch = 'master';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return version;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.currentPackage = currentPackage = getPackage();
							 | 
						||
| 
								 | 
							
								exports.gitRepoInfo = gitRepoInfo = getGitRepoInfo();
							 | 
						||
| 
								 | 
							
								exports.previousVersions = previousVersions = getPreviousVersions();
							 | 
						||
| 
								 | 
							
								exports.currentVersion = getTaggedVersion() || getSnapshotVersion();
							 |