Skip to content
Browse files

reworked how existing version:changeid pairs are read from the changelog

  • Loading branch information...
1 parent 88dd54b commit 4beb6b3c86dd003be62630d08e68eb21932c1b19 @drewfish committed Apr 7, 2012
Showing with 89 additions and 67 deletions.
  1. +0 −12 Readme.md
  2. +0 −5 lib/crank.js
  3. +87 −49 lib/op-changelog.js
  4. +2 −1 package.json
View
12 Readme.md
@@ -104,18 +104,6 @@ a tool to update version number and changelog, for npm module development
* `regexp`: string
* `replace`: "string"
* if results in "--CRANK:SKIP--" then version is skipped
-* `database` -- TODO
- * maps version:changeid
- * only really needed by `crank changelog`
- * types
- * `file {foo.json}`
- * separate json file
- * `changelog`
- * uses changelog file itself to find version:changeid pairs
- * TODO: need way to pull pairs out of changelog (regexp?)
- * `scm-changes`
- * uses SCM change log to find version:changeid pairs
- * TODO: need way to pull pairs out of SCM change log
## template
View
5 lib/crank.js
@@ -83,11 +83,6 @@ function Base(options) {
versions: {
dateformat: 'default',
filters: []
- },
- database: {
- type: 'regexp',
- file: 'Changelog.md',
- regexp: '\\bversion\\s+([0-9.]+)[\\s\\S]*?\\bchange\\s+(\\S+)'
}
}
};
View
136 lib/op-changelog.js
@@ -28,8 +28,7 @@ var
libdateformat = require('dateformat'),
libmu = require('mu2'),
libpath = require('path'),
-
- CHANGELOG_DBS = {};
+ libxregexp = require('xregexp').XRegExp;
@@ -42,6 +41,7 @@ function OPChangelog(base) {
this.base.config.changelog.template =
libpath.extname(this.base.config.changelog.file).substr(1);
}
+ this.template = new Template(base);
}
module.exports = OPChangelog;
@@ -60,21 +60,18 @@ OPChangelog.prototype.usage = function(command) {
OPChangelog.prototype.run = function(command) {
var me = this,
- db,
mapVersionChange,
currentChangeID,
latestChangeID,
changes,
latestVersion,
rendered = '';
- db = makeChangelogDB(this.base, this.base.config.changelog.database);
-
libasync.series([
// read db
function step1(cb) {
- db.read(function(error, map) {
+ me._readChangelog(function(error, map) {
if (error) {
cb(error);
return;
@@ -104,7 +101,7 @@ OPChangelog.prototype.run = function(command) {
function step3(cb) {
latestChangeID = mapVersionChange[Object.keys(mapVersionChange)[0]];
if (currentChangeID === latestChangeID) {
- console.log('NOTICE: no changes since last crank. done..');
+ console.log('NOTICE: no changes since last crank. done.');
return;
}
cb();
@@ -137,7 +134,7 @@ OPChangelog.prototype.run = function(command) {
// filter/transform/templatize changes
function step6(cb) {
- var release = {}, releases, template;
+ var release, releases;
changes = me.base.filter(changes,
me.base.config.changelog.changes.filters);
@@ -158,18 +155,14 @@ OPChangelog.prototype.run = function(command) {
me.base.config.changelog.versions.filters);
release = releases[0];
- template = libpath.join(__dirname, '..', 'templates-changelog',
- me.base.config.changelog.template + '.mu');
- libmu.compileAndRender(template, release)
- .on('error', function(error) {
+ me.template.renderVersion(release, function(error, content) {
+ if (error) {
cb(error);
- })
- .on('data', function(data) {
- rendered += data.toString();
- })
- .on('end', function() {
- cb();
- });
+ return;
+ }
+ rendered = content;
+ cb();
+ });
},
// update changelog
@@ -179,54 +172,99 @@ OPChangelog.prototype.run = function(command) {
content = rendered + content;
me.base.fileWrite(me.base.config.changelog.file, content);
cb();
- },
-
- // update db
- function step8(cb) {
- db.update(latestVersion, latestChangeID, cb);
- },
+ }
]);
};
+OPChangelog.prototype._readChangelog = function(cb) {
+ var content, versions, version, i,
+ db = {};
+
+ content = this.base.fileRead(this.base.config.changelog.file);
+ versions = this.template.parseChangelog(content);
+
+ for (i = 0; i < versions.length; i++) {
+ version = versions[i];
+ db[version.version] = version.changeid;
+ }
+ cb(null, db);
+};
-//--------------------------------------------------------
-// changelog database
-function makeChangelogDB(base, config) {
- return new CHANGELOG_DBS[config.type](base, config);
-}
-// duck typing methods:
-// * read(cb(error,db))
-// returns an array of pairs (TODO: what is a pair)
-// * update(version, change, db(error))
-// returns success as boolean
//--------------------------------------------------------
-// data stored in changelog, pulled out via RegExps
-function ChangelogDBRegexp(base, config) {
+// abstraction over template, since we need to do some
+// funky things
+
+function Template(base) {
this.base = base;
- this.config = config;
- this.regexp = new RegExp(config.regexp, 'g');
+ this._load();
}
-CHANGELOG_DBS.regexp = ChangelogDBRegexp;
-ChangelogDBRegexp.prototype.read = function(cb) {
- var content, matches, db = {};
- content = this.base.fileRead(this.config.file);
- while (matches = this.regexp.exec(content)) {
- db[matches[1]] = matches[2];
+Template.prototype.parseChangelog = function(changelog) {
+ var tokenized, regexp,
+ names = {}, idx = 1,
+ matches,
+ versions = [], version;
+
+ // This makes a RegExp out of the template, and uses that to match against
+ // the changelog. The generated RegExp is only approximately able to parse
+ // the formatted string (changelog), but it's good enough to pull out the
+ // things we care about ({{version}} and {{changeid}}).
+
+ tokenized = this.content.replace(/{{#([^}]+)}}[\s\S]*?{{\/\1}}/, ':CRANK:$1:');
+ tokenized = tokenized.replace(/{{^([^}]+)}}[\s\S]*?{{\/\1}}/, ':CRANK:no-$1:');
+ tokenized = tokenized.replace(/{?{{([^}]*)}}}?/g, ':CRANK:$1:');
+
+ regexp = libxregexp.escape(tokenized);
+ while (matches = regexp.match(/:CRANK:([a-z]+):/)) {
+ // TODO: This doesn't capture all of {{changes}}.
+ // That's hard to do since it needs to only go up to the end of the
+ // version, and not match into the next version. (It's doable, but
+ // tricky since the template could be user-defined, and thus we can't
+ // make any assumptions about its structure.)
+ regexp = regexp.replace(matches[0], '([\\s\\S]*?)');
+ names[idx] = matches[1];
+ idx++;
}
- cb(null, db);
+ regexp = new RegExp(regexp, 'g');
+
+ while (matches = regexp.exec(changelog)) {
+ version = {};
+ for (idx in names) {
+ if (names.hasOwnProperty(idx)) {
+ version[names[idx]] = matches[idx];
+ }
+ }
+ versions.push(version);
+ }
+ return versions;
};
-ChangelogDBRegexp.prototype.update = function(version, change, cb) {
- // noop because the info has already been written to the changelog file
- cb();
+Template.prototype.renderVersion = function(data, cb) {
+ var rendered = '';
+ libmu.renderText(this.content, data)
+ .on('error', function(error) {
+ cb(error);
+ })
+ .on('data', function(data) {
+ rendered += data.toString();
+ })
+ .on('end', function() {
+ cb(null, rendered);
+ });
};
+Template.prototype._load = function() {
+ var path;
+ path = libpath.join(__dirname, '..', 'templates-changelog',
+ this.base.config.changelog.template + '.mu');
+ this.content = this.base.fileRead(path);
+};
+
View
3 package.json
@@ -30,7 +30,8 @@
"async": ">= 0.1.18",
"dateformat": ">= 1.0.2-1.2.3",
"mu2": ">= 0.5.3",
- "semver": ">= 1.0.13"
+ "semver": ">= 1.0.13",
+ "xregexp": ">= 1.5.3 < 2.0.0"
},
"main": "lib/crank",
"bin": {

0 comments on commit 4beb6b3

Please sign in to comment.
Something went wrong with that request. Please try again.