Skip to content

feat(cli/config): get/set objects and property paths#9811

Merged
zkochan merged 30 commits intomainfrom
pnpm-config-get-object-object-9797
Aug 14, 2025
Merged

feat(cli/config): get/set objects and property paths#9811
zkochan merged 30 commits intomainfrom
pnpm-config-get-object-object-9797

Conversation

@KSXGitHub
Copy link
Copy Markdown
Contributor

Resolves #9797

return { output: Array.isArray(config) ? config.join(',') : String(config), exitCode: 0 }
let output: string
if (Array.isArray(config)) {
output = config.join(',')
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was on me: #7917. I don't remember why I decided to return a comma-separated list instead of a JSON string, but changing it now would be a breaking change.

@KSXGitHub
Copy link
Copy Markdown
Contributor Author

I do feel that pnpm config get and pnpm config set are still incomplete. Especially now that pnpm has expand its config structure to more nested objects.

pnpm config get can get an object, but not the property of that object. Perhaps we could make pnpm config get packageExtensions react dependencies to access config.packageExtensions.react.dependencies? Or perhaps we should make pnpm config get ignores pnpm-workspace.yaml entirely?

@zkochan
Copy link
Copy Markdown
Member

zkochan commented Jul 29, 2025

Yes, probably we should support that. But I think the field names should be separated by dots:

pnpm config get packageExtensions.react.dependencies

@KSXGitHub
Copy link
Copy Markdown
Contributor Author

Yes, probably we should support that. But I think the field names should be separated by dots

jq does that. And looks good too. The problem is how are we suppose to escape dots in property name? Do we make another property path parser similar to jq? Is there an existing library for that?

@KSXGitHub
Copy link
Copy Markdown
Contributor Author

And escaping is necessary because dependency names can contain all kinds of symbols: @, /, ., etc.

@zkochan
Copy link
Copy Markdown
Member

zkochan commented Jul 29, 2025

See how Yarn also supports this: https://yarnpkg.com/cli/config/set

We can check what library Yarn uses. It should be something small.

@KSXGitHub KSXGitHub force-pushed the pnpm-config-get-object-object-9797 branch 4 times, most recently from 3b1a9ef to e28f84f Compare August 3, 2025 20:04
@zkochan

This comment was marked as resolved.

@KSXGitHub

This comment was marked as resolved.

@KSXGitHub KSXGitHub force-pushed the pnpm-config-get-object-object-9797 branch 2 times, most recently from 8161463 to 0dc5e8d Compare August 4, 2025 15:45
@KSXGitHub KSXGitHub force-pushed the pnpm-config-get-object-object-9797 branch from 0dc5e8d to aeef6df Compare August 5, 2025 21:31
@KSXGitHub
Copy link
Copy Markdown
Contributor Author

KSXGitHub commented Aug 8, 2025

Discovered flaws

Note

The following flaws can't be fixed without breaking changes.

  • pnpm config get _authToken would emit an error from npm, but pnpm config list shows it regardless.
  • pnpm config set <npm-setting> would write to ~/.npmrc despite local pnpm-workspace.yaml exists.
  • the global rc file (~/.config/pnpm/rc) can set workspace specific settings (such as packages).
  • pnpm config get <array> prints comma-separated list instead of INI.
  • pnpm config list would have kebab-case for top-level keys but camelCase for non-top-level keys.

@KSXGitHub KSXGitHub changed the title feat: config get prints json for object feat(cli/config): get/set objects and property paths Aug 11, 2025
@KSXGitHub KSXGitHub marked this pull request as ready for review August 13, 2025 21:20
@KSXGitHub KSXGitHub requested a review from zkochan as a code owner August 13, 2025 21:20
Copy link
Copy Markdown
Member

@zkochan zkochan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@KSXGitHub KSXGitHub requested a review from zkochan August 14, 2025 00:02
@zkochan zkochan merged commit b84c71d into main Aug 14, 2025
19 of 21 checks passed
@zkochan zkochan deleted the pnpm-config-get-object-object-9797 branch August 14, 2025 08:28
export class ConfigSetDeepKeyError extends PnpmError {
constructor () {
// it shouldn't be supported until there is a mechanism to validate the config value
super('CONFIG_SET_DEEP_KEY', 'Setting deep property path is not supported')
Copy link
Copy Markdown

@JounQin JounQin Aug 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error breaks pnpm config set supportedArchitectures.cpu "${CPU_ARCH}", what's the replacement then?

https://github.com/oxc-project/oxc-resolver/actions/runs/17197957513/job/48783406788#step:3:67

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not break. It only reveals a flawed assumption.

pnpm config set supportedArchitectures.cpu doesn't actually do what you think it does:

what `pnpm config set supportedArchitectures.cpu` actually does

As you can see, it didn't actually create an object named supportedArchitectures with the content { "cpu": "x64" }. Instead, it added a field named supported-architectures-cpu to the global rc file.

what's the replacement then?

Write a small JS script that modifies package.json. This applies to older pnpm too (because it has never worked with older pnpm, it's just that they don't print error).

Copy link
Copy Markdown

@JounQin JounQin Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KSXGitHub But config get works after config set previously.

image

Anyway, we want to modify the global pnpm config without changing the source files, it seems impossible now?

Personally, I think merging this PR without implementing setting correctly is incomplete and should be considered as BREAKING CHNAGE.

Copy link
Copy Markdown
Contributor Author

@KSXGitHub KSXGitHub Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But config get works after config set previously.
image

pnpm config get supportedArchitectures.cpu is literally the same as pnpm config get supported-architectures-cpu (there's no object path, just a property name that makes no sense). You were already misusing it before, removing it has zero effect.

Anyway, we want to modify the global pnpm config without changing the source files, it seems impossible now?

pnpm has never read supportedArchitectures from rc files, be it local or global. The fact pnpm get makes it seems like your use-case has effect was just an illusion caused by ill-thought-out config implementation. But the loading code has always only loads fields that appear in types (which doesn't include supportedArchitectures):

const pnpmConfig: ConfigWithDeprecatedSettings = Object.fromEntries(
rcOptions.map((configKey) => [camelcase(configKey, { locale: 'en-US' }), npmConfig.get(configKey)])
) as ConfigWithDeprecatedSettings

In other words, it was always impossible, it's just that older pnpm versions silently ignored the error.

BREAKING CHNAGE

I certainly didn't think anybody would be mistakenly believing that pnpm supports property paths, but then I have insight from the code itself. Regardless though, I don't think it's a breaking change because it doesn't actually break legitimate use-cases, it only reveals a nonsense use-case that doesn't do anything.

You may believe that temporary downgrade pnpm would fix the problem, but it actually doesn't, because as I already explained: pnpm get/set supportedArchitectures.cpu doesn't do anything except reading/setting supported-architectures-cpu which has zero effect. It is the same as not doing anything at all. The only way to fix the problem is to replace the wrong pnpm config set with a script that modifies either package.json or pnpm-workspace.yaml.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I also made a suggestion to your PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pnpm get config on properties with object values returns [object Object]

3 participants