src/plugins/meteor/build.js
import debug from 'debug';
import fs from 'fs';
import rimraf from 'rimraf';
import { spawn } from 'child_process';
import tar from 'tar';
const log = debug('mup:module:meteor');
export default function buildApp(appPath, buildOptions, verbose, api) {
// Check if the folder exists
try {
fs.statSync(api.resolvePath(appPath));
} catch (e) {
if (e.code === 'ENOENT') {
console.log(`${api.resolvePath(appPath)} does not exist`);
} else {
console.log(e);
}
process.exit(1);
}
// Make sure it is a Meteor app
try {
// checks for release file since there also is a
// .meteor folder in the user's home
fs.statSync(api.resolvePath(appPath, '.meteor/release'));
} catch (e) {
console.log(`${api.resolvePath(appPath)} is not a meteor app`);
process.exit(1);
}
return new Promise((resolve, reject) => {
const callback = err => {
if (err) {
reject(err);
return;
}
resolve();
};
buildMeteorApp(appPath, buildOptions, code => {
if (code === 0) {
callback();
return;
}
console.log('\n=> Build Error. Check the logs printed above.');
process.exit(1);
});
});
}
function createBuildArgs(buildOptions, appPath) {
const args = [
'build',
'--directory',
buildOptions.buildLocation,
'--architecture',
'os.linux.x86_64'
];
if (buildOptions.debug) {
args.push('--debug');
}
if (buildOptions.mobileSettings) {
args.push('--mobile-settings');
args.push(JSON.stringify(buildOptions.mobileSettings));
}
if (buildOptions.serverOnly) {
args.push('--server-only');
} else if (!buildOptions.mobileSettings) {
args.push('--mobile-settings');
args.push(`${appPath}/settings.json`);
}
if (buildOptions.server) {
args.push('--server');
args.push(buildOptions.server);
}
if (buildOptions.allowIncompatibleUpdate) {
args.push('--allow-incompatible-update');
}
return args;
}
function buildMeteorApp(appPath, buildOptions, callback) {
let executable = buildOptions.executable || 'meteor';
let args = createBuildArgs(buildOptions, appPath);
const isWin = /^win/.test(process.platform);
if (isWin) {
// Sometimes cmd.exe is not available in the path
// See: http://goo.gl/ADmzoD
args = ['/c', executable].concat(args);
executable = process.env.comspec || 'cmd.exe';
}
const options = {
cwd: appPath,
env: {
...process.env,
METEOR_HEADLESS: 1
},
stdio: [process.stdin, process.stdout, process.stderr]
};
log(`Build Path: ${appPath}`);
log(`Build Command: ${executable} ${args.join(' ')}`);
const meteor = spawn(executable, args, options);
meteor.on('error', e => {
console.log(options);
console.log(e);
console.log('This error usually happens when meteor is not installed.');
});
meteor.on('close', callback);
}
export function archiveApp(buildLocation, api, cb) {
const bundlePath = api.resolvePath(buildLocation, 'bundle.tar.gz');
log('starting archive');
tar.c({
file: bundlePath,
onwarn(message, data) { console.log(message, data); },
cwd: buildLocation,
portable: true,
gzip: {
level: 9
}
}, ['bundle'], err => {
log('archive finished');
if (err) {
console.log('=> Archiving failed: ', err.message);
}
cb(err);
});
}
export function cleanBuildDir(buildLocation) {
return new Promise((resolve, reject) => {
rimraf(buildLocation, {
glob: false
}, err => {
if (err) {
return reject(err);
}
return resolve();
});
});
}