Permalink
Browse files

added --color output (new default)

  • Loading branch information...
dylang committed Aug 7, 2011
1 parent 68031cf commit 54a67fbcf1c6c8136aee1007165a71bb436e7647
Showing with 177 additions and 51 deletions.
  1. +8 −9 lib/cli.js
  2. +19 −0 lib/color.js
  3. +11 −2 lib/github.js
  4. +8 −1 lib/log.js
  5. +41 −8 lib/npm.js
  6. +44 −8 lib/output.js
  7. +2 −2 lib/util.js
  8. +44 −21 readme.md
View
@@ -5,18 +5,17 @@ var Github = require('./github');
var Npm = require('./npm');
var log = require('./log');
-CLI.parse();
-
-/*
- Usage:
- changelog request
- changelog http://github.com/mikeal/request
- */
+CLI.setUsage('changelog <npm module name or github repo url> [OPTIONS]').parse({
+ color: ['c', 'Output as Color (default)'],
+ markdown: ['m', 'Output as Github-flavored Markdown'],
+ json: ['j', 'Output as JSON'],
+ debug: ['d', 'Enable debugging']
+});
CLI.main(function (args, options) {
var project = args[0];
- var output = options.json ? Output.json : Output.markdown;
+ var output = options.json ? Output.json : options.markdown ? Output.markdown : Output.color;
log.debugEnabled(options.debug);
@@ -44,7 +43,7 @@ CLI.main(function (args, options) {
},
function(err, data) {
if (err) {
- console.error(err.message);
+ log.error(err.message);
}
else {
console.info(data);
View
@@ -0,0 +1,19 @@
+module.exports = {
+ RESET: '\x1B[0m',
+ GREY: '\x1B[0;30m',
+ RED: '\x1B[0;31m',
+ GREEN: '\x1B[0;32;40m',
+ YELLOW: '\x1B[0;33m',
+ BLUE: '\x1B[0;34m',
+ MAGENTA: '\x1B[0;35m',
+ CYAN: '\x1B[0;36m',
+ WHITE: '\x1B[0;37m',
+ GREY_BOLD: '\x1B[1;30m',
+ RED_BOLD: '\x1B[1;31m',
+ GREEN_BOLD: '\x1B[1;32m',
+ YELLOW_BOLD:'\x1B[1;33m',
+ BLUE_BOLD: '\x1B[1;34m',
+ MAGENTA_BOLD: '\x1B[1;35m',
+ CYAN_BOLD: '\x1B[1;36m',
+ WHITE_BOLD: '\x1B[1;37m'
+};
View
@@ -38,7 +38,13 @@ function changes(options, cb) {
} else {
error = Error('Unknown Github Repo: ' + options.repo);
}
- cb(error, { changes: changes });
+ cb(error, {
+ project: {
+ github: project,
+ repository: 'https://github.com/' + project
+ },
+ changes: changes
+ });
});
}
@@ -64,7 +70,10 @@ function changelog(repo, cb) {
Object.keys(VersionsHash).forEach(function(simpleDate) {
Versions.push(VersionsHash[simpleDate]);
});
- cb(err, Versions);
+ cb(err, {
+ project: repo.project,
+ versions: Versions
+ });
});
}
View
@@ -1,16 +1,23 @@
+var Color = require('./color');
+
var showDebugMessages = false;
function debug(message) {
if (showDebugMessages) {
- console.info(message);
+ console.info(Color.GREY + message + Color.RESET);
}
}
+function error(message) {
+ console.error(Color.RED + message + Color.RESET);
+}
+
function debugEnabled(bool) {
showDebugMessages = !!bool;
}
module.exports = {
debug: debug,
+ error: error,
debugEnabled: debugEnabled
};
View
@@ -11,9 +11,26 @@ function sortVersions (a, b) {
return 0;
}
-function versions(packageName, cb) {
+function findRepoUrl(data) {
+var repo;
+ ['repository', 'repositories', 'bugs', 'licenses'].forEach(function(branch){
+ if (!repo) {
+ var repoTree = data[branch];
+ if (repoTree) {
+ repo = repoTree.url || repoTree.web;
+ if (!repo) {
+ repoTree = repoTree[0];
+ repo = repoTree.url || repoTree.web;
+ }
+ }
+ }
+ });
+ return repo;
+}
+
+function versions(moduleName, cb) {
var v = [];
- var url = 'http://search.npmjs.org/api/' + packageName;
+ var url = 'http://search.npmjs.org/api/' + moduleName;
log.debug('requesting: ' + url);
Request({ uri: url }, function(err, response, body) {
log.debug('complete: ' + url);
@@ -27,11 +44,16 @@ function versions(packageName, cb) {
err = new Error('Trouble with npm. A non-json response was returned: \n' + body);
}
if (!err) {
- if (data && data.repository && data.repository.url) {
- repo = data.repository.url;
- } else {
- err = new Error('Package author did not specify the code repo location.');
+ repo = findRepoUrl(data);
+
+ if (!repo) {
+ Object.keys(data.versions).forEach(function(version) {
+ if (!repo) {
+ repo = findRepoUrl(data.versions[version]);
+ }
+ });
}
+
if (data && data.time) {
var time = data.time;
delete time.created;
@@ -44,8 +66,11 @@ function versions(packageName, cb) {
});
});
}
+ if (!repo) {
+ err = new Error('Author of module ' + moduleName + ' did not specify the code repository url.');
+ }
if ((!err && !repo) || (data && !v.length)) {
- err = new Error('Unknown package: ' + packageName);
+ err = new Error('Unknown package: ' + moduleName);
}
}
}
@@ -70,6 +95,11 @@ function changelog(packageName, cb) {
},
function(err, data) {
var i;
+ var project;
+ if (data) {
+ project = data.project;
+ }
+
if (data && data.changes) {
if (data.changes[0].date > Versions[0].date) {
Versions.unshift({ version: 'Upcoming', date: data.changes[0].date});
@@ -88,7 +118,10 @@ function changelog(packageName, cb) {
}
});
}
- cb(err, Versions);
+ cb(err, {
+ project: project,
+ versions: Versions
+ } );
}
);
}
View
@@ -1,11 +1,46 @@
var Util = require('./util');
+var Color = require('./color');
-function markdown(changelog, cb) {
+function color(data, cb) {
var output = [];
- var err = !changelog || !changelog.length ? new Error ('No Changes') : null;
+ var err = !data || !data.versions || !data.versions.length ? new Error ('No Changes') : null;
- changelog.map(function(version, i){
+ data.versions.map(function(version, i){
+ if (version.changes) {
+ var date = version.date;
+ var versionString = (version.version ? version.version + ' / ' : '')
+ + date.getFullYear() + '-' + Util.padZero(date.getMonth() + 1) + '-' + Util.padZero(date.getDate());
+
+ // add a blank line between sections
+ if (i > 0) {
+ output.push('');
+ }
+
+ output.push(Color.BLUE + versionString + Color.RESET);
+
+ var uniqueChanges = {};
+ version.changes.forEach(function(change){
+ if (!uniqueChanges[change.message]) {
+ var message = change.message
+ .replace(/([^`]*)`([^`]*)`([^`]*)/g, '$1' + Color.GREEN + '$2' + Color.RESET + '$3')
+ .replace(/(#[0-9]*)/g, Color.CYAN + '$1' + Color.RESET)
+ .replace(/^(\[[^\]]*\])/, Color.GREY + '$1' + Color.RESET);
+ output.push(Color.RESET + Util.bullet(message, '\u2022') + Color.RESET);
+ }
+ uniqueChanges[change.message] = true;
+ });
+ }
+ });
+
+ cb(err, output.join('\n'));
+}
+
+function markdown(data, cb) {
+ var output = [];
+ var err = !data || !data.versions || !data.versions.length ? new Error ('No Changes') : null;
+
+ data.versions.map(function(version, i){
if (version.changes) {
var date = version.date;
var versionString = (version.version ? version.version + ' / ' : '')
@@ -23,7 +58,8 @@ function markdown(changelog, cb) {
var uniqueChanges = {};
version.changes.forEach(function(change){
if (!uniqueChanges[change.message]) {
- output.push(Util.bullet(change.message));
+ var message = change.message;
+ output.push(Util.bullet(message, '*'));
}
uniqueChanges[change.message] = true;
});
@@ -33,13 +69,13 @@ function markdown(changelog, cb) {
cb(err, output.join('\n'));
}
-function json(changelog, cb) {
- var err = !changelog || !changelog.length ? new Error ('No Changes') : null;
- cb(err, JSON.stringify(changelog));
+function json(data, cb) {
+ var err = !data || !data.versions || !data.versions.length ? new Error ('No Changes') : null;
+ cb(err, JSON.stringify(data.versions));
}
-
module.exports = {
+ color: color,
markdown: markdown,
json: json
};
View
@@ -15,12 +15,12 @@ function initWordWrap(width){
wordwrap = WordWrap(4, width);
}
-function bullet(string) {
+function bullet(string, bulletCharacter) {
if (!wordwrap) {
initWordWrap();
}
string = string.replace(/(\r?\n)+/g, '\r\n');
- return ' * ' + wordwrap(string).trim();
+ return ' ' + (bulletCharacter || '*') + ' ' + wordwrap(string).trim();
}
module.exports = {
Oops, something went wrong.

0 comments on commit 54a67fb

Please sign in to comment.