Skip to content

Commit

Permalink
feat(resolve-dependencies): add more projects to install when resolving
Browse files Browse the repository at this point in the history
  • Loading branch information
kenrick95 committed Aug 17, 2022
1 parent 16ae965 commit b458ef5
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 8 deletions.
Expand Up @@ -2,7 +2,8 @@
"name": "@kenrick95/internal-f",
"version": "1.0.0",
"dependencies": {
"is-positive": "1.0.0"
"is-positive": "1.0.0",
"is-negative": "1.0.0"
}
}

4 changes: 4 additions & 0 deletions packages/core/src/install/extendInstallOptions.ts
Expand Up @@ -12,6 +12,7 @@ import {
PeerDependencyRules,
ReadPackageHook,
Registries,
Project,
} from '@pnpm/types'
import pnpmPkgJson from '../pnpmPkgJson'
import { ReporterFunction } from '../types'
Expand Down Expand Up @@ -109,6 +110,9 @@ export interface StrictInstallOptions {
global: boolean
globalBin?: string
patchedDependencies?: Record<string, string>

allProjects?: Project[]
workspaceDir?: string
}

export type InstallOptions =
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/install/index.ts
Expand Up @@ -806,6 +806,8 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
{
allowBuild: createAllowBuildFunction(opts),
allowedDeprecatedVersions: opts.allowedDeprecatedVersions,
allProjects: opts.allProjects,
workspaceDir: opts.workspaceDir,
autoInstallPeers: opts.autoInstallPeers,
currentLockfile: ctx.currentLockfile,
defaultUpdateDepth: (opts.update || (opts.updateMatching != null)) ? opts.depth : -1,
Expand Down
2 changes: 2 additions & 0 deletions packages/plugin-commands-installation/src/installDeps.ts
Expand Up @@ -190,6 +190,8 @@ when running add/update with the --workspace option')
storeController: store.ctrl,
storeDir: store.dir,
workspacePackages,
workspaceDir: opts.workspaceDir,
allProjects: opts.allProjects,
}
if (opts.global && opts.pnpmHomeDir != null) {
const nodeExecPath = await getNodeExecPath()
Expand Down
28 changes: 23 additions & 5 deletions packages/plugin-commands-installation/test/installDeep.ts
Expand Up @@ -12,11 +12,12 @@ const f = fixtures(__dirname)

test('Installing a package deeply installs all required dependencies', async () => {
f.prepare('workspace-external-depends-deep')
const cwd = process.cwd()
const {
allProjects,
selectedProjectsGraph,
} = await readProjects(process.cwd(), [
{ namePattern: '@kenrick95/internal-f' },
{ namePattern: '@kenrick95/internal-g' },
])
for (const project of allProjects) {
await rimraf(path.join(project.dir, 'node_modules'))
Expand All @@ -25,24 +26,41 @@ test('Installing a package deeply installs all required dependencies', async ()
const projectGraphKeys = Object.keys(selectedProjectsGraph)
expect(projectGraphKeys).toHaveLength(1)
expect(selectedProjectsGraph[projectGraphKeys[0]].package.manifest.name).toBe(
'@kenrick95/internal-f'
'@kenrick95/internal-g'
)

console.log('projectGraphKeys', projectGraphKeys)
console.log('cwd', cwd)

await install.handler({
...DEFAULT_OPTS,
dir: process.cwd(),
workspaceDir: process.cwd(),
dir: cwd,
workspaceDir: cwd,

allProjects,
recursive: true,
selectedProjectsGraph,
preferWorkspacePackages: true,
linkWorkspacePackages: 'deep',
})

for (const project of allProjects) {
console.log(project.dir, await fs.readdir(project.dir))
const files = await fs.readdir(project.dir)
console.log(project.dir, files)
if (files.includes('node_modules')) {
console.log(
project.dir,
'node_modules',
await fs.readdir(path.join(project.dir, 'node_modules'))
)
// Somehow "g" now has pnpm-lock.yaml ???
}
}

for (const project of allProjects) {
if (project.dir === cwd) {
continue
}
const projectAssertion = assertProject(project.dir)
expect(projectAssertion.requireModule('is-positive')).toBeTruthy()
}
Expand Down
1 change: 1 addition & 0 deletions packages/resolve-dependencies/package.json
Expand Up @@ -32,6 +32,7 @@
"@pnpm/constants": "workspace:*",
"@pnpm/core-loggers": "workspace:*",
"@pnpm/error": "workspace:*",
"@pnpm/filter-workspace-packages": "workspace:*",
"@pnpm/lockfile-types": "workspace:*",
"@pnpm/lockfile-utils": "workspace:*",
"@pnpm/manifest-utils": "workspace:*",
Expand Down
67 changes: 66 additions & 1 deletion packages/resolve-dependencies/src/index.ts
Expand Up @@ -13,8 +13,10 @@ import {
getSpecFromPackageManifest,
PinnedVersion,
} from '@pnpm/manifest-utils'
import { filterPkgsBySelectorObjects } from '@pnpm/filter-workspace-packages'
import { safeReadPackageFromDir as safeReadPkgFromDir } from '@pnpm/read-package-json'
import {
Project,
DEPENDENCIES_FIELDS,
DependencyManifest,
ProjectManifest,
Expand Down Expand Up @@ -79,6 +81,8 @@ export type ImporterToResolve = Importer<{
export default async function (
importers: ImporterToResolve[],
opts: ResolveDependenciesOptions & {
allProjects?: Project[]
workspaceDir?: string
defaultUpdateDepth: number
preserveWorkspaceProtocol: boolean
saveWorkspaceProtocol: 'rolling' | boolean
Expand All @@ -93,8 +97,10 @@ export default async function (
virtualStoreDir: opts.virtualStoreDir,
workspacePackages: opts.workspacePackages,
})
console.log('importers', JSON.stringify(importers))
const projectsToResolve = await Promise.all(importers.map(async (project) => _toResolveImporter(project)))
const {
console.log('projectsToResolve', JSON.stringify(projectsToResolve))
let {
dependenciesTree,
outdatedDependencies,
resolvedImporters,
Expand All @@ -103,6 +109,65 @@ export default async function (
appliedPatches,
} = await resolveDependencyTree(projectsToResolve, opts)

while (true) {
if (!opts.workspaceDir || !opts.allProjects) {
break
}

const allProjectsToResolve = new Set(projectsToResolve.map(p => p.manifest.name))
console.log('dependenciesTree', dependenciesTree)

const newProjects = []
for (const node of Object.values(dependenciesTree)) {
if (node.depth === -1 && node.resolvedPackage.name) {
if (!allProjectsToResolve.has(node.resolvedPackage.name)) {
newProjects.push(node.resolvedPackage.name)
}
}
}
if (newProjects.length === 0) {
break
}

{
const { selectedProjectsGraph } = await filterPkgsBySelectorObjects(
opts.allProjects,
newProjects.map(newP => ({
namePattern: newP,
includeDependencies: true,
})),
{
workspaceDir: opts.workspaceDir,
}
)

for (const node of Object.values(selectedProjectsGraph)) {
const importer = {
id: '.', // What value should I use?
manifest: node.package.manifest,
originalManifest: node.package.manifest,
modulesDir: path.join(node.package.dir, 'node_modules'),
rootDir: node.package.dir,
binsDir: path.join(node.package.dir, 'node_modules', '.bin'),
wantedDependencies: [],
updatePackageManifest: false,
mutation: 'install', // How to do this only for mutation == install?
} as ImporterToResolve
importers.push(importer)
const projectToResolve = await _toResolveImporter(importer)
projectsToResolve.push(projectToResolve)
}
}

const result = await resolveDependencyTree(projectsToResolve, opts)
dependenciesTree = result.dependenciesTree
outdatedDependencies = result.outdatedDependencies
resolvedImporters = result.resolvedImporters
resolvedPackagesByDepPath = result.resolvedPackagesByDepPath
wantedToBeSkippedPackageIds = result.wantedToBeSkippedPackageIds
appliedPatches = result.appliedPatches
}

// We only check whether patches were applied in cases when the whole lockfile was reanalyzed.
if (
opts.patchedDependencies &&
Expand Down
5 changes: 4 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit b458ef5

Please sign in to comment.