From c519c720c53e4e068541db1b52984e959d7d3da3 Mon Sep 17 00:00:00 2001 From: Alisdair McDiarmid Date: Tue, 11 Aug 2015 00:38:48 +0100 Subject: [PATCH] Add key generators: git-tag-commit, version-commit Git Tag Commit constructs a revision key from the git tag and commit hash. Version Commit is similar, but uses the package version instead of the tag. --- README.md | 19 ++++ index.js | 1 + lib/key-generators/git-tag-commit.js | 23 ++++ lib/key-generators/index.js | 4 +- lib/key-generators/version-commit.js | 37 +++++++ package.json | 3 +- tests/fixtures/not-a-repo/package.json | 3 + tests/fixtures/repo/dotgit/HEAD | 1 + tests/fixtures/repo/dotgit/config | 7 ++ tests/fixtures/repo/dotgit/index | Bin 0 -> 225 bytes .../41/d41f081b45ad50935c08b1203220737d9739b4 | 2 + .../77/06f9e51d51a2f357b2c2078cdd04e4acf48f93 | Bin 0 -> 41 bytes .../a5/10e8069cc7eaa8b8262a9c071a702fbd52dbea | Bin 0 -> 41 bytes .../d4/6bba1991f218165a93efe79024e16da2a213fc | Bin 0 -> 89 bytes tests/fixtures/repo/dotgit/refs/heads/master | 1 + tests/fixtures/repo/dotgit/refs/tags/2.3.4 | 1 + tests/fixtures/repo/package.json | 3 + tests/fixtures/repo/version.json | 3 + tests/fixtures/tagless-repo/dotgit/HEAD | 1 + tests/fixtures/tagless-repo/dotgit/config | 7 ++ tests/fixtures/tagless-repo/dotgit/index | Bin 0 -> 145 bytes .../5e/29d0ad64c0132a1fc27416a0af2c05511c3e99 | Bin 0 -> 57 bytes .../77/06f9e51d51a2f357b2c2078cdd04e4acf48f93 | Bin 0 -> 41 bytes .../91/38ef996f3c7680aedcba68b0371d828b6dbb0b | 2 + .../tagless-repo/dotgit/refs/heads/master | 1 + tests/fixtures/tagless-repo/package.json | 3 + tests/unit/index-nodetest.js | 2 +- .../key-generators/git-tag-commit-nodetest.js | 57 ++++++++++ .../key-generators/version-commit-nodetest.js | 101 ++++++++++++++++++ 29 files changed, 279 insertions(+), 3 deletions(-) create mode 100644 lib/key-generators/git-tag-commit.js create mode 100644 lib/key-generators/version-commit.js create mode 100644 tests/fixtures/not-a-repo/package.json create mode 100644 tests/fixtures/repo/dotgit/HEAD create mode 100644 tests/fixtures/repo/dotgit/config create mode 100644 tests/fixtures/repo/dotgit/index create mode 100644 tests/fixtures/repo/dotgit/objects/41/d41f081b45ad50935c08b1203220737d9739b4 create mode 100644 tests/fixtures/repo/dotgit/objects/77/06f9e51d51a2f357b2c2078cdd04e4acf48f93 create mode 100644 tests/fixtures/repo/dotgit/objects/a5/10e8069cc7eaa8b8262a9c071a702fbd52dbea create mode 100644 tests/fixtures/repo/dotgit/objects/d4/6bba1991f218165a93efe79024e16da2a213fc create mode 100644 tests/fixtures/repo/dotgit/refs/heads/master create mode 100644 tests/fixtures/repo/dotgit/refs/tags/2.3.4 create mode 100644 tests/fixtures/repo/package.json create mode 100644 tests/fixtures/repo/version.json create mode 100644 tests/fixtures/tagless-repo/dotgit/HEAD create mode 100644 tests/fixtures/tagless-repo/dotgit/config create mode 100644 tests/fixtures/tagless-repo/dotgit/index create mode 100644 tests/fixtures/tagless-repo/dotgit/objects/5e/29d0ad64c0132a1fc27416a0af2c05511c3e99 create mode 100644 tests/fixtures/tagless-repo/dotgit/objects/77/06f9e51d51a2f357b2c2078cdd04e4acf48f93 create mode 100644 tests/fixtures/tagless-repo/dotgit/objects/91/38ef996f3c7680aedcba68b0371d828b6dbb0b create mode 100644 tests/fixtures/tagless-repo/dotgit/refs/heads/master create mode 100644 tests/fixtures/tagless-repo/package.json create mode 100644 tests/unit/lib/key-generators/git-tag-commit-nodetest.js create mode 100644 tests/unit/lib/key-generators/version-commit-nodetest.js diff --git a/README.md b/README.md index 36fde28..9e469a9 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ For detailed information on how configuration of plugins works, please refer to The type of [Key Generator](#key-generators) to be used. *Default:* `'file-hash'` +*Alternatives:* `'git-tag-commit'`, `'version-commit'` ## Key Generators @@ -83,6 +84,24 @@ The list of built project files. This option should be relative to `distDir` and *Default:* `context.distFiles` +### Git Tag Commit generator + +Creates a key based on the most recent git tag and the currently checked-out commit. The tag is the tag identifier, followed by a `+` symbol, followed by the first 8 characters of the commit hash. + +For example, if your most recent git tag is `v2.0.3`, and the current commit is `0993043d49f9e0[...]`, this generator will return a revision of `v2.0.3+0993043d`. + +### Version Commit generator + +Similar to the Git Tag Commit generator, but uses the `package.json` version string instead of the git tag. The JSON file containing the version string can be configured with the `versionFile` option. + +#### Configuration Options + +##### versionFile + +The file containing your project's version number. Must be a JSON file with a top-level `version` key. Only used by the `version-commit` key generator. + +*Default:* `package.json` + ## Prerequisites The following properties are expected to be present on the deployment `context` object: diff --git a/index.js b/index.js index 8ba9792..5aa30a8 100644 --- a/index.js +++ b/index.js @@ -20,6 +20,7 @@ module.exports = { distFiles: function(context) { return context.distFiles; }, + versionFile: 'package.json', }, didBuild: function(context) { var self = this; diff --git a/lib/key-generators/git-tag-commit.js b/lib/key-generators/git-tag-commit.js new file mode 100644 index 0000000..b1741ea --- /dev/null +++ b/lib/key-generators/git-tag-commit.js @@ -0,0 +1,23 @@ +var CoreObject = require('core-object'); +var gitRepoInfo = require('git-repo-info'); +var Promise = require('ember-cli/lib/ext/promise'); + +module.exports = CoreObject.extend({ + generate: function() { + var path = gitRepoInfo._findRepo(); + + if (path === null) { + return Promise.reject('Could not find git repository'); + } + + var info = gitRepoInfo(path); + var tag = info.tag; + var sha = info.sha.slice(0, 8); + + if (!info.tag || !sha) { + return Promise.reject('Could not build revision with tag `' + tag + '` and commit hash `' + sha + '`'); + } + + return Promise.resolve(info.tag + '+' + sha); + } +}); diff --git a/lib/key-generators/index.js b/lib/key-generators/index.js index 3145768..2d39e85 100644 --- a/lib/key-generators/index.js +++ b/lib/key-generators/index.js @@ -1,3 +1,5 @@ module.exports = { - "file-hash": require('./file-hash') + "file-hash": require('./file-hash'), + "git-tag-commit": require('./git-tag-commit'), + "version-commit": require('./version-commit') }; diff --git a/lib/key-generators/version-commit.js b/lib/key-generators/version-commit.js new file mode 100644 index 0000000..75a1af0 --- /dev/null +++ b/lib/key-generators/version-commit.js @@ -0,0 +1,37 @@ +var CoreObject = require('core-object'); +var gitRepoInfo = require('git-repo-info'); +var fs = require('fs'); +var Promise = require('ember-cli/lib/ext/promise'); + +var denodeify = require('rsvp').denodeify; +var readFile = denodeify(fs.readFile); + +module.exports = CoreObject.extend({ + init: function(options) { + this._plugin = options.plugin; + }, + + generate: function() { + var versionFile = this._plugin.readConfig('versionFile'); + + var path = gitRepoInfo._findRepo(); + + if (path === null) { + return Promise.reject('Could not find git repository'); + } + + var info = gitRepoInfo(path); + var sha = info.sha.slice(0, 8); + + return readFile(versionFile) + .then(function(contents) { + var json = JSON.parse(contents); + + if (!json.version || !sha) { + return Promise.reject('Could not build revision with version `' + json.version + '` and commit hash `' + sha + '`'); + } + + return json.version + '+' + sha; + }); + } +}); diff --git a/package.json b/package.json index 84af815..554a845 100644 --- a/package.json +++ b/package.json @@ -46,8 +46,9 @@ "dependencies": { "chalk": "^1.0.0", "core-object": "^1.1.0", - "ember-cli-deploy-plugin": "0.1.3", "ember-cli-babel": "^5.0.0", + "ember-cli-deploy-plugin": "0.1.3", + "git-repo-info": "^1.1.2", "minimatch": "^2.0.4", "rsvp": "^3.0.18" }, diff --git a/tests/fixtures/not-a-repo/package.json b/tests/fixtures/not-a-repo/package.json new file mode 100644 index 0000000..7706f9e --- /dev/null +++ b/tests/fixtures/not-a-repo/package.json @@ -0,0 +1,3 @@ +{ + "version": "3.2.1" +} diff --git a/tests/fixtures/repo/dotgit/HEAD b/tests/fixtures/repo/dotgit/HEAD new file mode 100644 index 0000000..cb089cd --- /dev/null +++ b/tests/fixtures/repo/dotgit/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/tests/fixtures/repo/dotgit/config b/tests/fixtures/repo/dotgit/config new file mode 100644 index 0000000..6c9406b --- /dev/null +++ b/tests/fixtures/repo/dotgit/config @@ -0,0 +1,7 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + ignorecase = true + precomposeunicode = true diff --git a/tests/fixtures/repo/dotgit/index b/tests/fixtures/repo/dotgit/index new file mode 100644 index 0000000000000000000000000000000000000000..910060a72df49a118b833bd29d56f46494a4441e GIT binary patch literal 225 zcmZ?q402{*U|<5_(35tYK$-zYGcqu+FiSZ;W?*Ps!oa}z6(}VF#FFJ~KcC75F8Un4 z=@5I*U6v0)`BXM=(dY0@huC}W vvOHPyrGGM1U0G^Tab|uVMBP$>7i@Emzgn?FO=}LjRDu59pxdtivF;;`nIS0Q literal 0 HcmV?d00001 diff --git a/tests/fixtures/repo/dotgit/refs/heads/master b/tests/fixtures/repo/dotgit/refs/heads/master new file mode 100644 index 0000000..9cbfe46 --- /dev/null +++ b/tests/fixtures/repo/dotgit/refs/heads/master @@ -0,0 +1 @@ +41d41f081b45ad50935c08b1203220737d9739b4 diff --git a/tests/fixtures/repo/dotgit/refs/tags/2.3.4 b/tests/fixtures/repo/dotgit/refs/tags/2.3.4 new file mode 100644 index 0000000..9cbfe46 --- /dev/null +++ b/tests/fixtures/repo/dotgit/refs/tags/2.3.4 @@ -0,0 +1 @@ +41d41f081b45ad50935c08b1203220737d9739b4 diff --git a/tests/fixtures/repo/package.json b/tests/fixtures/repo/package.json new file mode 100644 index 0000000..7706f9e --- /dev/null +++ b/tests/fixtures/repo/package.json @@ -0,0 +1,3 @@ +{ + "version": "3.2.1" +} diff --git a/tests/fixtures/repo/version.json b/tests/fixtures/repo/version.json new file mode 100644 index 0000000..a510e80 --- /dev/null +++ b/tests/fixtures/repo/version.json @@ -0,0 +1,3 @@ +{ + "version": "1.2.3" +} diff --git a/tests/fixtures/tagless-repo/dotgit/HEAD b/tests/fixtures/tagless-repo/dotgit/HEAD new file mode 100644 index 0000000..cb089cd --- /dev/null +++ b/tests/fixtures/tagless-repo/dotgit/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/tests/fixtures/tagless-repo/dotgit/config b/tests/fixtures/tagless-repo/dotgit/config new file mode 100644 index 0000000..6c9406b --- /dev/null +++ b/tests/fixtures/tagless-repo/dotgit/config @@ -0,0 +1,7 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + ignorecase = true + precomposeunicode = true diff --git a/tests/fixtures/tagless-repo/dotgit/index b/tests/fixtures/tagless-repo/dotgit/index new file mode 100644 index 0000000000000000000000000000000000000000..670a28457117a20f7de019a98e6e226b9fe7f914 GIT binary patch literal 145 zcmZ?q402{*U|<4b#?X@vGl4V%jAmqDU}2VWy1>BDxCAKu6(}VF#FFJ~KcC75F8Un4 z=@5I*U6vI$SJ84MK+xZ*S~tW7x}tR;V_ jL~Ox&9o9e@yO}lH1U}sP&&;%RO*dPevAvMK>QW&9lQSv& literal 0 HcmV?d00001 diff --git a/tests/fixtures/tagless-repo/dotgit/objects/5e/29d0ad64c0132a1fc27416a0af2c05511c3e99 b/tests/fixtures/tagless-repo/dotgit/objects/5e/29d0ad64c0132a1fc27416a0af2c05511c3e99 new file mode 100644 index 0000000000000000000000000000000000000000..1f0343d41fe9126f124fb7d1dab14b27a9966622 GIT binary patch literal 57 zcmV-90LK4#0V^p=O;s>4U@$Z=Ff%bxC`e4sPE1eL%PP*#V<>0)`BXM=(dY0@huC}W PvOHPyrGGL2hO`rVX^a@d literal 0 HcmV?d00001 diff --git a/tests/fixtures/tagless-repo/dotgit/objects/77/06f9e51d51a2f357b2c2078cdd04e4acf48f93 b/tests/fixtures/tagless-repo/dotgit/objects/77/06f9e51d51a2f357b2c2078cdd04e4acf48f93 new file mode 100644 index 0000000000000000000000000000000000000000..6bf47f7ad2fb59a7e7c596d8a5918394d06fc349 GIT binary patch literal 41 xcmbÊŸŒ»>m˜,°zîn“BM \ No newline at end of file diff --git a/tests/fixtures/tagless-repo/dotgit/refs/heads/master b/tests/fixtures/tagless-repo/dotgit/refs/heads/master new file mode 100644 index 0000000..3f77067 --- /dev/null +++ b/tests/fixtures/tagless-repo/dotgit/refs/heads/master @@ -0,0 +1 @@ +9138ef996f3c7680aedcba68b0371d828b6dbb0b diff --git a/tests/fixtures/tagless-repo/package.json b/tests/fixtures/tagless-repo/package.json new file mode 100644 index 0000000..7706f9e --- /dev/null +++ b/tests/fixtures/tagless-repo/package.json @@ -0,0 +1,3 @@ +{ + "version": "3.2.1" +} diff --git a/tests/unit/index-nodetest.js b/tests/unit/index-nodetest.js index 46b6d10..3f0221f 100644 --- a/tests/unit/index-nodetest.js +++ b/tests/unit/index-nodetest.js @@ -77,7 +77,7 @@ describe('the index', function() { return previous; }, []); - assert.equal(messages.length, 4); + assert.equal(messages.length, 5); }); it('adds default config to the config object', function() { diff --git a/tests/unit/lib/key-generators/git-tag-commit-nodetest.js b/tests/unit/lib/key-generators/git-tag-commit-nodetest.js new file mode 100644 index 0000000..1434e09 --- /dev/null +++ b/tests/unit/lib/key-generators/git-tag-commit-nodetest.js @@ -0,0 +1,57 @@ +'use strict'; + +var assert = require('ember-cli/tests/helpers/assert'); +var gitRepoInfo = require('git-repo-info'); + +describe('the git-tag-commit key generator', function() { + var KeyGenerator; + var cwd; + + before(function() { + KeyGenerator = require('../../../../lib/key-generators/git-tag-commit'); + gitRepoInfo._changeGitDir('dotgit'); + }); + + beforeEach(function() { + cwd = process.cwd(); + }); + + afterEach(function() { + process.chdir(cwd); + }); + + describe('#generate', function() { + it('concatenates the git tag and the git commit hash', function() { + process.chdir('tests/fixtures/repo'); + + var subject = new KeyGenerator(); + + return assert.isFulfilled(subject.generate()) + .then(function(revision) { + assert.equal(revision, '2.3.4+41d41f08'); + }); + }); + + it('rejects if no repository found', function() { + process.chdir('tests/fixtures/not-a-repo'); + + var subject = new KeyGenerator(); + + return assert.isRejected(subject.generate()) + .then(function(error) { + assert.equal(error, 'Could not find git repository'); + }); + }); + + it('rejects if no git tag found', function() { + process.chdir('tests/fixtures/tagless-repo'); + + var subject = new KeyGenerator(); + + return assert.isRejected(subject.generate()) + .then(function(error) { + assert.equal(error, 'Could not build revision with tag `null` and commit hash `9138ef99`'); + }); + }); + }); +}); diff --git a/tests/unit/lib/key-generators/version-commit-nodetest.js b/tests/unit/lib/key-generators/version-commit-nodetest.js new file mode 100644 index 0000000..296f118 --- /dev/null +++ b/tests/unit/lib/key-generators/version-commit-nodetest.js @@ -0,0 +1,101 @@ +'use strict'; + +var assert = require('ember-cli/tests/helpers/assert'); +var gitRepoInfo = require('git-repo-info'); + +describe('the version-commit key generator', function() { + var KeyGenerator; + var cwd; + + before(function() { + KeyGenerator = require('../../../../lib/key-generators/version-commit'); + gitRepoInfo._changeGitDir('dotgit'); + }); + + beforeEach(function() { + cwd = process.cwd(); + }); + + afterEach(function() { + process.chdir(cwd); + }); + + describe('#generate', function() { + it('concatenates the package version and the git commit hash', function() { + process.chdir('tests/fixtures/repo'); + + var plugin = { + stubConfig: { + versionFile: 'package.json' + }, + readConfig: function(key) { return this.stubConfig[key]; } + }; + + var subject = new KeyGenerator({ + plugin: plugin + }); + + return assert.isFulfilled(subject.generate()) + .then(function(revision) { + assert.equal(revision, '3.2.1+41d41f08'); + }); + }); + + it('rejects if no repository found', function() { + process.chdir('tests/fixtures/not-a-repo'); + + var plugin = { + stubConfig: { + versionFile: 'package.json' + }, + readConfig: function(key) { return this.stubConfig[key]; } + }; + + var subject = new KeyGenerator({ + plugin: plugin + }); + + return assert.isRejected(subject.generate()) + .then(function(error) { + assert.equal(error, 'Could not find git repository'); + }); + }); + + it('has version source file option', function() { + process.chdir('tests/fixtures/repo'); + + var plugin = { + stubConfig: { + versionFile: 'version.json' + }, + readConfig: function(key) { return this.stubConfig[key]; } + }; + + var subject = new KeyGenerator({ + plugin: plugin + }); + + return assert.isFulfilled(subject.generate()) + .then(function(revision) { + assert.equal(revision, '1.2.3+41d41f08'); + }); + }); + + it('rejects when the version source file doesn\'t exist', function() { + process.chdir('tests/fixtures/repo'); + + var plugin = { + stubConfig: { + versionFile: 'tests/fixtures/missing-version.json' + }, + readConfig: function(key) { return this.stubConfig[key]; } + }; + + var subject = new KeyGenerator({ + plugin: plugin + }); + + return assert.isRejected(subject.generate()); + }); + }); +});