Skip to content

Commit

Permalink
enables multiple files/ folders to be scanned in one go
Browse files Browse the repository at this point in the history
  • Loading branch information
sverweij committed Dec 10, 2016
1 parent 2f48216 commit 1a2026b
Show file tree
Hide file tree
Showing 14 changed files with 297 additions and 63 deletions.
4 changes: 2 additions & 2 deletions doc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ stable <span style="color: orange">the API is under construction</span>.
```javascript
const depcruise = require('dependency-cruiser');

let dependencies = depcruise("src");
let dependencies = depcruise(["src"]);
```

This will return an object
Expand All @@ -32,7 +32,7 @@ followed, and having a GraphViz dot script returned, you'd do this:
const depcruise = require('dependency-cruiser');

let dependenciesInAGraphVizDotScript = depcruise(
"src"
["src"]
{
exclude : "(node_modules)",
system : ["cjs"],
Expand Down
10 changes: 9 additions & 1 deletion doc/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Running with no parameters gets you help:
```
Usage: dependency-cruise [options] <directory-or-file>
Usage: dependency-cruise [options] <files-or-directories>
Options:
Expand Down Expand Up @@ -112,6 +112,14 @@ default) and 'info') with them that will appear in some reporters:
}
```

### Cruising multiple files and directories in one go
Just pass them as arguments. This, e.g. will cruise every file in the folders
src, test and lib (recursively)+ the file called index.ts in the root.

```sh
depcruise --output-type dot src test lib index.ts
```

## Daphne's dependencies - a gentle introduction
**[Daphne's
dependencies](sample-output.md)**
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ program
.option("-x, --exclude <regex>", "a regular expression for excluding modules")
.option("-M, --system <items>", "list of module systems (default: amd,cjs,es6)")
.option("-T, --output-type <type>", "output type - html|dot|err|json (default:json)")
.arguments("<directory-or-file>")
.arguments("<files-or-directories>")
.parse(process.argv);

if (Boolean(program.args[0])) {
processCLI(
program.args[0],
program.args,
program
);
} else {
Expand Down
6 changes: 3 additions & 3 deletions src/cli/processCLI.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ function write(pOutputTo, pContent) {
}
}

module.exports = (pDirOrFile, pOptions) => {
module.exports = (pFileDirArray, pOptions) => {
try {
validateParameters(pDirOrFile, pOptions);
validateParameters(pFileDirArray, pOptions);
pOptions = normalizeOptions(pOptions);

if (Boolean(pOptions.rulesFile)){
Expand All @@ -38,7 +38,7 @@ module.exports = (pDirOrFile, pOptions) => {
}

let lDependencyList = main(
pDirOrFile,
pFileDirArray,
pOptions
);
let lExitCode = lDependencyList.metaData ? lDependencyList.metaData.error : 0;
Expand Down
4 changes: 2 additions & 2 deletions src/cli/validateParameters.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ function validateValidation(pOptions) {
}
}

module.exports = (pDirOrFile, pOptions) => {
validateFileExistence(pDirOrFile);
module.exports = (pFileDirArray, pOptions) => {
pFileDirArray.forEach(validateFileExistence);
if (Boolean(pOptions)) {
validateSystems(pOptions.system);
validateExcludePattern(pOptions.exclude);
Expand Down
37 changes: 37 additions & 0 deletions src/extract/gatherInitialSources.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const fs = require('fs');
const path = require('path');
const utl = require('../utl');

const SUPPORTED_EXTENSIONS = [
".js",
".ts",
".coffee",
".litcoffee",
".coffee.md"
];

function gatherScannableFilesFromDir (pDirName, pOptions) {
return fs.readdirSync(pDirName)
.filter(pFileInDir => utl.ignore(pFileInDir, pOptions.exclude))
.reduce((pSum, pFileName) => {
if (fs.statSync(path.join(pDirName, pFileName)).isDirectory()){
return pSum.concat(gatherScannableFilesFromDir(path.join(pDirName, pFileName), pOptions));
}
if (SUPPORTED_EXTENSIONS.some(pExt => pFileName.endsWith(pExt))){
return pSum.concat(path.join(pDirName, pFileName));
}
return pSum;
}, []);
}

module.exports = (pFileDirArray, pOptions) =>
pFileDirArray.reduce(
(pAll, pThis) => {
if (fs.statSync(pThis).isDirectory()) {
return pAll.concat(gatherScannableFilesFromDir(pThis, pOptions));
} else {
return pAll.concat(pThis);
}
},
[]
);
39 changes: 6 additions & 33 deletions src/extract/index.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,9 @@
"use strict";

const fs = require('fs');
const path = require('path');
const _ = require('lodash');

const extract = require('./extract');
const utl = require('../utl');

const SUPPORTED_EXTENSIONS = [
".js",
".ts",
".coffee",
".litcoffee",
".coffee.md"
];

function getAllJSFilesFromDir (pDirName, pOptions) {
return fs.readdirSync(pDirName)
.filter(pFileInDir => utl.ignore(pFileInDir, pOptions.exclude))
.reduce((pSum, pFileName) => {
if (fs.statSync(path.join(pDirName, pFileName)).isDirectory()){
return pSum.concat(getAllJSFilesFromDir(path.join(pDirName, pFileName), pOptions));
}
if (SUPPORTED_EXTENSIONS.some(pExt => path.extname(pFileName) === pExt)){
return pSum.concat(path.join(pDirName, pFileName));
}
return pSum;
}, []);
}
const gather = require('./gatherInitialSources');

function extractRecursive (pFileName, pOptions, pVisited) {
pOptions = pOptions || {};
Expand Down Expand Up @@ -56,11 +32,11 @@ function extractRecursive (pFileName, pOptions, pVisited) {
return lRetval;
}

function extractRecursiveDir(pDirName, pOptions) {
function extractFileDirArray(pFileDirArray, pOptions) {
let lVisited = new Set();

return _.spread(_.concat)(
getAllJSFilesFromDir(pDirName, pOptions)
gather(pFileDirArray, pOptions)
.reduce((pDependencies, pFilename) => {
if (!lVisited.has(pFilename)){
lVisited.add(pFilename);
Expand Down Expand Up @@ -103,14 +79,11 @@ function complete(pAll, pFromListItem) {
);
}

module.exports = (pDirOrFile, pOptions, pCallback) => {
module.exports = (pFileDirArray, pOptions, pCallback) => {
let lRetvalToTransform = {};
let lCallback = pCallback ? pCallback : pInput => ({dependencies: pInput, metaData: {}});

if (fs.statSync(pDirOrFile).isDirectory()) {
lRetvalToTransform = extractRecursiveDir(pDirOrFile, pOptions);
} else {
lRetvalToTransform = extractRecursive(pDirOrFile, pOptions);
}
lRetvalToTransform = extractFileDirArray(pFileDirArray, pOptions);

return lCallback(lRetvalToTransform.reduce(complete, []));
};
12 changes: 6 additions & 6 deletions src/main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ const TYPE2REPORTER = {
* out the function will return a javascript object as dependencies
* }
*
* @param {string} pDirOrFile The directory to cruise or the file to start
* the cruise with
* @param {array} pFileDirArray An array of (names of) files and directories to
* start the cruise with
* @param {object} pOptions see above
* @return {object}
* @return {object} An object with ...
* {
* dependencies : when outputType is defined: a string containing the dependencies
* in the format specified in outputType
* In all other cases: a javascript with the dependencies
* In all other cases: a javascript array with the dependencies
* metaData : meta data with a summary of
* { error : the number of errors,
* warn : the number of warnings,
Expand All @@ -54,11 +54,11 @@ const TYPE2REPORTER = {
* always return this in the near future)
* }
*/
module.exports = (pDirOrFile, pOptions) => {
module.exports = (pFileDirArray, pOptions) => {
pOptions = pOptions ? pOptions : {};

return extract(
pDirOrFile,
pFileDirArray,
pOptions,
TYPE2REPORTER[pOptions.outputType]
);
Expand Down
37 changes: 28 additions & 9 deletions test/cli/cli.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ const testPairs = [
expect: "{{moduleType}}.dir.filtered.err",
cleanup: true
}

];

function deleteDammit(pFileName) {
Expand All @@ -133,6 +132,7 @@ function resetOutputDir() {
deleteDammit(path.join(OUT_DIR, "cjs.dir.stdout.json"));
deleteDammit(path.join(OUT_DIR, "amd.dir.stdout.json"));
deleteDammit(path.join(OUT_DIR, "cjs.dir.dot"));
deleteDammit(path.join(OUT_DIR, "multiple-in-one-go.json"));
}

function setModuleType(pTestPairs, pModuleType) {
Expand All @@ -157,7 +157,7 @@ function setModuleType(pTestPairs, pModuleType) {
function runFileBasedTests(pModuleType) {
setModuleType(testPairs, pModuleType).forEach(pPair => {
it(pPair.description, () => {
processCLI(pPair.dirOrFile, pPair.options);
processCLI([pPair.dirOrFile], pPair.options);
tst.assertFileEqual(
pPair.options.outputTo,
path.join(FIX_DIR, pPair.expect)
Expand All @@ -180,14 +180,33 @@ describe("#processCLI", () => {
});

describe("specials", () => {
it("dependency-cruises multiple files and folders in one go", () => {
const lOutputFileName = "multiple-in-one-go.json";
const lOutputTo = path.join(OUT_DIR, lOutputFileName);

processCLI(
[
"test/cli/fixtures/cjs/sub",
"test/cli/fixtures/duplicate-subs/sub/more-in-sub.js",
"test/cli/fixtures/unresolvable-in-sub"
],
{
outputTo: lOutputTo
}
);
tst.assertFileEqual(
lOutputTo,
path.join(FIX_DIR, lOutputFileName)
);
});

it("dependency-cruise test/cli/fixtures/cjs - outputs to stdout", () => {
let lCapturedStdout = "";
const unhookIntercept = intercept(pText => {
lCapturedStdout += pText;
});

processCLI("test/cli/fixtures/cjs");
processCLI(["test/cli/fixtures/cjs"]);
unhookIntercept();
fs.writeFileSync(
path.join(OUT_DIR, "cjs.dir.stdout.json"),
Expand All @@ -207,7 +226,7 @@ describe("#processCLI", () => {
lCapturedStdout += pText;
});

processCLI("test/cli/fixtures/cjs", {outputTo: "-", outputType: 'json'});
processCLI(["test/cli/fixtures/cjs"], {outputTo: "-", outputType: 'json'});
unhookIntercept();
fs.writeFileSync(
path.join(OUT_DIR, "cjs.dir.stdout.json"),
Expand All @@ -231,7 +250,7 @@ describe("#processCLI", () => {
lCapturedStderr += pText;
});

processCLI("this-doesnot-exist", {outputTo: path.join(OUT_DIR, "cjs.dir.wontmarch.json")});
processCLI(["this-doesnot-exist"], {outputTo: path.join(OUT_DIR, "cjs.dir.wontmarch.json")});
unhookInterceptStdOut();
unhookInterceptStdErr();

Expand All @@ -253,7 +272,7 @@ describe("#processCLI", () => {
});

processCLI(
"test/cli/fixtures",
["test/cli/fixtures"],
{
outputTo: path.join(OUT_DIR, "/dev/null"),
system: "invalidmodulesystem"
Expand Down Expand Up @@ -283,7 +302,7 @@ describe("#processCLI", () => {
});

processCLI(
"test/cli/fixtures",
["test/cli/fixtures"],
{
outputTo: path.join(OUT_DIR, "/dev/null"),
outputType: "invalidoutputtype"
Expand Down Expand Up @@ -313,7 +332,7 @@ describe("#processCLI", () => {
});

processCLI(
"test/cli/fixtures",
["test/cli/fixtures"],
{
outputTo: path.join(OUT_DIR, "file/you/cant/write/to")
}
Expand Down Expand Up @@ -342,7 +361,7 @@ describe("#processCLI", () => {
});

processCLI(
"test/cli/fixtures",
["test/cli/fixtures"],
{
outputTo: path.join(OUT_DIR, "/dev/null"),
exclude: "([A-Za-z]+)*"
Expand Down
Loading

0 comments on commit 1a2026b

Please sign in to comment.