Skip to content

Commit

Permalink
feat(core): allows options to be defined at kpo package.json key
Browse files Browse the repository at this point in the history
  • Loading branch information
rafamel committed Apr 27, 2019
1 parent 8b0f221 commit 6297145
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ const core = {
// set current directory as the the one of the scope
options.setCli({ file: null, directory: scope.directory });
// reset options
options.setScope();
options.resetScope();
}
// Continue recursively
if (next.length) return core.setScope(next);
Expand Down
44 changes: 31 additions & 13 deletions src/core/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,24 @@ import yaml from 'js-yaml';
import { rejects } from 'errorish';
import { open } from '~/utils/errors';
import { ILoaded, IPaths } from './types';
import { IOfType } from '~/types';
import { IOfType, TCoreOptions } from '~/types';
import options from './options';

export default async function load(paths: IPaths): Promise<ILoaded> {
return {
kpo: paths.kpo ? await loadFile(paths.kpo) : null,
pkg: paths.pkg ? await fs.readJSON(paths.pkg).catch(rejects) : null
};
// pkg must be loaded first to set options first, if present at key `kpo`
const pkg = paths.pkg
? await fs
.readJSON(paths.pkg)
.then(processPkg)
.catch(rejects)
: null;

const kpo = paths.kpo ? await loadFile(paths.kpo) : null;

return { kpo, pkg };
}

export async function loadFile(file: string): Promise<IOfType<any>> {
export async function loadFile(file: string): Promise<IOfType<any> | null> {
const { ext } = path.parse(file);

switch (ext) {
Expand All @@ -23,8 +30,8 @@ export async function loadFile(file: string): Promise<IOfType<any>> {
case '.json':
return fs
.readJSON(file)
.catch(rejects)
.then(getScripts);
.then(processStatic)
.catch(rejects);
case '.yml':
case '.yaml':
const kpo = yaml.safeLoad(
Expand All @@ -33,15 +40,26 @@ export async function loadFile(file: string): Promise<IOfType<any>> {
.then(String)
.catch(rejects)
);
return getScripts(kpo);
return processStatic(kpo);
default:
throw Error(`Extension not valid for ${file}`);
}
}

export function getScripts(kpo: IOfType<any>): IOfType<any> {
if (!kpo.scripts) throw Error(`Scripts file didn't contain a scripts key`);

export function processStatic(kpo: IOfType<any>): IOfType<any> | null {
if (kpo.options) options.setScope(kpo.options);
return kpo.scripts;

return kpo.scripts || null;
}

export function processPkg(pkg: IOfType<any>): IOfType<any> {
if (!pkg || !pkg.kpo) return pkg;

const opts: TCoreOptions = Object.assign({}, pkg.kpo);
// file was already read when getting paths;
// it's also not a IScopeOptions field
delete opts.file;

options.setScope(opts);
return pkg;
}
10 changes: 5 additions & 5 deletions src/core/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ export default {
merge();
},
setScope(opts: IScopeOptions = {}): void {
// TODO: overwriting state.scope shouldn't be needed
// if we add a reset method to be called on scope change,
// that way, several options() calls within a require can accumulate;
// also, it would allow options to be optionally set on package.json
state.scope = opts;
Object.assign(state.scope, opts);
merge();
},
resetScope(): void {
state.scope = {};
merge();
}
};
Expand Down
8 changes: 4 additions & 4 deletions src/core/paths/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ export async function getFromPackage(
const dir = path.parse(pkg).dir;
const parsed = await fs.readJSON(pkg).catch(rejects);

if (!parsed.kpo || !parsed.kpo.path) return null;
if (!parsed.kpo || !parsed.kpo.file) return null;

const file = path.isAbsolute(parsed.kpo.path)
? parsed.kpo.path
: path.join(dir, parsed.kpo.path);
const file = path.isAbsolute(parsed.kpo.file)
? parsed.kpo.file
: path.join(dir, parsed.kpo.file);

// Ensure file exists
await exists(file, { fail: true });
Expand Down
8 changes: 7 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export interface IOptions {
}

/**
* Options to be passed to `options`, if your *kpo* file is a `javascript` file, or to define in the `options` key of your scripts file otherwise. They can also live at `kpo.options` in your `package.json`.
* Options to be passed to `options`, if your *kpo* file is a `javascript` file, or to define in the `options` key of your scripts file otherwise.
*/
export interface IScopeOptions extends IOptions {
/**
Expand All @@ -98,9 +98,15 @@ export interface IScopeOptions extends IOptions {
* Options taken by the CLI.
*/
export interface IBaseOptions extends IOptions {
/**
* The location of the *kpo* scripts file for the project.
*/
file?: string | null;
}

/**
* Options that can live in the `kpo` key of a `package.json`.
*/
export type TCoreOptions = IBaseOptions & IScopeOptions;

/**
Expand Down

0 comments on commit 6297145

Please sign in to comment.