Skip to content

Commit

Permalink
feat(state): separates load into paths and load; gets root paths
Browse files Browse the repository at this point in the history
  • Loading branch information
rafamel committed Apr 23, 2019
1 parent cb6a334 commit ea2b809
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 55 deletions.
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"@types/jest": "24.0.11",
"@types/js-yaml": "3.12.1",
"@types/lodash.mergewith": "4.6.6",
"@types/object-hash": "^1.2.0",
"@typescript-eslint/eslint-plugin": "1.6.0",
"@typescript-eslint/parser": "1.6.0",
"@zerollup/ts-transform-paths": "1.7.1",
Expand Down Expand Up @@ -121,6 +122,7 @@
"lodash.mergewith": "^4.6.1",
"loglevel": "^1.6.1",
"manage-path": "^2.0.0",
"object-hash": "^1.3.1",
"promist": "^0.5.3",
"slimconf": "^0.9.0",
"spawn-command": "0.0.2-1",
Expand Down
36 changes: 9 additions & 27 deletions src/state/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import load, { ILoad } from './load';
import paths, { IPaths } from './paths';
import mergewith from 'lodash.mergewith';
import { IBaseOptions, IScopeOptions, TOptions } from '~/types';
import { DEFAULT_LOG_LEVEL } from '~/constants';
import { setLevel } from '~/utils/logger';
import { lazy } from 'promist';
import up from 'find-up';

export interface IConfig {
load: ILoad;
paths: string[];
}
import load, { ILoaded } from './load';

export const states = {
base: {
Expand All @@ -22,7 +17,7 @@ export const states = {
scope: {} as IScopeOptions
};

let config: Promise<IConfig>;
let promise: Promise<IPaths>;
let state: TOptions = {};
merge();

Expand All @@ -40,11 +35,11 @@ export default {
get(key: keyof TOptions): any {
return state[key];
},
load(): Promise<ILoad> {
return config.then((x) => x.load);
paths(): Promise<IPaths> {
return promise;
},
paths(): Promise<string[]> {
return config.then((x) => x.paths);
load(): Promise<ILoaded> {
return promise.then((paths) => load(paths));
}
};

Expand All @@ -62,20 +57,7 @@ function merge(): void {
if (state.log) setLevel(state.log);

// Set config lazy promise
config = lazy((resolve) => resolve(getConfig()));
}

async function getConfig(): Promise<IConfig> {
const res = await load({
file: state.file,
directory: state.directory
promise = lazy((resolve) => {
resolve(paths({ file: state.file, directory: state.directory }));
});

return {
load: res,
// TODO add root path
paths: [await up('node_modules/.bin', { cwd: res.directory })].filter(
(path, i, arr) => path && arr.indexOf(path) === i
) as string[]
};
}
40 changes: 14 additions & 26 deletions src/state/load/index.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,24 @@
import path from 'path';
import fs from 'fs-extra';
import getFile from './get-file';
import readFile from './read-file';
import { IOfType, IScripts } from '~/types';
import logger from '~/utils/logger';
import { IScripts, IOfType } from '~/types';
import { rejects } from 'errorish';
import { IBasePaths } from '~/state/paths';
import hash from 'object-hash';
import readFile from './read-file';

export interface ILoadOpts {
file?: string;
directory?: string;
}

export interface ILoad {
export interface ILoaded {
kpo: IScripts | null;
pkg: IOfType<any> | null;
directory: string;
}

export default async function load(opts: ILoadOpts): Promise<ILoad> {
const { kpo, pkg } = await getFile(opts);

let dir = path.parse(pkg || kpo || process.cwd()).dir;

if (kpo) logger.debug('kpo configuration file found at: ' + kpo);
if (pkg) logger.debug('package.json found at: ' + pkg);
if (!kpo && !pkg) {
throw Error(`No file or package.json was found in directory`);
const cache: IOfType<ILoaded> = {};
export default async function load(paths: IBasePaths): Promise<ILoaded> {
const key = hash(paths);
if (!cache.hasOwnProperty(key)) {
cache[key] = {
kpo: paths.kpo ? await readFile(paths.kpo) : null,
pkg: paths.pkg ? await fs.readJSON(paths.pkg).catch(rejects) : null
};
}

return {
kpo: kpo ? await readFile(kpo) : null,
pkg: pkg ? await fs.readJSON(pkg).catch(rejects) : null,
directory: dir
};
return cache[key];
}
File renamed without changes.
69 changes: 69 additions & 0 deletions src/state/paths/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import path from 'path';
import getFile from './get-file';
import { IOfType } from '~/types';
import logger from '~/utils/logger';
import { wrap } from '~/utils/errors';
import load from '../load';
import state from '../index';
import up from 'find-up';

export interface IPathsOpts {
file?: string;
directory?: string;
}

export interface IBasePaths {
kpo: string | null;
pkg: string | null;
bin: string[];
directory: string;
}

export interface IPaths extends IBasePaths {
root: IBasePaths | null;
children: IOfType<IBasePaths>;
}

export default async function paths(opts: IPathsOpts): Promise<IPaths> {
const base = await trunk(opts);
await load(base);

// has to to called after load to wait for scope options to modify state
const root = await trunk({
directory: state.get('root') || path.join(base.directory, '../')
}).catch(async (err) => {
return state.get('root')
? wrap.rejects(err, { message: "@root couldn't be retrieved" })
: null;
});

return {
...base,
// add also root bin path
bin: base.bin
.concat(root ? root.bin : [])
.filter((x, i, arr) => arr.indexOf(x) === i),
root,
children: {}
};
}

export async function trunk(opts: IPathsOpts): Promise<IBasePaths> {
const { kpo, pkg } = await getFile(opts);
let dir = path.parse(pkg || kpo || process.cwd()).dir;

if (kpo) logger.debug('kpo configuration file found at: ' + kpo);
if (pkg) logger.debug('package.json found at: ' + pkg);
if (!kpo && !pkg) {
throw Error(`No file or package.json was found in directory`);
}

return {
kpo: kpo,
pkg: pkg,
directory: dir,
bin: [await up('node_modules/.bin', { cwd: dir })].filter(
Boolean
) as string[]
};
}
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ export interface IBaseOptions extends ICoreOptions {

export interface IScopeOptions extends ICoreOptions {
root?: string;
children?: string[];
children?: IOfType<string>;
}
2 changes: 1 addition & 1 deletion src/utils/exec/get-env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default async function getEnv(): Promise<IOfType<string | undefined>> {
state.get('env')
);
const alter = manage(env);
alter.unshift(await state.paths());
alter.unshift(await state.paths().then((paths) => paths.bin));

return env;
}

0 comments on commit ea2b809

Please sign in to comment.