diff options
| author | Peter Bacon Darwin | 2014-03-11 06:34:09 +0000 |
|---|---|---|
| committer | Peter Bacon Darwin | 2014-03-11 06:35:19 +0000 |
| commit | 11c5bb7f3de13722a84c5503129097393056061e (patch) | |
| tree | af646817f443eead6d6f0fd3259363aba200bdd3 | |
| parent | d6419d0aff4194675ed816f74eb688070ba45285 (diff) | |
| download | angular.js-11c5bb7f3de13722a84c5503129097393056061e.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 8b297cda..b5ec7122 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(); |
