New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(pkg-manifest): preserve comments in json5 manifests #5677
Conversation
@@ -118,9 +119,72 @@ export async function tryReadProjectManifest (projectDir: string): Promise<{ | |||
} | |||
|
|||
function detectFileFormatting (text: string) { | |||
const finalNewline = text.endsWith('\n') | |||
if (!finalNewline) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this new logic to a new function and don't run it for JSON files.
.stringify(manifest, undefined, opts?.indent ?? '\t') | ||
|
||
if (opts?.comments) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this new logic to a function and don't run it for JSON files.
Use npm package `strip-comments-strings` to find all comments in any manifest file as it is read. Save them as part of the "file formatting" detected by the manifest reader, noting for each the text of the lines they are on, before, and after, and the line number as a fallback. When the manifest is written, attempt to place each comment back in the resulting JSON5 text, so that the text of the line it is on, before, or after (in that priority order) matches the text at time of reading. Otherwise, so that no comments are lost, replace the comment on the same line number, adding a notation that it may have been relocated (due to sorting dependencies, for example, it may no longer be in the same "logical position" in the file, even though it is on the same physical line number). When comments are in fairly ordinary positions and the manifest does not change too drastically (i.e. once the dependencies are sorted as pnpm prefers, and there are not many parameters added all at once), this strategy results in exact preservation of the comments, as a new test shows. The motivation for this commit is to take advantage of the feature of JSON5 that it allows human-readable comments. For this feature to be useful in the case of package.json5 manifests, those comments must be preserved across manifest changes. Partially resolves pnpm#2008. [That issue requests comment preservation also for YAML manifests, but I have no experience working with YAML, and it also requests that key order be preserved, but I did not address key order because current code in the the pnpm manifest reader/writer _explicitly_ reorders keys -- clearly deliberately -- so I did not want to simply remove code that appeared to have been purposefully written and included.]
(Including one unused variable that was inadvertently left in.)
Move comment extraction and reinsertion into their own functions, called only when the manifest is Json5.
c785009
to
7fba4af
Compare
I think that should take care of your current requests. Thanks for reviewing. |
Use npm package
strip-comments-strings
to find all comments in anymanifest file as it is read. Save them as part of the "file formatting"
detected by the manifest reader, noting for each the text of the lines
they are on, before, and after, and the line number as a fallback.
When the manifest is written, attempt to place each comment back in
the resulting JSON5 text, so that the text of the line it is on,
before, or after (in that priority order) matches the text at time of
reading. Otherwise, so that no comments are lost, replace the comment
on the same line number, adding a notation that it may have been
relocated (due to sorting dependencies, for example, it may no longer
be in the same "logical position" in the file, even though it is on
the same physical line number).
When comments are in fairly ordinary positions and the manifest does
not change too drastically (i.e. once the dependencies are sorted as
pnpm prefers, and there are not many parameters added all at once),
this strategy results in exact preservation of the comments, as a new
test shows.
The motivation for this commit is to take advantage of the feature of
JSON5 that it allows human-readable comments. For this feature to be
useful in the case of package.json5 manifests, those comments must be
preserved across manifest changes.
A cleaner implementation of this facility would parse the json5 manifest,
attaching comments as metadata to the proper nodes of the syntax tree.
However, I am unaware of a json5 parser that does that, and certainly the
parser currently being used does not. So hopefully this pragmatic
approach will be acceptable for production use.
Partially resolves #2008. [That issue requests comment preservation
also for YAML manifests, but I have no experience working with YAML,
and it also requests that key order be preserved, but I did not
address key order because current code in the the pnpm manifest
reader/writer explicitly reorders keys -- clearly deliberately --
so I did not want to simply remove code that appeared to have been
purposefully written and included.]