Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(init): add new options (cwd, logger) to init() #203

Merged
merged 1 commit into from
Jun 17, 2018
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
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ ybiq init
### Programmatic API

```js
const ybiq = require('ybiq')
const ybiq = require("ybiq");

ybiq.init()
ybiq.init({
// Default options
// cwd: process.cwd(),
// logger: msg => process.stdout.write(msg),
});
```
31 changes: 18 additions & 13 deletions lib/init.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
const path = require('path')
const { EOL } = require('os')
const fs = require('fs-extra')
const originalPackage = require('../package.json')

const stdout = str => process.stdout.write(`${str}\n`)

const packagePath = (...pathElements) =>
path.join(...[__dirname, '..', ...pathElements])

const copyFile = async (src, dest) => {
await fs.copy(src, dest)
stdout(`${dest} was updated.`)
}

const template = name => path.join(__dirname, '..', 'templates', name)

class Init {
constructor(baseDir) {
constructor(baseDir, logger) {
this.baseDir = baseDir
this.logger = logger
}

async copyFile(src, dest) {
await fs.copy(src, dest)
this.logger(`${dest} was updated.`)
}

currentPath(...pathElements) {
Expand All @@ -26,7 +26,7 @@ class Init {
async writeFile(fileName, fileContent) {
const file = this.currentPath(fileName)
await fs.writeFile(file, `${fileContent}\n`)
stdout(`${file} was updated.`)
this.logger(`${file} was updated.`)
}

async readFile(fileName) {
Expand Down Expand Up @@ -65,16 +65,21 @@ class Init {
}

async writeTemplateFile(name) {
await copyFile(template(name), this.currentPath(name))
await this.copyFile(template(name), this.currentPath(name))
}

async writePackageFile(name) {
await copyFile(packagePath(name), this.currentPath(name))
await this.copyFile(packagePath(name), this.currentPath(name))
}
}

module.exports = async function init() {
const cmd = new Init(process.cwd())
const defaultLogger = msg => process.stdout.write(`${msg}${EOL}`)

module.exports = async function init({
cwd = process.cwd(),
logger = defaultLogger,
} = {}) {
const cmd = new Init(cwd, logger)
await cmd.updatePackageFile()
await cmd.writePackageFile('.editorconfig')
await cmd.writePackageFile('.prettierignore')
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"eslint-config-ybiquitous": "^4.2.1"
},
"scripts": {
"test": "nyc --check-coverage tape \"test/**/*.test.js\"",
"test": "nyc --check-coverage --lines 100 --branches 90 tape \"test/**/*.test.js\"",
"test:watch": "nodemon --ext js --watch . --exec \"tape test/**/*.test.js\"",
"test:coverage": "nyc report --reporter=text-lcov > coverage.lcov",
"lint:js": "eslint --ignore-path .gitignore --ext .js,.jsx,.mjs .",
Expand Down
4 changes: 4 additions & 0 deletions test/helpers/exec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ module.exports = function exec(...args) {
const options = {
env: { ...process.env, LANG: 'C' },
}
const lastArg = args[args.length - 1]
if (lastArg && typeof lastArg === 'object') {
options.cwd = lastArg.cwd
}
return new Promise((resolve, reject) => {
cp.execFile(tested, args, options, (error, stdout, stderr) => {
if (error) {
Expand Down
36 changes: 21 additions & 15 deletions test/init.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const path = require('path')
const os = require('os')
const fs = require('fs-extra')
const test = require('tape')
const exec = require('./helpers/exec')
const pkg = require('../package.json')
const init = require('../lib/init')

Expand All @@ -10,15 +11,13 @@ const readFile = file => fs.readFile(file, 'utf8')
const sandbox = async (fn, t) => {
const workDir = path.join(os.tmpdir(), `${pkg.name}${Date.now()}`)
await fs.mkdirs(workDir)
const origDir = process.cwd()
process.chdir(workDir)

const origLogger = process.stdout.write
const logMsgs = []
process.stdout.write = msg => logMsgs.push(msg)
const logger = msg => logMsgs.push(msg)

try {
const fixturePath = name => path.join(__dirname, 'fixtures', name)
const cwd = process.cwd()
const fixturePath = name => path.join(cwd, 'test', 'fixtures', name)
const fixture = async name => {
const src = fixturePath(name)
const dest = path.join(workDir, 'package.json')
Expand All @@ -30,13 +29,12 @@ const sandbox = async (fn, t) => {
fixturePath,
fixture,
readFixture: name => readFile(fixturePath(name)),
readOrigFile: name => readFile(path.join(origDir, name)),
readOrigFile: name => readFile(path.join(cwd, name)),
readWorkFile: name => readFile(path.join(workDir, name)),
logMessage: () => logMsgs.join(''),
initArgs: { cwd: workDir, logger },
})
} finally {
process.stdout.write = origLogger
process.chdir(origDir)
await fs.remove(workDir)
}
}
Expand All @@ -48,7 +46,7 @@ test('init', t => {

testInSandbox('update "package.json"', async (t, ctx) => {
const src = await ctx.fixture('package-normal.json')
await init()
await init(ctx.initArgs)
const actual = await readFile(src)
const expected = await ctx.readFixture('package-normal_expected.json')
t.is(actual, expected)
Expand All @@ -57,7 +55,7 @@ test('init', t => {

testInSandbox('update "package.json" without fields', async (t, ctx) => {
const src = await ctx.fixture('package-empty.json')
await init()
await init(ctx.initArgs)
const actual = await readFile(src)
const expected = await ctx.readFixture('package-empty_expected.json')
t.is(actual, expected)
Expand All @@ -66,7 +64,7 @@ test('init', t => {
;['.editorconfig', '.prettierignore', '.markdownlint.json'].forEach(file => {
testInSandbox(`write "${file}"`, async (t, ctx) => {
await ctx.fixture('package-normal.json')
await init()
await init(ctx.initArgs)
t.ok(ctx.logMessage().includes('package.json was updated.'))

const original = await ctx.readOrigFile(file)
Expand All @@ -78,7 +76,7 @@ test('init', t => {

testInSandbox('write ".eslintrc.js"', async (t, ctx) => {
await ctx.fixture('package-normal.json')
await init()
await init(ctx.initArgs)
t.ok(ctx.logMessage().includes('.eslintrc.js was updated.'))

const actual = await ctx.readWorkFile('.eslintrc.js')
Expand All @@ -89,7 +87,7 @@ test('init', t => {

testInSandbox('write ".commitlintrc.js"', async (t, ctx) => {
await ctx.fixture('package-normal.json')
await init()
await init(ctx.initArgs)
t.ok(ctx.logMessage().includes('.commitlintrc.js was updated.'))

const actual = await ctx.readWorkFile('.commitlintrc.js')
Expand All @@ -98,10 +96,18 @@ test('init', t => {
t.end()
})

testInSandbox('throw error if no package.json', async t => {
const error = await init().catch(err => err)
testInSandbox('throw error if no package.json', async (t, ctx) => {
const error = await init(ctx.initArgs).catch(err => err)
t.ok(error instanceof Error)
t.is(error.code, 'ENOENT')
t.end()
})

testInSandbox('End-to-End via CLI', async (t, ctx) => {
await ctx.fixture('package-normal.json')
const { stdout, stderr } = await exec('init', { cwd: ctx.initArgs.cwd })
t.ok(stdout.includes('package.json was updated.'))
t.is(stderr, '')
t.end()
})
})