Skip to content

Commit

Permalink
feat(deploy): apply publishConfig to all packages during deploy (#6943)
Browse files Browse the repository at this point in the history
When deploying packages, the package.json of the deployed package
(as well as any other locally defined dependencies)
should be treated as if it published, and mutate the package.json
according to `publishConfig` and local `workspace:` dependencies.

close #6693

---------

Co-authored-by: Zoltan Kochan <[email protected]>
  • Loading branch information
JacobLey and zkochan committed Feb 13, 2024
1 parent 8936f6f commit 7ac0389
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 276 deletions.
6 changes: 6 additions & 0 deletions .changeset/flat-kids-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@pnpm/plugin-commands-deploy": minor
"@pnpm/directory-fetcher": minor
---

Apply `publishConfig` for workspace packages on directory fetch. Enables a publishable ("exportable") `package.json` on deployment [#6693](https://github.com/pnpm/pnpm/issues/6693).
5 changes: 4 additions & 1 deletion fetching/directory-fetcher/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@
"@pnpm/logger": "^5.0.0"
},
"dependencies": {
"@pnpm/exportable-manifest": "workspace:*",
"@pnpm/fetcher-base": "workspace:*",
"@pnpm/fs.packlist": "workspace:*",
"@pnpm/read-project-manifest": "workspace:*",
"@pnpm/resolver-base": "workspace:*",
"@pnpm/types": "workspace:*"
"@pnpm/types": "workspace:*",
"@pnpm/write-project-manifest": "workspace:*",
"fast-deep-equal": "^3.1.3"
},
"devDependencies": {
"@pnpm/directory-fetcher": "workspace:*",
Expand Down
38 changes: 23 additions & 15 deletions fetching/directory-fetcher/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { promises as fs, type Stats } from 'fs'
import path from 'path'
import { createExportableManifest } from '@pnpm/exportable-manifest'
import type { DirectoryFetcher, DirectoryFetcherOptions } from '@pnpm/fetcher-base'
import { logger } from '@pnpm/logger'
import { packlist } from '@pnpm/fs.packlist'
import { safeReadProjectManifestOnly } from '@pnpm/read-project-manifest'
import { type DependencyManifest } from '@pnpm/types'
import type { ProjectManifest } from '@pnpm/types'
import { writeProjectManifest } from '@pnpm/write-project-manifest'
import equal from 'fast-deep-equal'

const directoryFetcherLogger = logger('directory-fetcher')

Expand Down Expand Up @@ -48,13 +51,7 @@ async function fetchAllFilesFromDir (
opts: FetchFromDirOpts
) {
const filesIndex = await _fetchAllFilesFromDir(readFileStat, dir)
let manifest: DependencyManifest | undefined
if (opts.readManifest) {
// In a regular pnpm workspace it will probably never happen that a dependency has no package.json file.
// Safe read was added to support the Bit workspace in which the components have no package.json files.
// Related PR in Bit: https://github.com/teambit/bit/pull/5251
manifest = await safeReadProjectManifestOnly(dir) as DependencyManifest ?? undefined
}
const manifest = await safeReadProjectManifestAndMakeExportable(dir, filesIndex) ?? {}
return {
local: true as const,
filesIndex,
Expand Down Expand Up @@ -130,17 +127,28 @@ async function fetchPackageFilesFromDir (
) {
const files = await packlist(dir)
const filesIndex: Record<string, string> = Object.fromEntries(files.map((file) => [file, path.join(dir, file)]))
let manifest: DependencyManifest | undefined
if (opts.readManifest) {
// In a regular pnpm workspace it will probably never happen that a dependency has no package.json file.
// Safe read was added to support the Bit workspace in which the components have no package.json files.
// Related PR in Bit: https://github.com/teambit/bit/pull/5251
manifest = await safeReadProjectManifestOnly(dir) as DependencyManifest ?? undefined
}
const manifest = await safeReadProjectManifestAndMakeExportable(dir, filesIndex) ?? {}
return {
local: true as const,
filesIndex,
packageImportMethod: 'hardlink' as const,
manifest,
}
}

async function safeReadProjectManifestAndMakeExportable (
dir: string,
filesIndex: Record<string, string>
): Promise<ProjectManifest | null> {
const manifest = await safeReadProjectManifestOnly(dir)
// In a regular pnpm workspace it will probably never happen that a dependency has no package.json file.
// Safe read was added to support the Bit workspace in which the components have no package.json files.
// Related PR in Bit: https://github.com/teambit/bit/pull/5251
if (!manifest) return null
const exportableManifest = await createExportableManifest(dir, manifest)
if (equal(manifest, exportableManifest)) return manifest
const manifestPathOverride = path.join(dir, 'node_modules/.pnpm/package.json')
await writeProjectManifest(manifestPathOverride, exportableManifest)
filesIndex['package.json'] = manifestPathOverride
return manifest
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "exportable",
"version": "1.0.0",
"main": "src/index.ts",
"publishConfig": {
"main": "dist/index.js"
}
}
21 changes: 21 additions & 0 deletions fetching/directory-fetcher/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,24 @@ describe('fetch resolves symlinked files to their real locations', () => {
expect(fetchResult.filesIndex['src/index.js']).toBe(path.resolve('src/index.js'))
})
})

test('fetch should return exportable manifest', async () => {
process.chdir(f.find('exportable-manifest'))
const fetcher = createDirectoryFetcher()

// eslint-disable-next-line
const fetchResult = await fetcher.directory({} as any, {
directory: '.',
type: 'directory',
}, {
lockfileDir: process.cwd(),
})

expect(fetchResult.filesIndex['package.json']).not.toBe(path.resolve('package.json'))

expect(JSON.parse(fs.readFileSync(fetchResult.filesIndex['package.json'], 'utf8'))).toStrictEqual({
name: 'exportable',
version: '1.0.0',
main: 'dist/index.js',
})
})
7 changes: 5 additions & 2 deletions fetching/directory-fetcher/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@
"path": "../../__utils__/test-fixtures"
},
{
"path": "../../fs/packlist"
"path": "../../packages/types"
},
{
"path": "../../packages/types"
"path": "../../pkg-manifest/exportable-manifest"
},
{
"path": "../../pkg-manifest/read-project-manifest"
},
{
"path": "../../pkg-manifest/write-project-manifest"
},
{
"path": "../../resolving/resolver-base"
},
Expand Down

0 comments on commit 7ac0389

Please sign in to comment.