diff --git a/decl/bluebird.js b/decl/bluebird.js deleted file mode 100644 index a146f420..00000000 --- a/decl/bluebird.js +++ /dev/null @@ -1,4 +0,0 @@ -// @flow -declare module 'bluebird' { - declare var exports: typeof Promise; -} diff --git a/package.json b/package.json index 5a41c04d..78751c5b 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "dependencies": { "ansi-regex": "2.0.0", "babel-eslint": "6.1.2", - "bluebird": "3.4.1", "chalk": "1.1.3", "commander": "2.9.0", "eslint": "3.2.2", diff --git a/scripts/build/cli.js b/scripts/build/cli.js index 4a751882..ba45ba1a 100644 --- a/scripts/build/cli.js +++ b/scripts/build/cli.js @@ -5,7 +5,7 @@ require('../../lib/babel-hook'); const path = require('path'); const rollup = require('rollup').rollup; -const fs = require('../../src/packages/fs').default; +const fs = require('../../src/packages/fs'); const dist = path.join(__dirname, '..', '..', 'dist'); const config = require('./config'); const commands = path.join( @@ -18,7 +18,7 @@ const commands = path.join( 'commands' ); -fs.readdirAsync(commands) +fs.readdir(commands) .then(files => { return Promise.all( files.map(file => { diff --git a/src/packages/cli/commands/create.js b/src/packages/cli/commands/create.js index af83df7d..b1865ae7 100644 --- a/src/packages/cli/commands/create.js +++ b/src/packages/cli/commands/create.js @@ -3,7 +3,7 @@ import { green } from 'chalk'; import { CWD } from '../../../constants'; -import fs from '../../fs'; +import { mkdir, writeFile } from '../../fs'; import template from '../../template'; import exec from '../../../utils/exec'; @@ -30,101 +30,88 @@ export async function create(name, database) { const driver = driverFor(database); const project = `${CWD}/${name}`; - await fs.mkdirAsync(project); + await mkdir(project); await Promise.all([ - fs.mkdirAsync(`${project}/app`), - fs.mkdirAsync(`${project}/config`), - fs.mkdirAsync(`${project}/db`) + mkdir(`${project}/app`), + mkdir(`${project}/config`), + mkdir(`${project}/db`) ]); await Promise.all([ - fs.mkdirAsync(`${project}/app/models`), - fs.mkdirAsync(`${project}/app/serializers`), - fs.mkdirAsync(`${project}/app/controllers`), - fs.mkdirAsync(`${project}/app/middleware`), - fs.mkdirAsync(`${project}/app/utils`), - fs.mkdirAsync(`${project}/config/environments`), - fs.mkdirAsync(`${project}/db/migrate`) + mkdir(`${project}/app/models`), + mkdir(`${project}/app/serializers`), + mkdir(`${project}/app/controllers`), + mkdir(`${project}/app/middleware`), + mkdir(`${project}/app/utils`), + mkdir(`${project}/config/environments`), + mkdir(`${project}/db/migrate`) ]); await Promise.all([ - fs.writeFileAsync( + writeFile( `${project}/app/index.js`, - appTemplate(name), - 'utf8' + appTemplate(name) ), - fs.writeFileAsync( + writeFile( `${project}/app/routes.js`, - routesTemplate(), - 'utf8' + routesTemplate() ), - fs.writeFileAsync( + writeFile( `${project}/config/environments/development.js`, - configTemplate(name, 'development'), - 'utf8' + configTemplate(name, 'development') ), - fs.writeFileAsync( + writeFile( `${project}/config/environments/test.js`, - configTemplate(name, 'test'), - 'utf8' + configTemplate(name, 'test') ), - fs.writeFileAsync( + writeFile( `${project}/config/environments/production.js`, - configTemplate(name, 'production'), - 'utf8' + configTemplate(name, 'production') ), - fs.writeFileAsync( + writeFile( `${project}/config/database.js`, - dbTemplate(name, driver), - 'utf8' + dbTemplate(name, driver) ), - fs.writeFileAsync( + writeFile( `${project}/db/seed.js`, - seedTemplate(), - 'utf8' + seedTemplate() ), - fs.writeFileAsync( + writeFile( `${project}/README.md`, - readmeTemplate(name), - 'utf8' + readmeTemplate(name) ), - fs.writeFileAsync( + writeFile( `${project}/LICENSE`, - licenseTemplate(), - 'utf8' + licenseTemplate() ), - fs.writeFileAsync( + writeFile( `${project}/package.json`, - pkgJSONTemplate(name, database), - 'utf8' + pkgJSONTemplate(name, database) ), - fs.writeFileAsync( + writeFile( `${project}/.babelrc`, - babelrcTemplate(), - 'utf8' + babelrcTemplate() ), - fs.writeFileAsync( + writeFile( `${project}/.eslintrc.json`, - eslintrcTemplate(), - 'utf8' + eslintrcTemplate() ), - fs.writeFileAsync( + writeFile( `${project}/.gitignore`, - gitignoreTemplate(), - 'utf8' + gitignoreTemplate() ) ]); diff --git a/src/packages/cli/commands/dbcreate.js b/src/packages/cli/commands/dbcreate.js index a554f4f4..52c37f95 100644 --- a/src/packages/cli/commands/dbcreate.js +++ b/src/packages/cli/commands/dbcreate.js @@ -1,7 +1,8 @@ import { CWD, NODE_ENV } from '../../../constants'; -import fs from '../../fs'; + import loader from '../../loader'; import { connect } from '../../database'; +import { writeFile } from '../../fs'; /** * @private @@ -18,7 +19,7 @@ export async function dbcreate() { } = loader(CWD, 'config'); if (driver === 'sqlite3') { - await fs.writeFileAsync(`${CWD}/db/${database}_${NODE_ENV}.sqlite`, ''); + await writeFile(`${CWD}/db/${database}_${NODE_ENV}.sqlite`, ''); } else { const { schema } = connect(CWD, { ...config, driver }); const query = schema.raw(`CREATE DATABASE ${database}`); diff --git a/src/packages/cli/commands/dbrollback.js b/src/packages/cli/commands/dbrollback.js index 0f30ad18..bcbaf304 100644 --- a/src/packages/cli/commands/dbrollback.js +++ b/src/packages/cli/commands/dbrollback.js @@ -1,8 +1,9 @@ import { CWD } from '../../../constants'; + import Database from '../../database'; import Logger, { sql } from '../../logger'; -import fs from '../../fs'; import loader from '../../loader'; +import { readdir } from '../../fs'; /** * @private @@ -23,7 +24,7 @@ export async function dbrollback() { }) }); - const migrationFiles = await fs.readdirAsync(`${CWD}/db/migrate`); + const migrationFiles = await readdir(`${CWD}/db/migrate`); if (migrationFiles.length) { let migration; diff --git a/src/packages/cli/commands/destroy.js b/src/packages/cli/commands/destroy.js index 01bb4475..74d6f839 100644 --- a/src/packages/cli/commands/destroy.js +++ b/src/packages/cli/commands/destroy.js @@ -2,7 +2,7 @@ import { CWD } from '../../../constants'; import { red, green } from 'chalk'; import { pluralize, singularize } from 'inflection'; -import fs, { rmrf, exists } from '../../fs'; +import { rmrf, exists, readdir, readFile, writeFile } from '../../fs'; /** * @private @@ -20,7 +20,7 @@ export async function destroyType(type, name) { break; case 'migration': - migrations = await fs.readdirAsync(`${CWD}/db/migrate`); + migrations = await readdir(`${CWD}/db/migrate`); name = migrations.find(file => `${name}.js` === file.substr(17)); path = `db/migrate/${name}`; break; @@ -54,7 +54,7 @@ export async function destroy({ type, name }: { name: string; }) { if (type === 'resource') { - const routes = (await fs.readFileAsync(`${CWD}/app/routes.js`, 'utf8')) + const routes = (await readFile(`${CWD}/app/routes.js`, 'utf8')) .split('\n') .reduce((lines, line) => { const pattern = new RegExp( @@ -72,7 +72,7 @@ export async function destroy({ type, name }: { destroyType('controller', name) ]); - await fs.writeFileAsync(`${CWD}/app/routes.js`, routes, 'utf8'); + await writeFile(`${CWD}/app/routes.js`, routes); console.log(`${green('update')} app/routes.js`); } else if (type === 'model') { await Promise.all([ diff --git a/src/packages/cli/commands/generate.js b/src/packages/cli/commands/generate.js index 46dfc84c..aaf5059d 100644 --- a/src/packages/cli/commands/generate.js +++ b/src/packages/cli/commands/generate.js @@ -3,8 +3,9 @@ import { pluralize, singularize } from 'inflection'; import { createInterface } from 'readline'; import { CWD } from '../../../constants'; -import fs, { rmrf, exists } from '../../fs'; + import { generateTimestamp } from '../../database'; +import { rmrf, exists, readdir, readFile, writeFile } from '../../fs'; import modelTemplate from '../templates/model'; import serializerTemplate from '../templates/serializer'; @@ -105,7 +106,7 @@ export async function generateType(type, name, cwd, attrs = []) { if (overwrite) { if (isMigration) { - const migrations = await fs.readdirAsync(`${cwd}/db/migrate`); + const migrations = await readdir(`${cwd}/db/migrate`); const isModelMigration = type === 'model-migration'; const oldName = migrations.find(file => { @@ -120,17 +121,17 @@ export async function generateType(type, name, cwd, attrs = []) { console.log(`${red('remove')} ${oldPath}`); } - await fs.writeFileAsync(`${cwd}/${path}`, data, 'utf8'); + await writeFile(`${cwd}/${path}`, data); console.log(`${green('create')} ${path}`); } else { - await fs.writeFileAsync(`${cwd}/${path}`, data, 'utf8'); + await writeFile(`${cwd}/${path}`, data); console.log(`${yellow('overwrite')} ${path}`); } } else { console.log(`${yellow('skip')} ${path}`); } } else { - await fs.writeFileAsync(`${cwd}/${path}`, data, 'utf8'); + await writeFile(`${cwd}/${path}`, data); console.log(`${green('create')} ${path}`); } @@ -152,7 +153,7 @@ export async function generate({ attrs: Array }) { if (type === 'resource') { - const routes = (await fs.readFileAsync(`${cwd}/app/routes.js`, 'utf8')) + const routes = (await readFile(`${cwd}/app/routes.js`, 'utf8')) .split('\n') .reduce((str, line, index, array) => { const closeIndex = array.lastIndexOf('}'); @@ -173,7 +174,7 @@ export async function generate({ await generateType('serializer', name, cwd, attrs); await generateType('controller', name, cwd, attrs); - await fs.writeFileAsync(`${cwd}/app/routes.js`, routes, 'utf8'); + await writeFile(`${cwd}/app/routes.js`, routes); console.log(`${green('update')} app/routes.js`); } else if (type === 'model') { await generateType(type, name, cwd, attrs); diff --git a/src/packages/compiler/index.js b/src/packages/compiler/index.js index 3ab44af0..38163048 100644 --- a/src/packages/compiler/index.js +++ b/src/packages/compiler/index.js @@ -8,7 +8,7 @@ import nodeResolve from 'rollup-plugin-node-resolve'; import { rollup } from 'rollup'; import { BACKSLASH } from './constants'; -import fs, { rmrf } from '../fs'; +import { rmrf, readdir } from '../fs'; import template from '../template'; import createManifest from './utils/create-manifest'; @@ -33,17 +33,17 @@ export async function compile(dir: string, env: string, { const sourceMapSupport = path.join(luxNodeModules, 'source-map-support'); const external = await Promise.all([ - fs.readdirAsync(nodeModules), - fs.readdirAsync(luxNodeModules), + readdir(nodeModules), + readdir(luxNodeModules) ]).then(([a, b]: [Array, Array]) => { return a.concat(b).filter(name => name !== 'lux-framework'); }); const assets = await Promise.all([ - fs.readdirAsync(path.join(dir, 'app', 'models')), - fs.readdirAsync(path.join(dir, 'app', 'controllers')), - fs.readdirAsync(path.join(dir, 'app', 'serializers')), - fs.readdirAsync(path.join(dir, 'db', 'migrate')), + readdir(path.join(dir, 'app', 'models')), + readdir(path.join(dir, 'app', 'controllers')), + readdir(path.join(dir, 'app', 'serializers')), + readdir(path.join(dir, 'db', 'migrate')) ]).then(([ models, controllers, diff --git a/src/packages/compiler/utils/create-boot-script.js b/src/packages/compiler/utils/create-boot-script.js index 97591c4a..59fa2bec 100644 --- a/src/packages/compiler/utils/create-boot-script.js +++ b/src/packages/compiler/utils/create-boot-script.js @@ -1,8 +1,8 @@ // @flow import path from 'path'; -import fs from '../../fs'; import template from '../../template'; +import { writeFile } from '../../fs'; /** * @private @@ -30,5 +30,5 @@ export default async function createBootScript(dir: string, { data = `'use strict';\n\n${data}`; } - await fs.writeFileAsync(path.join(dir, 'dist', 'boot.js'), data, 'utf8'); + await writeFile(path.join(dir, 'dist', 'boot.js'), data); } diff --git a/src/packages/compiler/utils/create-manifest.js b/src/packages/compiler/utils/create-manifest.js index ed8f5b95..8674b9a6 100644 --- a/src/packages/compiler/utils/create-manifest.js +++ b/src/packages/compiler/utils/create-manifest.js @@ -3,7 +3,7 @@ import { join as joinPath } from 'path'; import { camelize, classify, pluralize } from 'inflection'; import { BACKSLASH } from '../constants'; -import fs from '../../fs'; +import { mkdir, writeFile, appendFile } from '../../fs'; import tryCatch from '../../../utils/try-catch'; import underscore from '../../../utils/underscore'; @@ -36,8 +36,8 @@ export default async function createManifest( const dist = joinPath(dir, 'dist'); const file = joinPath(dist, 'index.js'); - await tryCatch(() => fs.mkdirAsync(dist)); - await fs.writeFileAsync(file, useStrict ? '\'use strict\';\n\n' : '', 'utf8'); + await tryCatch(() => mkdir(dist)); + await writeFile(file, useStrict ? '\'use strict\';\n\n' : ''); for (const [key, value] of assets) { switch (key) { @@ -53,7 +53,7 @@ export default async function createManifest( name += 'Controller'; - await fs.appendFileAsync(file, exportStatement(name, path), 'utf8'); + await appendFile(file, exportStatement(name, path)); } break; @@ -62,7 +62,7 @@ export default async function createManifest( const path = joinPath('app', 'models', name); name = classify(underscore(name.replace(/\.js$/ig, ''))); - await fs.appendFileAsync(file, exportStatement(name, path), 'utf8'); + await appendFile(file, exportStatement(name, path)); } break; @@ -73,13 +73,15 @@ export default async function createManifest( underscore(name.replace(/\.js$/ig, '')).substr(17) , true); - await fs.appendFileAsync(file, + await appendFile( + file, exportStatement(`up as ${name}Up`, path, false) - , 'utf8'); + ); - await fs.appendFileAsync(file, + await appendFile( + file, exportStatement(`down as ${name}Down`, path, false) - , 'utf8'); + ); } break; @@ -95,13 +97,13 @@ export default async function createManifest( name += 'Serializer'; - await fs.appendFileAsync(file, exportStatement(name, path), 'utf8'); + await appendFile(file, exportStatement(name, path)); } break; default: if (typeof value === 'string') { - await fs.appendFileAsync(file, exportStatement(key, value), 'utf8'); + await appendFile(file, exportStatement(key, value)); } } } diff --git a/src/packages/database/utils/pending-migrations.js b/src/packages/database/utils/pending-migrations.js index 0cc62f18..6900c953 100644 --- a/src/packages/database/utils/pending-migrations.js +++ b/src/packages/database/utils/pending-migrations.js @@ -1,5 +1,5 @@ // @flow -import fs from '../../fs'; +import { readdir } from '../../fs'; /** * @private @@ -8,7 +8,7 @@ export default async function pendingMigrations( appPath: string, table: Function ) { - const migrations = await fs.readdirAsync(`${appPath}/db/migrate`); + const migrations = await readdir(`${appPath}/db/migrate`); const versions = await table().select().map(({ version }) => version); return migrations.filter(migration => { diff --git a/src/packages/fs/index.js b/src/packages/fs/index.js index dcf850f0..3b8fd022 100644 --- a/src/packages/fs/index.js +++ b/src/packages/fs/index.js @@ -1,7 +1,94 @@ import fs from 'fs'; -import { promisifyAll } from 'bluebird'; + +import createResolver from './utils/create-resolver'; + +import type { fs$readOpts, fs$writeOpts } from './interfaces'; export { default as rmrf } from './utils/rmrf'; export { default as exists } from './utils/exists'; export { default as isJSFile } from './utils/is-js-file'; -export default promisifyAll(fs); + +/** + * @private + */ +export const { watch } = fs; + +/** + * @private + */ +export function mkdir(path: string, mode: number = 511) { + return new Promise((resolve, reject) => { + fs.mkdir(path, mode, createResolver(resolve, reject)); + }); +} + +/** + * @private + */ +export function rmdir(path: string) { + return new Promise((resolve, reject) => { + fs.rmdir(path, createResolver(resolve, reject)); + }); +} + +/** + * @private + */ +export function readdir(path: string, opts?: fs$readOpts) { + return new Promise((resolve, reject) => { + fs.readdir(path, opts, createResolver(resolve, reject)); + }); +} + +/** + * @private + */ +export function readFile(path: string, opts?: fs$readOpts) { + return new Promise((resolve, reject) => { + fs.readFile(path, opts, createResolver(resolve, reject)); + }); +} + +/** + * @private + */ +export function writeFile( + path: string, + data: string | Buffer, + opts?: fs$writeOpts +) { + return new Promise((resolve, reject) => { + fs.writeFile(path, data, opts, createResolver(resolve, reject)); + }); +} + +/** + * @private + */ +export function appendFile( + path: string, + data: string | Buffer, + opts?: fs$writeOpts +) { + return new Promise((resolve, reject) => { + fs.appendFile(path, data, opts, createResolver(resolve, reject)); + }); +} + +/** + * @private + */ +export function stat(path: string) { + return new Promise((resolve, reject) => { + fs.stat(path, createResolver(resolve, reject)); + }); +} + +/** + * @private + */ +export function unlink(path: string) { + return new Promise((resolve, reject) => { + fs.unlink(path, createResolver(resolve, reject)); + }); +} diff --git a/src/packages/fs/interfaces.js b/src/packages/fs/interfaces.js new file mode 100644 index 00000000..2a9c96ca --- /dev/null +++ b/src/packages/fs/interfaces.js @@ -0,0 +1,11 @@ +// @flow +export type fs$writeOpts = string | { + mode?: number; + flag?: string; + encoding?: ?string; +}; + +export type fs$readOpts = string | { + flag?: string; + encoding?: ?string; +}; diff --git a/src/packages/fs/utils/create-resolver.js b/src/packages/fs/utils/create-resolver.js new file mode 100644 index 00000000..3c17bdb1 --- /dev/null +++ b/src/packages/fs/utils/create-resolver.js @@ -0,0 +1,19 @@ +// @flow + +/** + * @private + */ +export default function createResolver( + resolve: (data: any) => void, + reject: (err: Error) => void +) { + return function fsResolver(err: ?Error, ...args: Array) { + const [data] = args; + + if (err) { + return reject(err); + } + + resolve(args.length > 1 ? args : data); + }; +} diff --git a/src/packages/fs/utils/exists.js b/src/packages/fs/utils/exists.js index c2e24c4a..b313f1d8 100644 --- a/src/packages/fs/utils/exists.js +++ b/src/packages/fs/utils/exists.js @@ -1,26 +1,24 @@ // @flow -import { stat, readdir } from 'fs'; +import { stat, readdir } from '../index'; + +import tryCatch from '../../../utils/try-catch'; /** * @private */ -export default function exists( - path: string | RegExp, - dir: string -): Promise { - return new Promise((resolve, reject) => { - if (typeof path === 'string') { - stat(path, err => resolve(Boolean(!err))); - } else if (path instanceof RegExp) { - const pattern = path; +export default async function exists(path: string | RegExp, dir: string) { + if (typeof path === 'string') { + return Boolean(await tryCatch(() => stat(path))); + } else if (path instanceof RegExp) { + const pattern = path; + let files = []; - readdir(dir, (err, files) => { - if (err) { - reject(err); - } else { - resolve(files.some(file => pattern.test(file))); - } - }); + if (dir) { + files = await readdir(dir); } - }); + + return files.some(file => pattern.test(file)); + } + + return false; } diff --git a/src/packages/fs/utils/rmrf.js b/src/packages/fs/utils/rmrf.js index 1acbc46a..f1646736 100644 --- a/src/packages/fs/utils/rmrf.js +++ b/src/packages/fs/utils/rmrf.js @@ -1,19 +1,20 @@ // @flow import path from 'path'; -import fs from '../index'; +import { stat, rmdir, readdir, unlink } from '../index'; + import tryCatch from '../../../utils/try-catch'; /** * @private */ -async function rmrf(target: string): Promise { - const stats = await tryCatch(() => fs.statAsync(target)); +async function rmrf(target: string) { + const stats = await tryCatch(() => stat(target)); if (stats && stats.isDirectory()) { - await rmdir(target); + await rmdirRec(target); } else if (stats && stats.isFile()) { - await tryCatch(() => fs.unlinkAsync(target)); + await tryCatch(() => unlink(target)); } return true; @@ -22,8 +23,8 @@ async function rmrf(target: string): Promise { /** * @private */ -async function rmdir(target: string): Promise { - let files = await tryCatch(() => fs.readdirAsync(target)); +async function rmdirRec(target: string) { + let files = await tryCatch(() => readdir(target)); if (files) { files = files.map(file => { @@ -31,7 +32,7 @@ async function rmdir(target: string): Promise { }); await Promise.all(files); - await fs.rmdirAsync(target); + await rmdir(target); } } diff --git a/src/packages/watcher/index.js b/src/packages/watcher/index.js index 2c5af067..5e076ae7 100644 --- a/src/packages/watcher/index.js +++ b/src/packages/watcher/index.js @@ -5,10 +5,12 @@ import { FSWatcher } from 'fs'; import initialize from './initialize'; +import type { Watcher$Client } from './interfaces'; // eslint-disable-line max-len, no-unused-vars + /** * @private */ -class Watcher extends EventEmitter { +class Watcher extends EventEmitter { path: string; client: T; diff --git a/src/packages/watcher/initialize.js b/src/packages/watcher/initialize.js index b0acd134..fc26fc9b 100644 --- a/src/packages/watcher/initialize.js +++ b/src/packages/watcher/initialize.js @@ -1,23 +1,28 @@ +// @flow import { Client } from 'fb-watchman'; import { join as joinPath } from 'path'; +import * as fs from '../fs'; + import exec from '../../utils/exec'; import tryCatch from '../../utils/try-catch'; -import fs, { isJSFile } from '../fs'; -import type Watcher from './'; -import type { FSWatcher } from 'fs'; +import type Watcher from './index'; // eslint-disable-line no-unused-vars +import type { Watcher$Client } from './interfaces'; // eslint-disable-line max-len, no-unused-vars const SUBSCRIPTION_NAME = 'lux-watcher'; /** * @private */ -function fallback(instance: Watcher, path: string): FSWatcher { +function fallback>( + instance: U, + path: string +): T { return fs.watch(path, { recursive: true }, (type, name) => { - if (isJSFile(name)) { + if (fs.isJSFile(name)) { instance.emit('change', [{ name, type }]); } }); @@ -26,7 +31,10 @@ function fallback(instance: Watcher, path: string): FSWatcher { /** * @private */ -function setupWatchmen(instance: Watcher, path: string): Promise { +function setupWatchmen>( // eslint-disable-line max-len, no-unused-vars + instance: U, + path: string +): Promise { return new Promise((resolve, reject) => { const client = new Client(); @@ -93,10 +101,10 @@ function setupWatchmen(instance: Watcher, path: string): Promise { /** * @private */ -export default async function initialize( - instance: Watcher, +export default async function initialize>( // eslint-disable-line max-len, no-unused-vars + instance: U, path: string -): Promise { +): Promise { let client; path = joinPath(path, 'app'); diff --git a/src/packages/watcher/interfaces.js b/src/packages/watcher/interfaces.js new file mode 100644 index 00000000..3eeab47e --- /dev/null +++ b/src/packages/watcher/interfaces.js @@ -0,0 +1,5 @@ +// @flow +import type { FSWatcher } from 'fs'; +import type { Client } from 'fb-watchman'; + +export type Watcher$Client = Client | FSWatcher; diff --git a/src/utils/exec.js b/src/utils/exec.js index b25df637..891cd773 100644 --- a/src/utils/exec.js +++ b/src/utils/exec.js @@ -1,7 +1,27 @@ -import { exec } from 'child_process'; -import { promisify } from 'bluebird'; +// @flow +import { exec as execute } from 'child_process'; /** * @private */ -export default promisify(exec); +export default function exec(cmd: string, opts?: { + cwd?: string; + env?: Object; + uid?: number; + gid?: number; + shell?: string; + timeout?: number; + encoding?: string; + maxBuffer?: number; + killSignal?: string; +}): Promise<[string | Buffer, string | Buffer]> { + return new Promise((resolve, reject) => { + execute(cmd, opts, (err, stdout, stderr) => { + if (err) { + return reject(err); + } + + resolve([stdout, stderr]); + }); + }); +}