Skip to content

Commit

Permalink
(#4449) - add custom builds
Browse files Browse the repository at this point in the history
  • Loading branch information
nolanlawson committed Oct 11, 2015
1 parent a1dcfcb commit d2bb71c
Show file tree
Hide file tree
Showing 29 changed files with 449 additions and 31 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -3,6 +3,7 @@ tmp
node_modules
docs/_site
docs/static/css
docs/static/js/custom
npm-debug.log
*~
coverage
Expand Down
2 changes: 1 addition & 1 deletion .npmignore
Expand Up @@ -9,4 +9,4 @@ tests/cordova/www
.idea
phantomjsdriver.log
bower_components
./docs/
./docs/
19 changes: 19 additions & 0 deletions CONTRIBUTING.md
Expand Up @@ -101,6 +101,24 @@ The source for the website http://pouchdb.com is stored inside the `docs` direct

You should now find the documentation at http://127.0.0.1:4000

Note that you also need to build the custom builds for the "Custom Builds" page.
You can do so by running:

$ npm run build-custom

If you don't do this, then `npm run build-site` will fail. Note that this step
takes a few minutes.

Also, if you want to only publish the builds for the *last* build (not the master
branch), then these are checked in to Git using a special tag,
`$VERSION-with-custom`.

So you can do

$ git checkout origin/refs/tags/$VERSION-with-custom -- docs/static/js/custom

in order to check them out.

Writing a PouchDB Blog Post
--------------------------------------

Expand Down Expand Up @@ -145,4 +163,5 @@ Release Procedure
* Put the new prerelease version in `lib/version-browser.js` too
* Update docs/_config.yml to the current version
* Push updated versions to master
* Check out the custom builds using `git checkout $VERSION-with-custom -- docs/static/js/custom`
* `npm run publish-site`
119 changes: 119 additions & 0 deletions bin/build-custom-builds.js
@@ -0,0 +1,119 @@
#!/usr/bin/env node

'use strict';

var TARGET_DIR = __dirname + '/../docs/static/js/custom';
var NUM_CONCURRENT_PROMISES = require('os').cpus().length;

var combinations = require('combinations');
var browserify = require('browserify');
var bluebird = require('bluebird');
var fs = bluebird.promisifyAll(require('fs'));
var rimraf = require('rimraf');
var rimrafAsync = bluebird.promisify(rimraf);
var mkdirp = require('mkdirp');
var streamToPromise = require('stream-to-promise');
var uglify = require('uglify-js');
var zlib = bluebird.promisifyAll(require('zlib'));
var options = require('../lib/custom/options');
var generateName = require('../lib/custom/generateName');
var generateCode = require('../lib/custom/generateCode');

rimraf.sync(TARGET_DIR);
mkdirp.sync(TARGET_DIR);

function build(comboName, code) {
var sourceFile = TARGET_DIR + '/pouchdb-custom-source-' + comboName + '.js';
var targetFile = TARGET_DIR + '/pouchdb-custom-' + comboName + '.js';
var targetMinFile = TARGET_DIR + '/pouchdb-custom-' + comboName + '.min.js';

var relativeCode = code.replace(/require\('pouchdb/g,
'require(\'../../../..');

return fs.writeFileAsync(sourceFile, relativeCode, 'utf8').then(function () {
var b = browserify(sourceFile, {
standalone: 'PouchDB'
}).plugin('bundle-collapser/plugin');
var stream = b.bundle().pipe(fs.createWriteStream(targetFile));
return streamToPromise(stream);
}).then(function () {
var uglified = uglify.minify(targetFile, {
mangle: true,
compress: {}
});
return fs.writeFileAsync(targetMinFile, uglified.code, 'utf8');
}).then(function () {
return rimrafAsync(sourceFile);
}).then(function () {
return bluebird.all([
fs.statAsync(targetFile),
fs.statAsync(targetMinFile),
bluebird.resolve().then(function () {
var stream = fs.createReadStream(targetMinFile)
.pipe(zlib.createGzip());
return streamToPromise(stream);
})
]).then(function (arr) {
var size = arr[0].size;
var sizeMin = arr[1].size;
var gzipped = arr[2];
return {
size: size,
sizeMin: sizeMin,
sizeGzipped: gzipped.length
};
});
});
}

// don't overload the user's CPU, but also don't try to do absolutely
// everything at once. it's a better UX to see a little bit of progress
function createPromiseChains() {
var promises = [];
for (var i = 0; i < NUM_CONCURRENT_PROMISES; i++) {
promises.push(bluebird.resolve());
}
return promises;
}

var combos = combinations(options);
combos.unshift([]); // add an empty one as well, at the beginning
var builtInfo = {};
var promises = createPromiseChains();
var numDone = 0;
var promiseIndex = 0;

function buildPromise(combo, comboName, code) {
var debuggableComboName = combo.map(function (x) {
return x.name;
});
return function () {
return build(comboName, code).then(function (info) {
console.log('Built custom build',
JSON.stringify(debuggableComboName),
'with ID',
comboName,
'(' + (++numDone) + '/' + combos.length +')...');
builtInfo[comboName] = info;
});
};
}

console.log('Building with', promises.length, 'concurrent promises...');

combos.forEach(function (combo) {
var comboName = generateName(combo);
var code = generateCode(combo);
promises[promiseIndex] = promises[promiseIndex].then(
buildPromise(combo, comboName, code));
if (++promiseIndex === promises.length) {
promiseIndex = 0;
}
});

bluebird.all(promises).then(function () {
return fs.writeFileAsync(TARGET_DIR + '/info.js',
'window.customBuildsInfo = ' +
JSON.stringify(builtInfo) +
';', 'utf8');
});
10 changes: 10 additions & 0 deletions bin/build-site.js
Expand Up @@ -9,6 +9,7 @@ var watchGlob = require('watch-glob');
var replace = require('replace');
var exec = require('child-process-promise').exec;
var mkdirp = require('mkdirp');
var yaml = require('js-yaml');

var POUCHDB_CSS = __dirname + '/../docs/static/css/pouchdb.css';
var POUCHDB_LESS = __dirname + '/../docs/static/less/pouchdb/pouchdb.less';
Expand Down Expand Up @@ -77,6 +78,15 @@ if (!process.env.BUILD) {
watchGlob('docs/static/less/*/*.less', buildCSS);
http_server.createServer({root: '_site', cache: '-1'}).listen(4000);
console.log('Server address: http://0.0.0.0:4000');
if (!fs.existsSync(__dirname + '/../docs/static/js/custom')) {
var version = yaml.safeLoad(fs.readFileSync(__dirname +
'/../docs/_config.yml', 'utf8')).version;
var msg = 'You need to do `npm run build-custom` beforehand ' +
'to build the builder UI, or check out the builds from Git using ' +
'`git checkout origin/refs/tags/' + version +
'-with-custom -- docs/static/js/custom`';
throw new Error(msg);
}
}

buildEverything();
8 changes: 8 additions & 0 deletions bin/release.sh
Expand Up @@ -26,6 +26,14 @@ git commit -m "build $VERSION"
git tag $VERSION
git push --tags git@github.com:pouchdb/pouchdb.git $VERSION

# Build the site and custom builds for posterity
npm run build-custom
BUILD=1 npm run build-site
git add -f docs
git commit -m "build $VERSION with custom builds"
git tag ${VERSION}-with-custom
git push --tags git@github.com:pouchdb/pouchdb.git $VERSION-with-custom

# Cleanup
git checkout master
git branch -D build
11 changes: 11 additions & 0 deletions custom/http.js
@@ -0,0 +1,11 @@
'use strict';

var PouchDB = require('./pouchdb');

// Some tests explicitly override this; also it's useful to have
// it attached to utils for the custom builds, although it's a little awkward.
PouchDB.ajax = PouchDB.utils.ajax = require('../lib/deps/ajax/prequest');

var httpAdapter = require('../lib/adapters/http');
PouchDB.adapter('http', httpAdapter);
PouchDB.adapter('https', httpAdapter);
6 changes: 6 additions & 0 deletions custom/idb.js
@@ -0,0 +1,6 @@
'use strict';

var PouchDB = require('./pouchdb');

var idb = require('../lib/adapters/idb');
PouchDB.adapter('idb', idb, true);
6 changes: 6 additions & 0 deletions custom/leveldb.js
@@ -0,0 +1,6 @@
'use strict';

var PouchDB = require('./pouchdb');

var level = require('../lib/adapters/leveldb');
PouchDB.adapter('leveldb', level, true);
5 changes: 5 additions & 0 deletions custom/mapreduce.js
@@ -0,0 +1,5 @@
'use strict';

var PouchDB = require('./pouchdb');

PouchDB.plugin(require('../lib/mapreduce'));
9 changes: 9 additions & 0 deletions custom/pouchdb.js
@@ -0,0 +1,9 @@
'use strict';

var PouchDB = require('../lib/setup');

PouchDB.utils = require('../lib/utils');
PouchDB.Errors = require('../lib/deps/errors');
PouchDB.version = require('../lib/version');

module.exports = PouchDB;
6 changes: 6 additions & 0 deletions custom/replication.js
@@ -0,0 +1,6 @@
'use strict';

var PouchDB = require('./pouchdb');

PouchDB.replicate = require('../lib/replicate').replicate;
PouchDB.sync = require('../lib/sync');
6 changes: 6 additions & 0 deletions custom/websql.js
@@ -0,0 +1,6 @@
'use strict';

var PouchDB = require('./pouchdb');

var websql = require('../lib/adapters/websql');
PouchDB.adapter('websql', websql, true);
23 changes: 23 additions & 0 deletions docs/_includes/custom_builds.html
@@ -0,0 +1,23 @@
<div id="custom-builder">
<div>
<div id="custom-options">
</div>
</div>
<div>
<pre><code id="custom-code"></code></pre>
<div id="custom-buttons">
<div>
<a id="download-custom" class="btn btn-primary" href="#">
Download
</a>
</div>
<div>
<a id="download-custom-min" class="btn btn-primary" href="#">
Download min
</a>
</div>
</div>
</div>
</div>

<script src="static/js/custom/builder.js"></script>
1 change: 1 addition & 0 deletions docs/_includes/nav.html
Expand Up @@ -4,5 +4,6 @@
{% include nav_item.html path="/api.html" text="API" %}
{% include nav_item.html path="/adapters.html" text="Adapters" %}
{% include nav_item.html path="/external.html" text="Plugins" %}
{% include nav_item.html path="/custom-builds.html" text="Custom Builds" %}
{% include nav_item.html path="/faq.html" text="FAQ" %}
{% include nav_item.html path="/errors.html" text="Common Errors" %}
1 change: 1 addition & 0 deletions docs/_layouts/default.html
Expand Up @@ -187,6 +187,7 @@ <h3 class="nav-head">Contribute</h3>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script type="text/javascript" src="{{ site.baseurl }}/static/js/code.min.js"></script>
<script type="text/javascript" src="http://cdn.jsdelivr.net/pouchdb/latest/pouchdb.min.js"></script>
<script type="text/javascript" src="{{ site.baseurl }}/static/js/custom/info.js"></script>
<script type="text/javascript">
$('[data-toggle="tooltip"]').tooltip();
function onCached(e) {
Expand Down
13 changes: 13 additions & 0 deletions docs/custom-builds.md
@@ -0,0 +1,13 @@
---
layout: 2ColLeft
title: Custom Builds
sidebar: nav.html
---

PouchDB supports custom builds! You can use exclude the parts of
PouchDB you're not using, and then either download it from this page, or
include it in your project as a
[Browserifiable](http://browserify.com/)/[Webpackable](http://webpack.github.io/)
script.

{% include custom_builds.html %}
3 changes: 3 additions & 0 deletions docs/manifest.appcache
Expand Up @@ -15,6 +15,8 @@ CACHE:
/static/css/pouchdb.css
/static/favicon.ico
/static/js/code.min.js
/static/js/custom/info.js
/static/js/custom/builder.js

http://code.jquery.com/jquery.min.js
http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js
Expand Down Expand Up @@ -55,6 +57,7 @@ http://fonts.gstatic.com/s/opensans/v10/k3k702ZOKiLJc3WVjuplzBampu5_7CjHW5spxoeN
/static/img/browser-logos/opera_32x32.png
/static/img/browser-logos/safari_32x32.png


NETWORK:
*
http://*
Expand Down
44 changes: 44 additions & 0 deletions docs/static/less/pouchdb/custom-builder.less
@@ -0,0 +1,44 @@
#custom-builder {
display: flex;
width: 100%;
margin-top: 30px;
}

#custom-builder > div:first-child {
margin-right:5px;
flex: 1;
}

#custom-builder > div:last-child {
flex: 2;
}

#custom-options label {
margin-left: 20px;
font-size: 16px;
}

#custom-buttons {
display: flex;
width: 100%;
}

#custom-buttons > div:first-child {
margin-right:5px;
}

#custom-buttons > div {
flex-grow: 1;
flex-shrink: 1;
}

#custom-buttons a {
width: 100%;
}

.custom-option-info {
color: #333;
font-style: italic;
margin: 5px 20px 5px;
font-size: 12px;
}
3 changes: 3 additions & 0 deletions docs/static/less/pouchdb/pouchdb.less
Expand Up @@ -45,3 +45,6 @@
@import "icons.less";
@import "block.less";
@import "icon-edit.less";

// Custom builder UI
@import "custom-builder.less";

0 comments on commit d2bb71c

Please sign in to comment.