Cscott has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/96828


Change subject: Factor out promise utility module 'P', shared with mw-latexer.
......................................................................

Factor out promise utility module 'P', shared with mw-latexer.

Change-Id: Ida24d906a37afa557b9b093f91e4ef038b37d6f1
---
M bin/mw-bundler
M lib/db.js
M lib/index.js
A lib/p.js
M lib/revisions.js
M lib/siteinfo.js
M test/samples.js
7 files changed, 71 insertions(+), 49 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Collection/OfflineContentGenerator/bundler
 refs/changes/28/96828/1

diff --git a/bin/mw-bundler b/bin/mw-bundler
index 7a5da80..f08f9a9 100755
--- a/bin/mw-bundler
+++ b/bin/mw-bundler
@@ -6,11 +6,11 @@
 var program = require('commander');
 var bundler = require('../');
 var fs = require('fs');
-var nodefn = require("when/node/function");
 var url = require('url');
 var when = require('when');
 
 var Api = require('../lib/api');
+var P = require('../lib/p');
 var Siteinfo = require('../lib/siteinfo');
 
 program
@@ -118,7 +118,7 @@
 if (program.metabook) {
        // Load from file and parse JSON
        p = p.then(function() {
-               return nodefn.call(fs.readFile.bind(fs), program.metabook, 
'utf8');
+               return P.call(fs.readFile, fs, program.metabook, 'utf8');
        }).then(function(data) {
                metabook = JSON.parse(data);
        });
diff --git a/lib/db.js b/lib/db.js
index fc044b8..d331321 100644
--- a/lib/db.js
+++ b/lib/db.js
@@ -4,6 +4,8 @@
 var when = require('when');
 var nodefn = require("when/node/function");
 
+var P = require('./p');
+
 var Db = module.exports = function(filename, options) {
        /* jshint bitwise: false */
        options = options || {};
@@ -17,9 +19,11 @@
        // this.db is a promise for the database, once tables have been created
        this.db = deferred.promise.then(function() {
                if (!options.readonly) {
-                       return nodefn.call(db.run.bind(db),
-                                                          "CREATE TABLE IF NOT 
EXISTS "+
-                                                          "kv_table (key TEXT 
PRIMARY KEY, val TEXT);");
+                       return P.call(
+                               db.run, db,
+                               "CREATE TABLE IF NOT EXISTS " +
+                               "kv_table (key TEXT PRIMARY KEY, val TEXT);"
+                       );
                }
        }).then(function() { return db; });
 };
@@ -27,9 +31,11 @@
 // Returns a promise for the value.
 Db.prototype.get = function(key, nojson) {
        return this.db.then(function(db) {
-               return nodefn.call(db.get.bind(db),
-                                                  "SELECT val FROM kv_table 
WHERE key = ?;",
-                                                  '' + key);
+               return P.call(
+                       db.get, db,
+                       "SELECT val FROM kv_table WHERE key = ?;",
+                       '' + key
+               );
        }).then(function(row) {
                var val = row.val;
                return nojson ? val : JSON.parse(val);
@@ -44,7 +50,7 @@
                f(row.key, val);
        };
        return this.db.then(function(db) {
-               return nodefn.call(db.each.bind(db), "SELECT * FROM kv_table;", 
each);
+               return P.call(db.each, db, "SELECT * FROM kv_table;", each);
        });
 };
 
@@ -52,15 +58,17 @@
 Db.prototype.put = function(key, value) {
        if (typeof(value) !== 'string') { value = JSON.stringify(value); }
        return this.db.then(function(db) {
-               return nodefn.call(db.run.bind(db),
-                                                  "INSERT OR REPLACE INTO 
kv_table (key, val) "+
-                                                  "VALUES (?,?);", '' + key, 
value);
+               return P.call(
+                       db.run, db,
+                       "INSERT OR REPLACE INTO kv_table (key, val) VALUES 
(?,?);",
+                       '' + key, value
+               );
        });
 };
 
 // Returns a promise to close and finalize the database.
 Db.prototype.close = function() {
        return this.db.then(function(db) {
-               return nodefn.call(db.close.bind(db));
+               return P.call(db.close, db);
        });
 };
diff --git a/lib/index.js b/lib/index.js
index 1abb1e3..9728047 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -1,11 +1,11 @@
 require('es6-shim'); // Map/Set support
 
 var fs = require('fs');
-var nodefn = require("when/node/function");
 var path = require('path');
 var rimraf = require('rimraf');
-var spawn = require('child_process').spawn;
 var when = require('when');
+
+var P = require('./p');
 
 // set this to true to emit deprecated file formats for better pediapress
 // compatibility
@@ -14,12 +14,6 @@
 // with the pediapress bundler (at the cost of poorer support for
 // interwiki collections)
 var IMAGEDB_COMPAT = false;
-
-// my own version of nodefn.call with an explicit 'this', used for methods
-var pcall = function(fn, self) {
-       var args = Array.prototype.slice.call(arguments, 2);
-       return nodefn.apply(fn.bind(self), args);
-};
 
 module.exports = {
        version: require('../package.json').version
@@ -50,7 +44,7 @@
 
        var mkOutputDir = function() {
                // fail if output location is not writable
-               return pcall(fs.mkdir, fs, options.output, 
0700).then(function() {
+               return P.call(fs.mkdir, fs, options.output, 
0700).then(function() {
                        // don't clean up output dir unless this mkdir succeeded
                        cleanUpOutput = true;
                });
@@ -109,7 +103,7 @@
        var imagedir = path.join(options.output, 'images');
 
        var mkImageDir = function() {
-               return pcall(fs.mkdir, fs, imagedir, 0777);
+               return P.call(fs.mkdir, fs, imagedir, 0777);
        };
 
        // returns a promise which is resolved when all images from the imageMap
@@ -193,7 +187,7 @@
                        { filename: 'metabook.json', data: metabook },
                        { filename: 'nfo.json', data: nfo }
                ], function(item) {
-                       return pcall(fs.writeFile, fs,
+                       return P.call(fs.writeFile, fs,
                                                 path.join(options.output, 
item.filename),
                                                 JSON.stringify(item.data),
                                                 { encoding: 'utf8' });
@@ -205,7 +199,7 @@
                log('Creating bundle');
                if (options.nozip) {
                        // make the directory readable, then we're done.
-                       return pcall(fs.chmod, fs, options.output, 0755);
+                       return P.call(fs.chmod, fs, options.output, 0755);
                }
 
                // create zip archive
@@ -216,21 +210,9 @@
                        // accessed directly within the .db without extraction.
                        params.unshift('-n', '.db');
                }
-               var deferred = when.defer();
-               spawn('zip', params, {
+               var p = P.spawn('zip', params, {
                        cwd: options.output
-               }).on('exit', function(exitCode) {
-                       if (exitCode === 0) {
-                               deferred.resolve();
-                       } else {
-                               deferred.reject(new Error(
-                                       'zip '+params.join(' ')+' exited with 
code '+exitCode
-                               ));
-                       }
-               }).on('error', function(err) {
-                       deferred.reject(err);
                });
-               var p = deferred.promise;
 
                // always clean up at the end
                p = p.ensure(function() {
diff --git a/lib/p.js b/lib/p.js
new file mode 100644
index 0000000..2f6544a
--- /dev/null
+++ b/lib/p.js
@@ -0,0 +1,30 @@
+// Helpers for promises.
+var nodefn = require('when/node/function');
+var spawn = require('child_process').spawn;
+var when = require('when');
+
+var P = module.exports = {};
+
+// My own version of nodefn.call with an explicit 'this', used for methods
+P.call = function(fn, self) {
+       var args = Array.prototype.slice.call(arguments, 2);
+       return nodefn.apply(fn.bind(self), args);
+};
+
+// Returns a promise for completion after spawning `program`
+P.spawn = function(program, args, options) {
+       var deferred = when.defer();
+       spawn(program, args || [], options || {}).
+               on('exit', function(exitCode) {
+                       if (exitCode === 0) {
+                               deferred.resolve();
+                       } else {
+                               deferred.reject(new Error(
+                                       program+' '+args.join(' ')+' exited 
with code '+exitCode
+                               ));
+                       }
+               }).on('error', function(err) {
+                       deferred.reject(err);
+               });
+       return deferred.promise;
+};
diff --git a/lib/revisions.js b/lib/revisions.js
index 7f4ab70..a921dea 100644
--- a/lib/revisions.js
+++ b/lib/revisions.js
@@ -2,12 +2,12 @@
 // this is a particularly grody file, so we also store this in a more
 // sane manner as revisions.db.  hopefully we can deprecate the ugliness.
 var fs = require('fs');
-var nodefn = require('when/node/function');
 var path = require('path');
 var when = require('when');
 
 var Api = require('./api');
 var Db = require('./db');
+var P = require('./p');
 
 var fetchOne = function(wikis, wiki, title, revid) {
        var api = new Api(wikis);
@@ -58,11 +58,11 @@
                }) +
                '\n';
        p = p.then(function() {
-               return nodefn.call(outstream.write.bind(outstream), s, 'utf8');
+               return P.call(outstream.write, outstream, s, 'utf8');
        });
        p = p.then(function() {
-               return nodefn.call(outstream.write.bind(outstream),
-                                                  data.revisions[0]['*'], 
'utf8');
+               return P.call(outstream.write, outstream,
+                                         data.revisions[0]['*'], 'utf8');
        });
        return p;
 };
@@ -86,7 +86,7 @@
                return revDb.close();
        }).then(function() {
                return (revStream===null) ? null :
-                       nodefn.call(revStream.end.bind(revStream));
+                       P.call(revStream.end, revStream);
        });
        return p;
 };
diff --git a/lib/siteinfo.js b/lib/siteinfo.js
index b36fdec..106bcff 100644
--- a/lib/siteinfo.js
+++ b/lib/siteinfo.js
@@ -1,9 +1,9 @@
 // Generate content of siteinfo.json
 var fs = require('fs');
-var nodefn = require('when/node/function');
 var path = require('path');
 
 var Api = require('./api');
+var P = require('./p');
 
 var fetchSiteInfo = function(wikis, wiki) {
        var api = new Api(wikis);
@@ -18,9 +18,11 @@
 
 var writeSiteInfo = function(outdir, wiki, siteinfo) {
        var filename = (wiki === 0) ? 'siteinfo.json' : 
('siteinfo-'+wiki+'.json');
-       return nodefn.call(fs.writeFile.bind(fs),
-                                          path.join(outdir, filename),
-                                          JSON.stringify(siteinfo));
+       return P.call(
+               fs.writeFile, fs,
+               path.join(outdir, filename),
+               JSON.stringify(siteinfo)
+       );
 };
 
 module.exports = {
diff --git a/test/samples.js b/test/samples.js
index a97e6a9..dace614 100644
--- a/test/samples.js
+++ b/test/samples.js
@@ -1,10 +1,10 @@
 /* global describe, it */
 var assert = require("assert");
 var fs = require('fs');
-var nodefn = require("when/node/function");
 var path = require('path');
 
 var bundler = require('../');
+var P = require('../lib/p');
 
 // ensure that we don't crash on any of our sample inputs
 describe("Basic crash test", function() {
@@ -13,7 +13,7 @@
                        it('should bundle', function(done) {
                                this.timeout(0);
                                var filename = path.join(__dirname, '..', 
'samples', name);
-                               return nodefn.call(fs.readFile.bind(fs), 
filename, 'utf8')
+                               return P.call(fs.readFile, fs, filename, 'utf8')
                                        .then(function(metabook) {
                                                metabook = JSON.parse(metabook);
                                                return bundler.bundle(metabook, 
{

-- 
To view, visit https://gerrit.wikimedia.org/r/96828
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ida24d906a37afa557b9b093f91e4ef038b37d6f1
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Collection/OfflineContentGenerator/bundler
Gerrit-Branch: master
Gerrit-Owner: Cscott <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to