mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-26 00:28:10 -05:00
fix: don't alway add a trailing new line to package.json
ref #2716 PR #2744
This commit is contained in:
5
.changeset/cuddly-moons-hug.md
Normal file
5
.changeset/cuddly-moons-hug.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/read-project-manifest": patch
|
||||
---
|
||||
|
||||
Trailing new lines are preserved, when updating the read manifests.
|
||||
5
.changeset/pretty-hounds-jump.md
Normal file
5
.changeset/pretty-hounds-jump.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/write-project-manifest": minor
|
||||
---
|
||||
|
||||
New option added: insertFinalNewline. By default, a new line is added to the end of the file. When `options.insertFinalNewline` is false, no trailing new line is added.
|
||||
@@ -49,12 +49,11 @@ export async function tryReadProjectManifest (projectDir: string): Promise<{
|
||||
try {
|
||||
const manifestPath = path.join(projectDir, 'package.json')
|
||||
const { data, text } = await readJsonFile(manifestPath)
|
||||
const { indent } = detectIndent(text)
|
||||
return {
|
||||
fileName: 'package.json',
|
||||
manifest: data,
|
||||
writeProjectManifest: createManifestWriter({
|
||||
indent,
|
||||
...detectFileFormatting(text),
|
||||
initialManifest: data,
|
||||
manifestPath,
|
||||
}),
|
||||
@@ -65,12 +64,11 @@ export async function tryReadProjectManifest (projectDir: string): Promise<{
|
||||
try {
|
||||
const manifestPath = path.join(projectDir, 'package.json5')
|
||||
const { data, text } = await readJson5File(manifestPath)
|
||||
const { indent } = detectIndent(text)
|
||||
return {
|
||||
fileName: 'package.json5',
|
||||
manifest: data,
|
||||
writeProjectManifest: createManifestWriter({
|
||||
indent,
|
||||
...detectFileFormatting(text),
|
||||
initialManifest: data,
|
||||
manifestPath,
|
||||
}),
|
||||
@@ -111,16 +109,22 @@ export async function tryReadProjectManifest (projectDir: string): Promise<{
|
||||
}
|
||||
}
|
||||
|
||||
function detectFileFormatting (text: string) {
|
||||
return {
|
||||
indent: detectIndent(text).indent,
|
||||
insertFinalNewline: text.endsWith('\n'),
|
||||
}
|
||||
}
|
||||
|
||||
export async function readExactProjectManifest (manifestPath: string) {
|
||||
const base = path.basename(manifestPath).toLowerCase()
|
||||
switch (base) {
|
||||
case 'package.json': {
|
||||
const { data, text } = await readJsonFile(manifestPath)
|
||||
const { indent } = detectIndent(text)
|
||||
return {
|
||||
manifest: data,
|
||||
writeProjectManifest: createManifestWriter({
|
||||
indent,
|
||||
...detectFileFormatting(text),
|
||||
initialManifest: data,
|
||||
manifestPath,
|
||||
}),
|
||||
@@ -128,11 +132,10 @@ export async function readExactProjectManifest (manifestPath: string) {
|
||||
}
|
||||
case 'package.json5': {
|
||||
const { data, text } = await readJson5File(manifestPath)
|
||||
const { indent } = detectIndent(text)
|
||||
return {
|
||||
manifest: data,
|
||||
writeProjectManifest: createManifestWriter({
|
||||
indent,
|
||||
...detectFileFormatting(text),
|
||||
initialManifest: data,
|
||||
manifestPath,
|
||||
}),
|
||||
@@ -164,6 +167,7 @@ function createManifestWriter (
|
||||
opts: {
|
||||
initialManifest: ProjectManifest,
|
||||
indent?: string | number | undefined,
|
||||
insertFinalNewline?: boolean,
|
||||
manifestPath: string,
|
||||
}
|
||||
): (WriteProjectManifest) {
|
||||
@@ -171,7 +175,10 @@ function createManifestWriter (
|
||||
return async (updatedManifest: ProjectManifest, force?: boolean) => {
|
||||
updatedManifest = normalize(updatedManifest)
|
||||
if (force === true || !equal(initialManifest, updatedManifest)) {
|
||||
return writeProjectManifest(opts.manifestPath, updatedManifest, { indent: opts.indent })
|
||||
return writeProjectManifest(opts.manifestPath, updatedManifest, {
|
||||
indent: opts.indent,
|
||||
insertFinalNewline: opts.insertFinalNewline,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,3 +164,31 @@ test('fail on invalid YAML', async (t) => {
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('preserve trailing new line at the end of package.json', async (t) => {
|
||||
process.chdir(tempy.directory())
|
||||
|
||||
await writeFile('package.json', '{}', 'utf8')
|
||||
|
||||
const { manifest, writeProjectManifest } = await readProjectManifest(process.cwd())
|
||||
|
||||
await writeProjectManifest({ ...manifest, dependencies: { bar: '1.0.0' } })
|
||||
|
||||
const rawManifest = await readFile('package.json', 'utf8')
|
||||
t.equal(rawManifest, '{"dependencies":{"bar":"1.0.0"}}')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('preserve trailing new line at the end of package.json5', async (t) => {
|
||||
process.chdir(tempy.directory())
|
||||
|
||||
await writeFile('package.json5', '{}', 'utf8')
|
||||
|
||||
const { manifest, writeProjectManifest } = await readProjectManifest(process.cwd())
|
||||
|
||||
await writeProjectManifest({ ...manifest, dependencies: { bar: '1.0.0' } })
|
||||
|
||||
const rawManifest = await readFile('package.json5', 'utf8')
|
||||
t.equal(rawManifest, "{dependencies:{bar:'1.0.0'}}")
|
||||
t.end()
|
||||
})
|
||||
|
||||
@@ -30,12 +30,16 @@
|
||||
"homepage": "https://github.com/pnpm/pnpm/blob/master/packages/write-project-manifest#readme",
|
||||
"dependencies": {
|
||||
"@pnpm/types": "workspace:^6.2.0",
|
||||
"write-json-file": "4.0.0",
|
||||
"write-json5-file": "^3.0.0",
|
||||
"json5": "^2.1.3",
|
||||
"mz": "^2.7.0",
|
||||
"write-file-atomic": "^3.0.3",
|
||||
"write-yaml-file": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pnpm/write-project-manifest": "link:",
|
||||
"@types/json5": "^0.0.30",
|
||||
"@types/mz": "^2.7.1",
|
||||
"@types/write-file-atomic": "^3.0.1",
|
||||
"tempy": "^0.6.0"
|
||||
},
|
||||
"funding": "https://opencollective.com/pnpm"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { ProjectManifest } from '@pnpm/types'
|
||||
import writeJsonFile = require('write-json-file')
|
||||
import writeJson5File = require('write-json5-file')
|
||||
import JSON5 = require('json5')
|
||||
import fs = require('mz/fs')
|
||||
import path = require('path')
|
||||
import writeFileAtomic = require('write-file-atomic')
|
||||
import writeYamlFile = require('write-yaml-file')
|
||||
|
||||
const YAML_FORMAT = {
|
||||
@@ -8,18 +10,24 @@ const YAML_FORMAT = {
|
||||
noRefs: true,
|
||||
}
|
||||
|
||||
export default function writeProjectManifest (
|
||||
export default async function writeProjectManifest (
|
||||
filePath: string,
|
||||
manifest: ProjectManifest,
|
||||
opts?: { indent?: string | number | undefined }
|
||||
): Promise<void> {
|
||||
switch (filePath.substr(filePath.lastIndexOf('.') + 1).toLowerCase()) {
|
||||
case 'json5':
|
||||
return writeJson5File(filePath, manifest, opts)
|
||||
case 'yaml':
|
||||
return writeYamlFile(filePath, manifest, YAML_FORMAT)
|
||||
case 'json':
|
||||
default:
|
||||
return writeJsonFile(filePath, manifest, opts)
|
||||
opts?: {
|
||||
indent?: string | number | undefined,
|
||||
insertFinalNewline?: boolean,
|
||||
}
|
||||
): Promise<void> {
|
||||
const fileType = filePath.substr(filePath.lastIndexOf('.') + 1).toLowerCase()
|
||||
if (fileType === 'yaml') {
|
||||
return writeYamlFile(filePath, manifest, YAML_FORMAT)
|
||||
}
|
||||
|
||||
await fs.mkdir(path.dirname(filePath), { recursive: true })
|
||||
const trailingNewline = opts?.insertFinalNewline === false ? '' : '\n'
|
||||
|
||||
const json = (fileType === 'json5' ? JSON5 : JSON)
|
||||
.stringify(manifest, null, opts?.indent ?? '\t')
|
||||
|
||||
return writeFileAtomic(filePath, `${json}${trailingNewline}`)
|
||||
}
|
||||
|
||||
20
pnpm-lock.yaml
generated
20
pnpm-lock.yaml
generated
@@ -2832,18 +2832,26 @@ importers:
|
||||
packages/write-project-manifest:
|
||||
dependencies:
|
||||
'@pnpm/types': 'link:../types'
|
||||
write-json-file: 4.0.0
|
||||
write-json5-file: 3.0.0
|
||||
json5: 2.1.3
|
||||
mz: 2.7.0
|
||||
write-file-atomic: 3.0.3
|
||||
write-yaml-file: 4.1.0
|
||||
devDependencies:
|
||||
'@pnpm/write-project-manifest': 'link:'
|
||||
'@types/json5': 0.0.30
|
||||
'@types/mz': 2.7.1
|
||||
'@types/write-file-atomic': 3.0.1
|
||||
tempy: 0.6.0
|
||||
specifiers:
|
||||
'@pnpm/types': 'workspace:^6.2.0'
|
||||
'@pnpm/write-project-manifest': 'link:'
|
||||
'@types/json5': ^0.0.30
|
||||
'@types/mz': ^2.7.1
|
||||
'@types/write-file-atomic': ^3.0.1
|
||||
json5: ^2.1.3
|
||||
mz: ^2.7.0
|
||||
tempy: ^0.6.0
|
||||
write-json-file: 4.0.0
|
||||
write-json5-file: ^3.0.0
|
||||
write-file-atomic: ^3.0.3
|
||||
write-yaml-file: ^4.1.0
|
||||
privatePackages/assert-project:
|
||||
dependencies:
|
||||
@@ -3636,7 +3644,7 @@ packages:
|
||||
integrity: sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=
|
||||
/@types/mz/2.7.1:
|
||||
dependencies:
|
||||
'@types/node': 14.0.23
|
||||
'@types/node': 14.0.27
|
||||
resolution:
|
||||
integrity: sha512-H86h7KmRDVs9UeSiQvtUeVhS+WYpJSYSsZrRvNYpGWGiytEqxwEtvgRnINESQtCgnojIH2wS2WgaMTJP0firBw==
|
||||
/@types/ncp/2.0.4:
|
||||
@@ -3790,7 +3798,7 @@ packages:
|
||||
integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==
|
||||
/@types/write-file-atomic/3.0.1:
|
||||
dependencies:
|
||||
'@types/node': 14.0.23
|
||||
'@types/node': 14.0.27
|
||||
dev: true
|
||||
resolution:
|
||||
integrity: sha512-o5Pl/qux8JEuFpof5fUg/Fl6R3N26ExJlsmWpB67ayrEJDMIxWdM9NDJacisXeNB7YW+vij8onctH8Pr1Zhi5g==
|
||||
|
||||
Reference in New Issue
Block a user