|
3 | 3 | // @flow
|
4 | 4 | import path from 'path';
|
5 | 5 | import madge from 'madge';
|
| 6 | +import fs from 'fs'; |
6 | 7 | import findPackage from 'find-package';
|
7 | 8 | import R from 'ramda';
|
8 | 9 |
|
@@ -96,28 +97,79 @@ function resolveMissingPackageName(packagePath) {
|
96 | 97 | return packagePathArr[0];
|
97 | 98 | }
|
98 | 99 |
|
| 100 | +/** |
| 101 | + * Recursivly search for node module inside node_modules dir |
| 102 | + * This function propegate up until it get's to the root provided then stops |
| 103 | + * |
| 104 | + * @param {string} nmPath - package name |
| 105 | + * @param {string} workingDir - dir to start searching of |
| 106 | + * @param {string} root - path to dir to stop the search |
| 107 | + * @returns The resolved path for the package directory |
| 108 | + */ |
| 109 | +function resolveModulePath(nmPath, workingDir, root) { |
| 110 | + const pathToCheck = path.resolve(workingDir, 'node_modules', nmPath); |
| 111 | + |
| 112 | + if (fs.existsSync(pathToCheck)) { |
| 113 | + return pathToCheck; |
| 114 | + } |
| 115 | + |
| 116 | + if (workingDir === root) { |
| 117 | + return null; |
| 118 | + } |
| 119 | + |
| 120 | + return resolveModulePath(nmPath, path.dirname(workingDir), root); |
| 121 | +} |
| 122 | + |
99 | 123 | /**
|
100 | 124 | * Run over each entry in the missing array and transform the missing from list of paths
|
101 | 125 | * to object with missing types
|
102 | 126 | *
|
103 | 127 | * @param {Array} missings
|
104 | 128 | * @returns new object with grouped missings
|
105 | 129 | */
|
106 |
| -function groupMissings(missings) { |
| 130 | +function groupMissings(missings, cwd, consumerPath) { |
107 | 131 | const groups = byPathType(missings);
|
108 |
| - groups.packages = groups.packages ? groups.packages.map(resolveMissingPackageName) : undefined; |
| 132 | + const packages = groups.packages ? groups.packages.map(resolveMissingPackageName) : []; |
| 133 | + // This is a hack to solve problems that madge has with packages for type script files |
| 134 | + // It see them as missing even if they are exists |
| 135 | + const foundedPackages = {}; |
| 136 | + const missingPackages = []; |
| 137 | + packages.forEach((packageName) => { |
| 138 | + const resolvedPath = resolveModulePath(packageName, cwd, consumerPath); |
| 139 | + if (!resolvedPath) { |
| 140 | + return missingPackages.push(packageName); |
| 141 | + } |
| 142 | + const packageWithVersion = resloveNodePackage(resolvedPath); |
| 143 | + return packageWithVersion ? Object.assign(foundedPackages, packageWithVersion) : |
| 144 | + missingPackages.push(packageWithVersion); |
| 145 | + }); |
| 146 | + groups.packages = missingPackages; |
109 | 147 |
|
110 |
| - return groups; |
| 148 | + return { groups, foundedPackages }; |
111 | 149 | }
|
112 | 150 |
|
113 |
| - |
114 | 151 | /**
|
115 | 152 | * Function for fetching dependency tree of file or dir
|
116 | 153 | * @param cwd working directory
|
117 | 154 | * @param filePath path of the file to calculate the dependecies
|
118 | 155 | * @return {Promise<{missing, tree}>}
|
119 | 156 | */
|
120 |
| -export default function getDependecyTree(cwd: string, filePath: string): Promise<*> { |
| 157 | +export default function getDependecyTree(cwd: string, consumerPath: string, filePath: string): Promise<*> { |
121 | 158 | return madge(filePath, { baseDir: cwd, includeNpm: true })
|
122 |
| - .then((res) => ({ missing: groupMissings(res.skipped), tree: groupDependencyTree(res.tree, cwd) })) |
| 159 | + .then((res) => { |
| 160 | + const { groups, foundedPackages } = groupMissings(res.skipped, cwd, consumerPath); |
| 161 | + const relativeFilePath = path.relative(cwd, filePath); |
| 162 | + const tree = groupDependencyTree(res.tree, cwd); |
| 163 | + // Merge manually found packages with madge founded packages |
| 164 | + if (foundedPackages && !R.isEmpty(foundedPackages)) { |
| 165 | + // Madge found packages so we need to merge them with the manual |
| 166 | + if (tree[relativeFilePath].packages) { |
| 167 | + Object.assign(tree[relativeFilePath].packages, foundedPackages); |
| 168 | + // There is only manually found packages |
| 169 | + } else { |
| 170 | + tree[relativeFilePath].packages = foundedPackages; |
| 171 | + } |
| 172 | + } |
| 173 | + return { missing: groups, tree }; |
| 174 | + }); |
123 | 175 | }
|
0 commit comments