Skip to content

Commit

Permalink
feat(core/scope): recurses up to @root looking for children scopes
Browse files Browse the repository at this point in the history
  • Loading branch information
rafamel committed Apr 25, 2019
1 parent a7261a4 commit c3640b0
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/bin/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export default async function main(argv: string[]): Promise<void> {
const command = first.split(':');
const scope = command.shift() as string;

await core.setScope(scope === '@' ? 'root' : scope.slice(1));
await core.setScope(scope === '@' ? ['root'] : [scope.slice(1)]);

first = command.length
? `:${command.join(':')}`
Expand Down
25 changes: 14 additions & 11 deletions src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import _cache from '~/utils/cache';
import options from '~/options';
import { getSelfPaths, getRootPaths } from './paths';
import load from './load';
import scope from './scope';
import setScope from './scope';
import { IPaths, ILoaded } from './types';
import getBin from './bin';
import exec from './exec';
import logger from '~/utils/logger';

export interface ICoreState {
scopes: string[];
Expand All @@ -26,16 +27,16 @@ const core = {
directory: options.get('directory') || undefined
});
}),
load: cache(async function(): Promise<ILoaded> {
return load(await core.paths());
}),
root: cache(async function(): Promise<IPaths | null> {
const paths = await core.paths();
return getRootPaths({
self: paths.directory,
root: options.get('root')
});
}),
load: cache(async function(): Promise<ILoaded> {
return load(await core.paths());
}),
bin: cache(async function(): Promise<string[]> {
const paths = await core.paths();
const root = await core.root();
Expand All @@ -49,24 +50,26 @@ const core = {
const env = options.get('env');
return exec(command, paths.directory, bin, env);
},
async setScope(name: string): Promise<void> {
async setScope(names: string[]): Promise<void> {
const paths = await core.paths();
const root = await core.root();

const definition = await scope(
name,
const { next, scope } = await setScope(
names,
{ self: paths.directory, root: root ? root.directory : undefined },
options.get('children')
);

if (definition) {
if (scope) {
logger.debug(`${scope.name} scope set`);
// keep track of scope branches
state.scopes = state.scopes.concat(definition.names);
state.scopes = state.scopes.concat(scope.name);
// set current directory as the the one of the scope
options.setBase({ file: null, directory: definition.directory });
options.setBase({ file: null, directory: scope.directory });
// reset options
options.setScope();
}
// Continue recursively
if (next.length) return core.setScope(next);
}
};

Expand Down
38 changes: 26 additions & 12 deletions src/core/scope/index.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,52 @@
import logger from '~/utils/logger';
import getChildren from './children';
import { IScopeDefinition } from '../types';
import { IScope } from '../types';
import { TChildrenDefinition } from '~/types';

export default async function scope(
scope: string,
export default async function setScope(
scopes: string[],
directories: { self: string; root?: string },
definitions?: TChildrenDefinition
): Promise<IScopeDefinition | null> {
): Promise<{ next: string[]; scope?: IScope }> {
if (!scopes.length) return { next: [] };

const name = scopes[0];
const next = scopes.slice(1);

// root scope
if (scope === 'root') {
if (name === 'root') {
if (directories.root) {
return { names: ['root'], directory: directories.root };
return { next, scope: { name: 'root', directory: directories.root } };
} else {
logger.debug('root scope was not found and was assigned to self');
return null;
return { next };
}
}

// child scopes
const children = await getChildren(directories.self, definitions);
const matches = children
.filter((child) => child.matcher(scope))
.filter((child) => child.matcher(name))
.map((child) => child.directory);

if (matches.length) {
logger.debug(`scopes found for ${scope}:\n${matches.join('\n')}`);
logger.debug(`scopes found for ${name}:\n${matches.join('\n')}`);

if (matches.length > 1) {
throw Error(`Several scopes matched name "${scope}"`);
throw Error(`Several scopes matched name "${name}"`);
}

return { names: [scope], directory: matches[0] };
return { next, scope: { name, directory: matches[0] } };
}

// it was not found as child, try scaling up to root
if (directories.root) {
logger.debug(`scope ${name} not found, scaling to root scope`);
return {
next: next.concat(name),
scope: { name: 'root', directory: directories.root }
};
}

throw Error(`Scope ${scope} was not found`);
throw Error(`Scope "${name}" was not found`);
}
4 changes: 2 additions & 2 deletions src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export interface ILoaded {
pkg: IOfType<any> | null;
}

export interface IScopeDefinition {
names: string[];
export interface IScope {
name: string;
directory: string;
}

Expand Down

0 comments on commit c3640b0

Please sign in to comment.