| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- #!/usr/bin/env node
- 'use strict'
- /**
- * Materialize Cypress reporter packages (and their transitive dependencies)
- * into a real node_modules tree so that Cypress's Electron process (which uses
- * PackherdModuleLoader, NOT Yarn PnP hooks) can load them.
- *
- * Builds a NESTED node_modules structure (each package gets its own
- * node_modules/ for its deps) to avoid version conflicts from flat dedup.
- *
- * The target-dir must be OUTSIDE the PnP workspace root — otherwise PnP
- * intercepts requires from the materialized packages and blocks undeclared deps.
- *
- * Usage: yarn node scripts/materialize-cypress-reporter.js <target-dir>
- */
- const path = require('path')
- const fs = require('fs')
- const targetDir = process.argv[2]
- if (!targetDir) {
- console.error(
- 'Usage: yarn node scripts/materialize-cypress-reporter.js <target-dir>'
- )
- process.exit(1)
- }
- const pnp = require('module').findPnpApi(__filename)
- if (!pnp) {
- console.log('Not running under PnP — nothing to do.')
- process.exit(0)
- }
- let totalCopied = 0
- // PnP patches readFileSync/readdirSync/statSync but NOT cpSync.
- // Manual recursive copy to read from virtual/zip paths.
- function copyRecursive(src, dest) {
- const stat = fs.statSync(src)
- if (stat.isDirectory()) {
- fs.mkdirSync(dest, { recursive: true })
- for (const entry of fs.readdirSync(src)) {
- copyRecursive(path.join(src, entry), path.join(dest, entry))
- }
- } else {
- fs.mkdirSync(path.dirname(dest), { recursive: true })
- fs.writeFileSync(dest, fs.readFileSync(src))
- }
- }
- function resolvePkgDir(pkgName, issuer) {
- // Use resolveToUnqualified to get the package directory without going
- // through the package's exports map (which may not expose package.json).
- let pkgDir = pnp.resolveToUnqualified(pkgName, issuer + '/')
- if (pkgDir.endsWith('/')) pkgDir = pkgDir.slice(0, -1)
- return pkgDir
- }
- /**
- * Materialize a package and its deps into destDir/node_modules/pkgName.
- * Each package's own deps get nested under its own node_modules/.
- */
- function materializeRecursive(pkgName, issuer, destNodeModules, seen) {
- // Dedupe by destination path to avoid infinite loops, but allow the same
- // package to appear in multiple locations (nested node_modules).
- const key = `${destNodeModules}/${pkgName}`
- if (seen.has(key)) return
- seen.add(key)
- let pkgDir
- try {
- pkgDir = resolvePkgDir(pkgName, issuer)
- } catch {
- return // optional/missing dep
- }
- const dest = path.join(destNodeModules, pkgName)
- copyRecursive(pkgDir, dest)
- totalCopied++
- const pkg = JSON.parse(
- fs.readFileSync(path.join(pkgDir, 'package.json'), 'utf8')
- )
- const deps = [
- ...Object.keys(pkg.dependencies || {}),
- ...Object.keys(pkg.peerDependencies || {}),
- ]
- if (deps.length > 0) {
- const nestedNodeModules = path.join(dest, 'node_modules')
- for (const dep of deps) {
- materializeRecursive(dep, pkgDir, nestedNodeModules, seen)
- }
- }
- }
- const rootNodeModules = path.resolve(targetDir, 'node_modules')
- const seen = new Set()
- const topLevel = [
- 'cypress-multi-reporters',
- 'mocha-junit-reporter',
- 'typescript',
- ]
- for (const pkg of topLevel) {
- try {
- materializeRecursive(pkg, process.cwd(), rootNodeModules, seen)
- } catch (e) {
- console.warn(`Warning: could not materialize ${pkg}: ${e.message}`)
- }
- }
- console.log(`Materialized ${totalCopied} packages into ${rootNodeModules}`)
|