Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 41 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,69 @@
# compass
# compass [![][travis_img]][travis_url]

Explore your MongoDB.
> Explore your MongoDB.

## Developing
## Development

1. Follow the setup instructions for [OSX][setup-osx], [Windows][setup-windows] or [Linux][setup-linux].
2. Clone this repo
2. Run `git clone git@github.com:10gen/compass.git ~/compass` to get the source code
3. Run `npm install` to install dependencies
4. Run `npm start` to launch
4. Run `npm start` to build the app and launch it

## Modules
Already setup and prefer a simple copy and paste?

```bash
git clone git@github.com:10gen/compass.git ~/compass;
cd ~/compass;
npm install;
npm start;
```

## Key Modules

<dl>
<dt><a href="https://github.com/10gen/scout">Compass</a></dt>
<dt><a href="https://magnum.travis-ci.com/10gen/compass"><img src="https://magnum.travis-ci.com/10gen/compass.svg?token=q2zsnxCbboarF6KYRYxM&branch=master" height="10" /></a>&nbsp;<a href="https://github.com/10gen/compass">compass</a> </dt>
<dd>
The default Ampersand.js single-page application people actually interact with.
<a href="https://github.com/10gen/scout/blob/dev/src/models/scout-client-mixin.js">ScoutClientMixin</a>
connects the <a href="https://github.com/10gen/scout/tree/dev/src/models">models</a> to
<a href="https://github.com/mongodb-js/scout-client">scout-client</a>.
</dd>
<dt><a href="https://github.com/mongodb-js/scout-brain">scout-brain</a></dt>
<dt><a href="https://magnum.travis-ci.com/10gen/scout-client"><img src="https://magnum.travis-ci.com/10gen/scout-client.svg?token=q2zsnxCbboarF6KYRYxM&branch=master" height="10" /></a>&nbsp;<a href="https://github.com/10gen/scout-client">scout-client</a></dt>
<dd>
Needs to be broken down into topic based models but for now, this is where
all the business logic code lives we want to share between modules running
in the browser, nodejs, or electron.
Provides a clean API for `compass` to talk to `scout-server` that works in the browser, nodejs, or electron.
</dd>
<dt><a href="https://github.com/mongodb-js/scout-client">scout-client</a></dt>
<dt><a href="https://magnum.travis-ci.com/10gen/scout-server"><img src="https://magnum.travis-ci.com/10gen/scout-server.svg?token=q2zsnxCbboarF6KYRYxM&branch=master" height="10" /></a>&nbsp;<a href="https://github.com/10gen/scout-server">scout-server</a></dt>
<dd>
Provides a clean API for <a href="https://github.com/mongodb-js/scout-server">scout-server</a>
that works in the browser, nodejs, or electron.
An express.js application which provides REST and socket.io endpoints
to the mongodb node.js driver.
</dd>
<dt><a href="https://github.com/mongodb-js/scout-server">scout-server</a></dt>
<dt><a href="https://travis-ci.org/mongodb-js/mongodb-connection-model"><img src="https://secure.travis-ci.org/mongodb-js/mongodb-connection-model.svg?branch=master" height="10" /></a>&nbsp;<a href="https://github.com/mongodb-js/mongodb-connection-model">mongodb-connection-model</a></dt>
<dd>
An express.js application which provides REST and socket.io connectivity
to the mongodb node.js driver.
A shared Ampersand.js model used by `compass`, `scout-client`, and `scout-server` that encapsulates
all of the business logic for generating valid parameters to hand to the driver to connect to MongoDB.
</dd>
<dt><a href="https://travis-ci.org/mongodb-js/mongodb-collection-sample"><img src="https://secure.travis-ci.org/mongodb-js/mongodb-collection-sample.svg?branch=master" height="10" /></a>&nbsp;<a href="https://github.com/mongodb-js/mongodb-collection-sample">mongodb-collection-sample</a></dt>
<dd>
Provides a single interface for `scout-server` to request a sample of documents from a collection that automatically uses the `$sample` operator if available, falling back to a client-side reservoir sample.
</dd>
<dt><a href="https://travis-ci.org/mongodb-js/mongodb-schema"><img src="https://secure.travis-ci.org/mongodb-js/mongodb-schema.svg?branch=master" height="10" /></a>&nbsp;<a href="https://github.com/mongodb-js/mongodb-schema">mongodb-schema</a></dt>
<dd>
`compass` uses `scout-client` to get a sample of documents from `scout-server` via `mongodb-collection-sample` which is piped into `mongodb-schema` to create a probabilistic representation of what the schema for a given collection most likely is.
</dd>
</dl>


## Building Releases

To compile electron + the app and the installer for your current platform:
After you've made some local changes, the next thing you'll probably want to do
is create an artifact to share. There is only one command you need to run to compile the app,
sign it if the signing certificate is available on your machine, and generate a single file
installer for your current platform:

```bash
npm run release
cd ~/compass;
npm run release;
```

[setup-osx]: https://github.com/mongodb-js/mongodb-js/blob/master/docs/setup.md#osx-setup
[setup-windows]: https://github.com/mongodb-js/mongodb-js/blob/master/docs/setup.md#windows-setup
[setup-linux]: https://github.com/mongodb-js/mongodb-js/blob/master/docs/setup.md#linux-setup
[travis_img]: https://magnum.travis-ci.com/10gen/compass.svg?token=q2zsnxCbboarF6KYRYxM&branch=master
[travis_url]: https://magnum.travis-ci.com/10gen/compass
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"fonts/*"
],
"browserify": {
"debug": true,
"entries": [
"./src/index.js"
]
Expand Down Expand Up @@ -92,6 +93,7 @@
"bootstrap": "https://github.com/twbs/bootstrap/archive/v3.3.5.tar.gz",
"browserify": "^10.2.4",
"bugsnag-js": "^2.4.8",
"chalk": "^1.1.1",
"d3": "^3.5.5",
"del": "^1.2.0",
"domready": "^1.0.8",
Expand All @@ -101,6 +103,7 @@
"eslint": "^0.24.1",
"eslint-config-mongodb-js": "^0.1.4",
"event-stream": "^3.3.1",
"figures": "^1.4.0",
"font-awesome": "https://github.com/FortAwesome/Font-Awesome/archive/v4.3.0.tar.gz",
"glob": "^5.0.14",
"gulp": "^3.9.0",
Expand Down
144 changes: 114 additions & 30 deletions tasks/darwin.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
var path = require('path');
var pkg = require(path.resolve(__dirname, '../package.json'));
var fs = require('fs');
var cp = require('child_process');
var run = require('./run');
var format = require('util').format;
var chalk = require('chalk');
var figures = require('figures');
var series = require('run-series');
var _ = require('lodash');
var packager = require('electron-packager');
var createDMG = require('electron-installer-dmg');

var debug = require('debug')('scout:tasks:darwin');

var NAME = pkg.product_name;
var PACKAGE = path.join('dist', NAME + '-darwin-x64');
var APP_PATH = path.join(PACKAGE, NAME + '.app');

var packager = require('electron-packager');
var createDMG = require('electron-installer-dmg');

module.exports.ELECTRON = path.join(APP_PATH, 'Contents', 'MacOS', 'Electron');
module.exports.RESOURCES = path.join(APP_PATH, 'Contents', 'Resources');

Expand All @@ -29,7 +31,6 @@ var PACKAGER_CONFIG = {
prune: true,
'app-bundle-id': 'com.mongodb.compass',
'app-version': pkg.version,
sign: '90E39AA7832E95369F0FC6DAF823A04DFBD9CF7A',
protocols: [
{
name: 'MongoDB Prototcol',
Expand All @@ -38,11 +39,6 @@ var PACKAGER_CONFIG = {
]
};

// Adjust config via environment variables
if (process.env.SCOUT_INSTALLER_UNSIGNED !== undefined) {
PACKAGER_CONFIG.sign = null;
}

// @todo (imlucas): Standardize `electron-installer-dmg`
// options w/ `electron-installer-squirrel-windows`.
var INSTALLER_CONFIG = {
Expand All @@ -69,39 +65,127 @@ var INSTALLER_CONFIG = {
]
};

module.exports.build = function(done) {
fs.exists(APP_PATH, function(exists) {
if (exists) {
debug('.app already exists. skipping packager run.');
return done();
var CODESIGN_IDENTITY_COMMON_NAME = 'Developer ID Application: Matt Kangas (ZD3CL9MT3L)';
var CODESIGN_IDENTITY_SHA1 = '90E39AA7832E95369F0FC6DAF823A04DFBD9CF7A';

/**
* Checks if the current environment can actually sign builds.
* If signing can be done, `electron-packager`'s config will
* be updated to sign artifacts. If not, gracefully degrade
*
* @param {Function} fn - Callback.
*/
function addCodesignIdentityIfAvailable(fn) {
run('certtool', ['y'], function(err, output) {
if (err) {
debug('Failed to list certificates. Build will not be signed.');
fn();
return;
}
debug('running packager to create electron binaries...');
packager(PACKAGER_CONFIG, done);
if (output.indexOf(CODESIGN_IDENTITY_COMMON_NAME) === -1) {
debug('Signing identity `%s` not detected. Build will not be signed.',
CODESIGN_IDENTITY_COMMON_NAME);
fn();
return;
}

PACKAGER_CONFIG.sign = CODESIGN_IDENTITY_SHA1;
debug('The signing identity `%s` is available! '
+ 'This build will be signed!', CODESIGN_IDENTITY_COMMON_NAME);

console.log(chalk.green.bold(figures.tick),
format(' This build will be signed using the `%s` signing identity',
CODESIGN_IDENTITY_COMMON_NAME));
fn();
});
};
}

module.exports.build = function(done) {
addCodesignIdentityIfAvailable(function(err) {
if (err) return done(err);

var verify = function(done) {
var cmd = 'codesign --verify "' + APP_PATH + '"';
debug('Verifying `%s` has been signed...', APP_PATH);
cp.exec(cmd, done);
fs.exists(APP_PATH, function(exists) {
if (exists && process.env.NODE_ENV !== 'production') {
debug('.app already exists. skipping packager run.');
return done();
}
debug('running electron-packager...');
packager(PACKAGER_CONFIG, done);
});
});
};

module.exports.installer = function(done) {
debug('creating installer...');
/**
* If the app is supposed to be signed, verify that
* the signing was actually completed correctly.
* If signing is not available, print helpful details
* on working with unsigned builds.
*
* @param {Function} done - Callback which receives `(err)`.
*/
function verify(done) {
if (!PACKAGER_CONFIG.sign) {
console.error(chalk.yellow.bold(figures.warning),
' User confusion ahead!');

var tasks = [];
if (PACKAGER_CONFIG.sign) {
tasks.push(verify);
console.error(chalk.gray(
' The default preferences for OSX Gatekeeper will not',
'allow users to run unsigned applications.'));

console.error(chalk.gray(
' However, we\'re going to continue building',
'the app and an installer because you\'re most likely'));

console.error(chalk.gray(
' a developer trying to test',
'the app\'s installation process.'));

console.error(chalk.gray(
' For more information on OSX Gatekeeper and how to change your',
'system preferences to run unsigned applications,'));
console.error(chalk.gray(' please see',
'https://support.apple.com/en-us/HT202491'));
debug('Build is not signed. Skipping codesign verification.');
process.nextTick(done);
return;
}

tasks.push(_.partial(createDMG, INSTALLER_CONFIG));
debug('Verifying `%s` has been signed correctly...', APP_PATH);
run('codesign', ['--verify', APP_PATH], function(err) {
if (err) {
err = new Error('App is not correctly signed');
done(err);
return;
}
debug('Verified that the app has been signed correctly!');
done();
});
}

/**
* Package the application as a single `.DMG` file which
* is the OSX equivalent of a `Setup.exe` installer.
*
* @param {Function} done - Callback which receives `(err)`.
*/
module.exports.installer = function(done) {
debug('creating installer...');

var tasks = [
verify,
_.partial(createDMG, INSTALLER_CONFIG)
];

series(tasks, function(err) {
if (err) {
console.error(err.stack);
console.error(chalk.red.bold(figures.cross),
'Failed to create DMG installer:', err.message);
console.error(chalk.gray(err.stack));
return done(err);
}
console.log('Installer created!');
console.log(chalk.green.bold(figures.tick),
' DMG installer written to',
path.join(INSTALLER_CONFIG.out, INSTALLER_CONFIG.name + '.dmg'));
done();
});
};
Loading