|
| 1 | +var fs = require('fs'); |
| 2 | +var path = require('path'); |
| 3 | +var shell = require('shelljs'); |
| 4 | +var semver = require('semver'); |
| 5 | +var _ = require('lodash'); |
| 6 | + |
| 7 | +var currentPackage, previousVersions; |
| 8 | + |
| 9 | + |
| 10 | +/** |
| 11 | + * Load information about this project from the package.json |
| 12 | + * @return {Object} The package information |
| 13 | + */ |
| 14 | +var getPackage = function() { |
| 15 | + // Search up the folder hierarchy for the first package.json |
| 16 | + var packageFolder = path.resolve('.'); |
| 17 | + while ( !fs.existsSync(path.join(packageFolder, 'package.json')) ) { |
| 18 | + var parent = path.dirname(packageFolder); |
| 19 | + if ( parent === packageFolder) { break; } |
| 20 | + packageFolder = parent; |
| 21 | + } |
| 22 | + return JSON.parse(fs.readFileSync(path.join(packageFolder,'package.json'), 'UTF-8')); |
| 23 | +}; |
| 24 | + |
| 25 | + |
| 26 | +/** |
| 27 | + * Parse the github URL for useful information |
| 28 | + * @return {Object} An object containing the github owner and repository name |
| 29 | + */ |
| 30 | +var getGitRepoInfo = function() { |
| 31 | + var GITURL_REGEX = /^https:\/\/github.com\/([^\/]+)\/(.+).git$/; |
| 32 | + var match = GITURL_REGEX.exec(currentPackage.repository.url); |
| 33 | + var git = { |
| 34 | + owner: match[1], |
| 35 | + repo: match[2] |
| 36 | + }; |
| 37 | + return git; |
| 38 | +}; |
| 39 | + |
| 40 | + |
| 41 | + |
| 42 | +/** |
| 43 | + * Extract the code name from the tagged commit's message - it should contain the text of the form: |
| 44 | + * "codename(some-code-name)" |
| 45 | + * @param {String} tagName Name of the tag to look in for the codename |
| 46 | + * @return {String} The codename if found, otherwise null/undefined |
| 47 | + */ |
| 48 | +var getCodeName = function(tagName) { |
| 49 | + var tagMessage = shell.exec('git cat-file -p '+ tagName +' | grep "codename"', {silent:true}).output; |
| 50 | + var codeName = tagMessage && tagMessage.match(/codename\((.*)\)/)[1]; |
| 51 | + if (!codeName) { |
| 52 | + throw new Error("Could not extract release code name. The message of tag "+tagName+ |
| 53 | + " must match '*codename(some release name)*'"); |
| 54 | + } |
| 55 | + return codeName; |
| 56 | +}; |
| 57 | + |
| 58 | + |
| 59 | +/** |
| 60 | + * Compute a build segment for the version, from the Jenkins build number and current commit SHA |
| 61 | + * @return {String} The build segment of the version |
| 62 | + */ |
| 63 | +function getBuild() { |
| 64 | + var hash = shell.exec('git rev-parse --short HEAD', {silent: true}).output.replace('\n', ''); |
| 65 | + return 'sha.'+hash; |
| 66 | +} |
| 67 | + |
| 68 | + |
| 69 | +/** |
| 70 | + * If the current commit is tagged as a version get that version |
| 71 | + * @return {SemVer} The version or null |
| 72 | + */ |
| 73 | +var getTaggedVersion = function() { |
| 74 | + var gitTagResult = shell.exec('git describe --exact-match', {silent:true}); |
| 75 | + |
| 76 | + if ( gitTagResult.code === 0 ) { |
| 77 | + var tag = gitTagResult.output; |
| 78 | + var version = semver.parse(tag); |
| 79 | + if ( version ) { |
| 80 | + if ( version.satisfies(currentPackage.branchVersion) ) { |
| 81 | + version.codeName = getCodeName(tag); |
| 82 | + } |
| 83 | + version.full = version.version + '+' + version.build; |
| 84 | + return version; |
| 85 | + } |
| 86 | + } |
| 87 | +}; |
| 88 | + |
| 89 | +/** |
| 90 | + * Stable versions have an even minor version and have no prerelease |
| 91 | + * @param {SemVer} version The version to test |
| 92 | + * @return {Boolean} True if the version is stable |
| 93 | + */ |
| 94 | +var isStable = function(version) { |
| 95 | + return semver.satisfies(version, '1.0 || 1.2') && version.prerelease.length === 0; |
| 96 | +}; |
| 97 | + |
| 98 | +/** |
| 99 | + * Get a collection of all the previous versions sorted by semantic version |
| 100 | + * @return {Array.<SemVer>} The collection of previous versions |
| 101 | + */ |
| 102 | +var getPreviousVersions = function() { |
| 103 | + var tagResults = shell.exec('git tag', {silent: true}); |
| 104 | + if ( tagResults.code === 0 ) { |
| 105 | + return _(tagResults.output.trim().split('\n')) |
| 106 | + .map(function(tag) { |
| 107 | + var version = semver.parse(tag); |
| 108 | + return version; |
| 109 | + }) |
| 110 | + .filter() |
| 111 | + .map(function(version) { |
| 112 | + version.isStable = isStable(version); |
| 113 | + |
| 114 | + version.docsUrl = 'http://code.angularjs.org/' + version.version + '/docs'; |
| 115 | + // Versions before 1.0.2 had a different docs folder name |
| 116 | + if ( version.major < 1 || (version.major === 1 && version.minor === 0 && version.dot < 2 ) ) { |
| 117 | + version.docsUrl += '-' + version.version; |
| 118 | + } |
| 119 | + return version; |
| 120 | + }) |
| 121 | + .sort(semver.compare) |
| 122 | + .value(); |
| 123 | + } |
| 124 | +}; |
| 125 | + |
| 126 | + |
| 127 | +/** |
| 128 | + * Get the unstable snapshot version |
| 129 | + * @return {SemVer} The snapshot version |
| 130 | + */ |
| 131 | +var getSnapshotVersion = function() { |
| 132 | + |
| 133 | + version = _(previousVersions) |
| 134 | + .filter(function(tag) { |
| 135 | + return semver.satisfies(tag, currentPackage.branchVersion); |
| 136 | + }) |
| 137 | + .last(); |
| 138 | + |
| 139 | + // We need to clone to ensure that we are not modifying another version |
| 140 | + version = semver(version.raw); |
| 141 | + |
| 142 | + var jenkinsBuild = process.env.TRAVIS_BUILD_NUMBER || process.env.BUILD_NUMBER; |
| 143 | + version.prerelease = jenkinsBuild ? ['build', jenkinsBuild] : ['local']; |
| 144 | + version.build = getBuild(); |
| 145 | + version.codeName = 'snapshot'; |
| 146 | + version.isSnapshot = true; |
| 147 | + version.format(); |
| 148 | + version.full = version.version + '+' + version.build; |
| 149 | + |
| 150 | + return version; |
| 151 | +}; |
| 152 | + |
| 153 | + |
| 154 | +exports.currentPackage = currentPackage = getPackage(); |
| 155 | +exports.previousVersions = previousVersions = getPreviousVersions(); |
| 156 | +exports.currentVersion = getTaggedVersion() || getSnapshotVersion(); |
| 157 | +exports.gitRepoInfo = getGitRepoInfo(); |
0 commit comments