From ca41efefc5b375b7d1dcc155aba7df668e58505d Mon Sep 17 00:00:00 2001 From: Mattia Gheda Date: Sat, 12 Mar 2016 19:06:10 -0500 Subject: [PATCH] add scm table moves old behaviour in separate file as well --- README.md | 25 ++++++++ index.js | 104 ++++++--------------------------- lib/legacy-table.js | 109 +++++++++++++++++++++++++++++++++++ lib/scm-table.js | 82 ++++++++++++++++++++++++++ package.json | 5 +- tests/unit/index-nodetest.js | 51 +++++++++++++++- 6 files changed, 286 insertions(+), 90 deletions(-) create mode 100644 lib/legacy-table.js create mode 100644 lib/scm-table.js diff --git a/README.md b/README.md index f0726fc..1c980af 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,31 @@ Display a list of deployed revisions using [ember-cli-deploy](https://github.com * `ember install ember-cli-deploy-display-revisions` +## Configuration Options + +### Defaults + +``` + ENV['display-revisions'] = { + amount: 10, + revisions: function(context) { + return context.revisions; + } + } +``` + +### amount + +Number of revisions displayed in the results table + +*Default:* `10` + +### revisions + +The data to be displayed + +*Default:* `context.revisions`, usually received from `fetchRevisions` + ## Usage * `ember deploy:list ` to list the latest 10 revisions diff --git a/index.js b/index.js index ca4b5e0..8ed441b 100644 --- a/index.js +++ b/index.js @@ -2,7 +2,9 @@ 'use strict'; var DeployPluginBase = require('ember-cli-deploy-plugin'); -var moment = require('moment'); +var ScmTable = require('./lib/scm-table'); +var LegacyTable = require('./lib/legacy-table'); +var _ = require('lodash'); module.exports = { name: 'ember-cli-deploy-display-revisions', @@ -15,103 +17,31 @@ module.exports = { amount: function(context) { return context.commandOptions.amount || 10; }, + + revisions: function(context) { + return context.revisions; + } }, displayRevisions: function(context) { - if(!context.revisions) { + var table; + var revisions = this.readConfig('revisions'); + if(!revisions || revisions.length === 0) { this.log("Could not display latest revisions because no revisions were found in context.", {color: 'yellow'}); return; } - var revisions = context.revisions.slice(0, this.readConfig("amount")); - - var keys = this._getKeys(revisions); + revisions = revisions.slice(0, this.readConfig("amount")); - this._displayHeader(keys, revisions); + var hasRevisionData = _.every(revisions, 'revisionData'); - revisions.forEach(function(revision) { - this._displayRow(keys, revision); - }.bind(this)); - }, - _displayRow: function(keys, revision) { - var row = ""; - if(revision.active) { - row += ">"; + if (hasRevisionData) { + table = new ScmTable(this, revisions); + table.display(); } else { - row += " "; + table = new LegacyTable(this, revisions); + table.display(); } - - var lastKey = keys[keys.length - 1]; - - keys.forEach(function(key) { - var value = revision[key.name] ? revision[key.name] : ""; - - if(key.name === 'timestamp') { - value = moment(value).format("YYYY/MM/DD HH:mm:ss"); - } - - if(key.maxLength !== -1) { - value = String(value).substr(0, key.maxLength); - } - - row += " " + value + " "; - - var fillerLength = key.maxLength - value.length; - for(var i = 0; i < fillerLength; i++) { - row += " "; - } - if(key !== lastKey) { - row += "|"; - } - }); - - this.log(row); - }, - _getKeys: function(revisions) { - var keys = [ - {name: 'version', maxLength: 7}, - {name: 'timestamp', maxLength: 19}, - {name: 'deployer', maxLength: 10}, - {name: 'revision', maxLength: -1} - ]; - var presentKeys = []; - keys.forEach(function(key) { - if(this._hasKey(key.name, revisions)) { - presentKeys.push(key); - } - }.bind(this)); - return presentKeys; - }, - _displayHeader: function(keys) { - var keyHeader = " "; - var lastKey = keys[keys.length - 1]; - - keys.forEach(function(key) { - var shortKey = key.maxLength === -1 ? key.name : key.name.substr(0, key.maxLength); - keyHeader += " " + shortKey + " "; - - var fillerLength = key.maxLength === -1 ? 0 : key.maxLength - shortKey.length; - for(var i = 0; i < fillerLength; i++) { - keyHeader += " "; - } - - // revision hash needs an unknown amount of space, don't display closing | - if(key !== lastKey) { - keyHeader += "|"; - } - }); - this.log(keyHeader); - - var underline = ""; - for(var i = 0; i < keyHeader.length; i++) { - underline += "="; - } - this.log(underline); - }, - _hasKey: function(key, revisions) { - return revisions.some(function(revision) { - return Object.keys(revision).indexOf(key) !== -1; - }); } }); diff --git a/lib/legacy-table.js b/lib/legacy-table.js new file mode 100644 index 0000000..af2c857 --- /dev/null +++ b/lib/legacy-table.js @@ -0,0 +1,109 @@ +var moment = require('moment'); + +var CoreObject = require('core-object'); +var Promise = require('ember-cli/lib/ext/promise'); + +module.exports = CoreObject.extend({ + init: function(plugin, revisions) { + this._plugin = plugin; + this.revisions = revisions; + }, + + log: function() { + this._plugin.log.apply(this._plugin, arguments); + }, + + display: function() { + var revisions = this.revisions; + var keys = this._getKeys(revisions); + + this._displayHeader(keys, revisions); + + revisions.forEach(function(revision) { + this._displayRow(keys, revision); + }.bind(this)); + }, + + _displayRow: function(keys, revision) { + var row = ""; + if(revision.active) { + row += ">"; + } else { + row += " "; + } + + var lastKey = keys[keys.length - 1]; + + keys.forEach(function(key) { + var value = revision[key.name] ? revision[key.name] : ""; + + if(key.name === 'timestamp') { + value = moment(value).format("YYYY/MM/DD HH:mm:ss"); + } + + if(key.maxLength !== -1) { + value = String(value).substr(0, key.maxLength); + } + + row += " " + value + " "; + + var fillerLength = key.maxLength - value.length; + for(var i = 0; i < fillerLength; i++) { + row += " "; + } + if(key !== lastKey) { + row += "|"; + } + }); + + this.log(row); + }, + + _getKeys: function(revisions) { + var keys = [ + {name: 'version', maxLength: 7}, + {name: 'timestamp', maxLength: 19}, + {name: 'deployer', maxLength: 10}, + {name: 'revision', maxLength: -1} + ]; + var presentKeys = []; + keys.forEach(function(key) { + if(this._hasKey(key.name, revisions)) { + presentKeys.push(key); + } + }.bind(this)); + return presentKeys; + }, + + _displayHeader: function(keys) { + var keyHeader = " "; + var lastKey = keys[keys.length - 1]; + + keys.forEach(function(key) { + var shortKey = key.maxLength === -1 ? key.name : key.name.substr(0, key.maxLength); + keyHeader += " " + shortKey + " "; + + var fillerLength = key.maxLength === -1 ? 0 : key.maxLength - shortKey.length; + for(var i = 0; i < fillerLength; i++) { + keyHeader += " "; + } + + // revision hash needs an unknown amount of space, don't display closing | + if(key !== lastKey) { + keyHeader += "|"; + } + }); + this.log(keyHeader); + + var underline = ""; + for(var i = 0; i < keyHeader.length; i++) { + underline += "="; + } + this.log(underline); + }, + _hasKey: function(key, revisions) { + return revisions.some(function(revision) { + return Object.keys(revision).indexOf(key) !== -1; + }); + } +}); diff --git a/lib/scm-table.js b/lib/scm-table.js new file mode 100644 index 0000000..5d3010b --- /dev/null +++ b/lib/scm-table.js @@ -0,0 +1,82 @@ +/* jshint node: true */ +var Table = require('cli-table2'); +var moment = require('moment'); + +var CoreObject = require('core-object'); +var Promise = require('ember-cli/lib/ext/promise'); + +module.exports = CoreObject.extend({ + init: function(plugin, revisions) { + this._plugin = plugin; + this.revisions = revisions; + }, + + display: function(revisions) { + var table = this._createTable(); + this._tableRows(table); + + this._plugin.logRaw(table.toString()); + return Promise.resolve(); + }, + + _isWide: function() { + return process.stdout.columns >= 98; + }, + + _tableHeader: function() { + var head = ['RevisionKey', 'Commit', 'User', 'Branch']; + + if (this._isWide()) { + head.push('Deploy time'); + } + return head; + }, + + _createTable: function() { + var head = this._tableHeader(); + + return new Table({ + head: head, + wordWrap: true, + chars: { + 'top': '', + 'top-mid': '', + 'top-left': '', + 'top-right': '', + 'bottom': '', + 'mid': '', + 'middle': '', + 'mid-mid': '', + 'bottom-mid': '', + 'bottom-left': '', + 'bottom-right': '', + 'left': '', + 'left-mid': '', + 'right': '', + 'right-mid': '' + } + }); + }, + + _tableRows: function(table) { + this.revisions.forEach(function(revision) { + var data = revision.revisionData; + + var row = [ + ((revision.active) ? '> ' : ' ') + data.revisionKey, + data.scm.sha.substr(0,8), + data.scm.email, + data.scm.branch, + ]; + + if (this._isWide()) { + var value = moment(data.timestamp).format("YYYY/MM/DD HH:mm:ss"); + row.push(value); + } + + table.push(row); + + }.bind(this)); + }, + +}); diff --git a/package.json b/package.json index 247a275..5a47fc2 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "ember-export-application-global": "^1.0.2", "ember-try": "0.0.4", "glob": "^5.0.5", + "lodash": "^3.10.1", "mocha": "^2.2.4" }, "keywords": [ @@ -43,8 +44,10 @@ "ember-cli-deploy-plugin" ], "dependencies": { + "cli-table2": "^0.2.0", + "core-object": "^2.0.0", "ember-cli-babel": "^5.0.0", - "ember-cli-deploy-plugin": "^0.2.1", + "ember-cli-deploy-plugin": "^0.2.3", "moment": "2.10.6" }, "ember-addon": { diff --git a/tests/unit/index-nodetest.js b/tests/unit/index-nodetest.js index 806c8ed..8e9fb80 100644 --- a/tests/unit/index-nodetest.js +++ b/tests/unit/index-nodetest.js @@ -61,7 +61,7 @@ describe('displayRevisions plugin', function() { return previous; }, []); - assert.equal(messages.length, 1); + assert.equal(messages.length, 2); }); it('adds default config to the config object', function() { @@ -95,8 +95,55 @@ describe('displayRevisions plugin', function() { return previous; }, []); - assert.equal(messages.length, 0); + assert.equal(messages.length, 1); + }); + }); + }); + describe('displayRevisions hook with revisionData', function() { + var plugin, context; + + beforeEach(function() { + plugin = subject.createDeployPlugin({ + name: 'display-revisions' }); + + context = { + ui: mockUi, + config: { }, + commandOptions: { + amount: 3 + }, + revisions: [ + { revision: "rev:first", revisionData: {revisionKey: 'rev:first', scm: {sha: '99ee96e7ee7d36717524bd6489d2eff966c83c3d', email: 'mattia@mail.com', branch: 'foo'}, timestamp: 1032123125000}}, + { revision: "rev:second", revisionData: {revisionKey: 'rev:second', scm: {sha: 'eeee96e7ee7d36717524bd6489d2eff966c83c3d', email: 'aaron@mail.com', branch: 'bar'}, timestamp: 1032123127000}}, + { revision: "rev:third", revisionData: {revisionKey: 'rev:third', scm: {sha: 'ffee96e7ee7d36717524bd6489d2eff966c83c3d', email: 'luke@mail.com', branch: 'foo'}, timestamp: 1032123128000}}, + ] + }; + plugin.beforeHook(context); + plugin.configure(context); + }); + + it('lists revisions', function() { + plugin.displayRevisions(context); + var messages = mockUi.messages.reduce(function(previous, current) { + if (current.indexOf("rev:") !== -1) { + previous.push(current); + } + + return previous; + }, []); + assert.equal(messages.length, 1); // logs a single message as table + var message = messages[0]; + assert.match(message, /RevisionKey/); + assert.match(message, /Commit/); + assert.match(message, /User/); + assert.match(message, /Branch/); + + var lines = message.split("\n"); + assert.equal(lines.length, 4); // logs headers and 3 revisions + var revisionLine = lines[1]; + assert.match(revisionLine, /rev:first/); + assert.match(revisionLine, /mattia@mail.com/); }); });