Skip to content

Commit

Permalink
put requiredFences in fence.json instead of config
Browse files Browse the repository at this point in the history
  • Loading branch information
jstevans committed Nov 5, 2018
1 parent 49a4372 commit 55dc7da
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 18 deletions.
1 change: 1 addition & 0 deletions src/types/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export default interface Config {
exports?: { [files: string]: string | string[] };
dependencies?: DependencyRule[];
imports?: string[];
requiredFences?: string[];
};
1 change: 0 additions & 1 deletion src/types/NormalizedOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@ import NormalizedPath from './NormalizedPath';
export default interface NormalizedOptions {
project: NormalizedPath;
rootDir: NormalizedPath;
requiredFences?: NormalizedPath[];
onError?: (message: string) => void;
};
1 change: 0 additions & 1 deletion src/types/Options.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export default interface Options {
project?: string;
rootDir?: string;
requiredFences?: string[];
onError?: (message: string) => void;
};
3 changes: 3 additions & 0 deletions src/utils/dedupe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function dedupe<T>(...arrays: T[][]) {
return Array.from(new Set([].concat(...arrays)));
}
4 changes: 0 additions & 4 deletions src/utils/getOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,9 @@ export function setOptions(providedOptions: Options) {
? normalizePath(providedOptions.project)
: normalizePath(rootDir, 'tsconfig.json');

const requiredFences =
providedOptions.requiredFences && providedOptions.requiredFences.map(f => normalizePath(f));

options = {
project,
rootDir,
requiredFences,
onError: providedOptions.onError,
};
}
67 changes: 55 additions & 12 deletions src/validation/validateFencesExistence.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,72 @@
import reportError from '../core/reportError';
import * as glob from 'glob';
import * as path from 'path';
import getOptions from '../utils/getOptions';
import normalizePath from '../utils/normalizePath';
import getAllConfigs from '../utils/getAllConfigs';
import Config from '../types/Config';
import ConfigSet from '../types/ConfigSet';
import dedupe from '../utils/dedupe';

interface ConfigPathPair {
path: string;
config: Config;
}

export default function validateFencesExistence() {
if (!getOptions().requiredFences) {
return true;
}
const configPaths = getAllConfigs();
const configPathMap = getAllConfigs();
const requiredFenceGlobs = getRequiredFenceGlobs(configPathMap);

// get a deduped list of required paths
const requiredPaths = Array.from(
new Set([].concat(...getOptions().requiredFences.map(f => glob.sync(f))))
);
const requiredPaths = dedupe(requiredFenceGlobs.map(f => glob.sync(f)));

// get the required paths that aren't in our map of all configs
const missingRequiredPaths = requiredPaths.filter(
p => configPaths[normalizePath(path.dirname(p))]
);
const missingRequiredPaths = requiredPaths.filter(p => !configPathMap[p]);

if (missingRequiredPaths.length > 0) {
missingRequiredPaths.forEach(p => reportError(`Missing fence.json at ${p}`));
}

return missingRequiredPaths.length === 0;
}

/**
* @summary Create a set of globs that define directories that must have fences
* @param configSet The set of configs to build our globs from
*/
function getRequiredFenceGlobs(configSet: ConfigSet) {
const configPathPairs = Object.keys(configSet).map(key => ({
path: key,
config: configSet[key],
}));

const configPathPairsWithFences = configPathPairs.filter(pair => pair.config.requiredFences);

const requiredFenceGlobs = configPathPairsWithFences
.map(absolutifyGlobs)
.map(directorizeGlobs)
.reduce((acc, e) => acc.concat(e), []);

return requiredFenceGlobs;
}

/**
* @summary Create globs with absolute paths
* @param pair A pair of base path and config
*/
function absolutifyGlobs(pair: ConfigPathPair) {
const pathParts = pair.path.split(/[\///]/);
const requiredFences = pair.config.requiredFences;
const absoluteGlobs = requiredFences.map(rf =>
pathParts.concat(rf.split(/[\///]/)).join(path.sep)
);

return absoluteGlobs;
}

/**
* @summary ensure we only match directories by appending a path separator (e.g. '/')
* @param globs The globs to directorize
*/
function directorizeGlobs(globs: string[]) {
const dirPaths = globs.map(g => g.replace(/[\///]*$/, path.sep));
return dirPaths;
}

0 comments on commit 55dc7da

Please sign in to comment.