(cwd, relPath, failOnMissingFiles = true)
| 175 | } |
| 176 | |
| 177 | async _getModulesFromPath(cwd, relPath, failOnMissingFiles = true) { |
| 178 | const nodePath = path.join(cwd, relPath); |
| 179 | if (this.#visitedNodePaths.has(nodePath)) { |
| 180 | log.verbose(`Module located at ${nodePath} has already been visited`); |
| 181 | return []; |
| 182 | } |
| 183 | this.#visitedNodePaths.add(nodePath); |
| 184 | let pkg; |
| 185 | try { |
| 186 | pkg = await this._readPackageJson(nodePath); |
| 187 | if (!pkg?.name || !pkg?.version) { |
| 188 | throw new Error( |
| 189 | `package.json must contain fields 'name' and 'version'`); |
| 190 | } |
| 191 | } catch (err) { |
| 192 | if (!failOnMissingFiles && err.code === "ENOENT") { |
| 193 | // When resolving a dynamic workspace pattern (not a static path), ignore modules that |
| 194 | // are missing a package.json (this might simply indicate an empty directory) |
| 195 | log.verbose(`Ignoring module at path ${nodePath}: Directory does not contain a package.json`); |
| 196 | return []; |
| 197 | } |
| 198 | throw new Error( |
| 199 | `Failed to resolve workspace dependency resolution path ${relPath} to ${nodePath}: ${err.message}`); |
| 200 | } |
| 201 | |
| 202 | // If the package.json defines an npm "workspaces", or an equivalent "ui5.workspaces" configuration, |
| 203 | // resolve the workspace and only use the resulting modules. The root package is ignored. |
| 204 | const packageWorkspaceConfig = pkg.ui5?.workspaces || pkg.workspaces; |
| 205 | if (packageWorkspaceConfig?.length) { |
| 206 | log.verbose(`Module ${pkg.name} provides a package.json workspaces configuration. ` + |
| 207 | `Ignoring the module and resolving workspaces instead...`); |
| 208 | const staticPatterns = []; |
| 209 | // Split provided patterns into dynamic and static patterns |
| 210 | // This is necessary, since fast-glob currently behaves different from |
| 211 | // "glob" (used by @npmcli/map-workspaces) in that it does not match the |
| 212 | // base directory in case it is equal to the pattern (https://github.com/mrmlnc/fast-glob/issues/47) |
| 213 | // For example a pattern "package-a" would not match a directory called |
| 214 | // "package-a" in the root directory of the project. |
| 215 | // We therefore detect the static pattern and resolve it directly |
| 216 | const dynamicPatterns = packageWorkspaceConfig.filter((pattern) => { |
| 217 | if (isDynamicPattern(pattern)) { |
| 218 | return true; |
| 219 | } else { |
| 220 | staticPatterns.push(pattern); |
| 221 | return false; |
| 222 | } |
| 223 | }); |
| 224 | |
| 225 | let searchPaths = []; |
| 226 | if (dynamicPatterns.length) { |
| 227 | searchPaths = await globby(dynamicPatterns, { |
| 228 | cwd: nodePath, |
| 229 | followSymbolicLinks: false, |
| 230 | onlyDirectories: true, |
| 231 | }); |
| 232 | } |
| 233 | searchPaths.push(...staticPatterns); |
| 234 |
no test coverage detected