-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for config files (#74)
- Loading branch information
1 parent
1784b38
commit 2c118b3
Showing
7 changed files
with
146 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ node_modules/ | |
package-lock.json | ||
.nyc_output | ||
build/ | ||
coverage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import * as fs from 'fs'; | ||
import { promisify } from 'util'; | ||
|
||
const readFile = promisify(fs.readFile); | ||
|
||
export interface Flags { | ||
config?: string; | ||
recurse?: boolean; | ||
skip?: string; | ||
format?: string; | ||
silent?: boolean; | ||
} | ||
|
||
export async function getConfig(flags: Flags) { | ||
// check to see if a config file path was passed | ||
const configPath = flags.config || 'linkinator.config.json'; | ||
let configData: string | undefined; | ||
try { | ||
configData = await readFile(configPath, { encoding: 'utf8' }); | ||
} catch (e) { | ||
if (flags.config) { | ||
console.error(`Unable to find config file ${flags.config}`); | ||
throw e; | ||
} | ||
} | ||
|
||
let config: Flags = {}; | ||
if (configData) { | ||
config = JSON.parse(configData); | ||
} | ||
// `meow` is set up to pass boolean flags as `undefined` if not passed. | ||
// copy the struct, and delete properties that are `undefined` so the merge | ||
// doesn't blast away config level settings. | ||
const strippedFlags = Object.assign({}, flags); | ||
Object.entries(strippedFlags).forEach(([key, value]) => { | ||
if (typeof value === 'undefined') { | ||
delete (strippedFlags as { [index: string]: {} })[key]; | ||
} | ||
}); | ||
|
||
// combine the flags passed on the CLI with the flags in the config file, | ||
// with CLI flags getting precedence | ||
config = Object.assign({}, config, strippedFlags); | ||
return config; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"format": "json", | ||
"recurse": true, | ||
"silent": true, | ||
"skip": "馃尦" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import * as assert from 'assert'; | ||
import * as path from 'path'; | ||
import { getConfig, Flags } from '../src/config'; | ||
const assertRejects = require('assert-rejects'); | ||
|
||
describe('config', () => { | ||
it('should allow passing no config', async () => { | ||
const cfg: Flags = { | ||
format: 'json', | ||
recurse: true, | ||
silent: true, | ||
skip: '馃尦', | ||
}; | ||
const config = await getConfig(cfg); | ||
assert.deepStrictEqual(config, cfg); | ||
}); | ||
|
||
it('should throw with a reasonable message if the path doesnt exist', async () => { | ||
const cfg = { | ||
config: '/path/does/not/exist', | ||
}; | ||
await assertRejects(getConfig(cfg), /ENOENT: no such file or directory/); | ||
}); | ||
|
||
it('should allow reading from a config file', async () => { | ||
const configPath = path.resolve( | ||
'test/fixtures/config/linkinator.config.json' | ||
); | ||
const expected = require(configPath); | ||
const config = await getConfig({ config: configPath }); | ||
delete config.config; | ||
assert.deepStrictEqual(config, expected); | ||
}); | ||
|
||
it('should merge config settings from the CLI and object', async () => { | ||
const configPath = path.resolve( | ||
'test/fixtures/config/linkinator.config.json' | ||
); | ||
const expected = require(configPath); | ||
expected.skip = 'loo'; | ||
const config = await getConfig({ | ||
config: configPath, | ||
skip: 'loo', | ||
}); | ||
delete config.config; | ||
assert.deepStrictEqual(config, expected); | ||
}); | ||
}); |