diff options
| author | Peter Bacon Darwin | 2014-03-11 06:34:09 +0000 | 
|---|---|---|
| committer | Peter Bacon Darwin | 2014-03-11 06:54:52 +0000 | 
| commit | a8aba8957be799823391168352a435fe60e3fc7d (patch) | |
| tree | 98d81337f5c88119d6b95dae7e4320c5bbfce13c | |
| parent | ca0ac649971ae4fb50419b38f92a98d2226eb696 (diff) | |
| download | angular.js-a8aba8957be799823391168352a435fe60e3fc7d.tar.bz2 | |
docs(versions): rework the version info extraction
The docs were relying on the grunt/util module for getting version info
but this was unreliable and full of custom regexes.  This is moved into
a new version-info module that makes much better use of the semver library.
| -rw-r--r-- | docs/config/processors/git-data.js | 7 | ||||
| -rw-r--r-- | docs/config/templates/indexPage.template.html | 2 | ||||
| -rw-r--r-- | docs/docs.config.js | 5 | ||||
| -rw-r--r-- | lib/versions/version-info.js | 157 | 
4 files changed, 164 insertions, 7 deletions
| diff --git a/docs/config/processors/git-data.js b/docs/config/processors/git-data.js index 229864bb..16bbef43 100644 --- a/docs/config/processors/git-data.js +++ b/docs/config/processors/git-data.js @@ -1,4 +1,5 @@  var gruntUtils = require('../../../lib/grunt/utils'); +var versionInfo = require('../../../lib/versions/version-info');  module.exports = {    name: 'git-data', @@ -6,9 +7,9 @@ module.exports = {    description: 'This processor adds information from the local git repository to the extraData injectable',    init: function(config, injectables) {      injectables.value('gitData', { -      version: gruntUtils.getVersion(), -      versions: gruntUtils.getPreviousVersions(), -      info: gruntUtils.getGitRepoInfo() +      version: versionInfo.currentVersion, +      versions: versionInfo.previousVersions, +      info: versionInfo.gitRepoInfo      });    },    process: function(extraData, gitData) { diff --git a/docs/config/templates/indexPage.template.html b/docs/config/templates/indexPage.template.html index 9582c825..0dfe6cc0 100644 --- a/docs/config/templates/indexPage.template.html +++ b/docs/config/templates/indexPage.template.html @@ -175,7 +175,7 @@          <div class="container main-grid main-header-grid">            <div class="grid-left">              <div ng-controller="DocsVersionsCtrl" class="picker version-picker"> -              <select ng-options="v as ('v' + v.full) group by (v.isStable?'Stable':'Unstable') for v in docs_versions" +              <select ng-options="v as ('v' + v.version + (v.isSnapshot ? ' (snapshot)' : '')) group by (v.isStable?'Stable':'Unstable') for v in docs_versions"                        ng-model="docs_version"                        ng-change="jumpToDocsVersion(docs_version)"                        class="docs-version-jump"> diff --git a/docs/docs.config.js b/docs/docs.config.js index 2e163254..883f80f0 100644 --- a/docs/docs.config.js +++ b/docs/docs.config.js @@ -1,13 +1,12 @@  var path = require('canonical-path'); -var gruntUtils = require('../lib/grunt/utils'); +var versionInfo = require('../lib/versions/version-info');  var basePath = __dirname;  var basePackage = require('./config');  module.exports = function(config) { -  var version = gruntUtils.getVersion(); -  var cdnUrl = "//ajax.googleapis.com/ajax/libs/angularjs/" + version.cdn; +  var cdnUrl = "//ajax.googleapis.com/ajax/libs/angularjs/" + versionInfo.currentPackage.cdnVersion;    var getVersion = function(component, sourceFolder, packageFile) {      sourceFolder = sourceFolder || '../bower_components'; diff --git a/lib/versions/version-info.js b/lib/versions/version-info.js new file mode 100644 index 00000000..588f1865 --- /dev/null +++ b/lib/versions/version-info.js @@ -0,0 +1,157 @@ +var fs = require('fs'); +var path = require('path'); +var shell = require('shelljs'); +var semver = require('semver'); +var _ = require('lodash'); + +var currentPackage, previousVersions; + + +/** + * 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 tagMessage = shell.exec('git cat-file -p '+ tagName +' | grep "codename"', {silent:true}).output; +  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; +    var version = semver.parse(tag); +    if ( version ) { +      if ( version.satisfies(currentPackage.branchVersion) ) { +        version.codeName = getCodeName(tag); +      } +      version.full = version.version + '+' + version.build; +      return version; +    } +  } +}; + +/** + * Stable versions have an even minor version and have no prerelease + * @param  {SemVer}  version The version to test + * @return {Boolean}         True if the version is stable + */ +var isStable = function(version) { +  return semver.satisfies(version, '1.0 || 1.2') && version.prerelease.length === 0; +}; + +/** + * Get a collection of all the previous versions sorted by semantic version + * @return {Array.<SemVer>} The collection of previous versions + */ +var getPreviousVersions =  function() { +  var tagResults = shell.exec('git tag', {silent: true}); +  if ( tagResults.code === 0 ) { +    return _(tagResults.output.trim().split('\n')) +      .map(function(tag) { +        var version = semver.parse(tag); +        return version; +      }) +      .filter() +      .map(function(version) { +        version.isStable = isStable(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.dot < 2 ) ) { +          version.docsUrl += '-' + version.version; +        } +        return version; +      }) +      .sort(semver.compare) +      .value(); +  } +}; + + +/** + * Get the unstable snapshot version + * @return {SemVer} The snapshot version + */ +var getSnapshotVersion = function() { + +  version = _(previousVersions) +    .filter(function(tag) { +      return semver.satisfies(tag, currentPackage.branchVersion); +    }) +    .last(); + +  // 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; +  version.prerelease = jenkinsBuild ? ['build', jenkinsBuild] : ['local']; +  version.build = getBuild(); +  version.codeName = 'snapshot'; +  version.isSnapshot = true; +  version.format(); +  version.full = version.version + '+' + version.build; + +  return version; +}; + + +exports.currentPackage = currentPackage = getPackage(); +exports.previousVersions = previousVersions = getPreviousVersions(); +exports.currentVersion = getTaggedVersion() || getSnapshotVersion(); +exports.gitRepoInfo = getGitRepoInfo(); | 
