Cannot request JSON output for CLI command: nix store diff-closures #532

Open
opened 2024-09-25 17:42:29 +00:00 by lehmanator · 1 comment

I wanted to parse the output of nix store diff-closures and discovered this command doesn't accept the --json flag accepted by many other Nix commands.

According to CppNix's manual entry on CLI guidelines:

Terse, machine-readable output formats can also be useful but shouldn’t get in the way of making beautiful CLI output. When needed, commands should offer a --json flag to allow users to easily parse and script the CLI.

This is a good instance to have machine-readable output.

Describe the solution you'd like

Support the --json flag in the nix store diff-closures command.

Not sure what other commands are missing this, but it might be worth adding support for the --json flag in other similar commands that may be missing it.

Describe alternatives you've considered

  • Tried other flags that might be able to add JSON output: --debug, --log-format internal-json, --print-build-logs, --verbosity.
  • Checked the implementation of pkgs.nvd to see if it was using a JSON representation anywhere before formatting for stdout.
  • Only other alternative would be to write a separate output parser to translate the current stdout into JSON. However, it would be much easier to get the JSON first then format that for stdout rather than in the reverse direction.

Additional context

Many other commands support JSON output, and it is useful for building tooling around the Nix CLI. Closure diffs are particularly useful for parsing since that can be used to develop insights about changes and updates.

## Is your feature request related to a problem? Please describe. I wanted to parse the output of `nix store diff-closures` and discovered this command doesn't accept the `--json` flag accepted by many other Nix commands. According to CppNix's [manual entry on CLI guidelines](https://nix.dev/manual/nix/2.23/contributing/cli-guideline#not-only-for-humans): > Terse, machine-readable output formats can also be useful but shouldn’t get in the way of making beautiful CLI output. When needed, commands should offer a --json flag to allow users to easily parse and script the CLI. This is a good instance to have machine-readable output. ## Describe the solution you'd like Support the `--json` flag in the `nix store diff-closures` command. Not sure what other commands are missing this, but it might be worth adding support for the `--json` flag in other similar commands that may be missing it. ## Describe alternatives you've considered - Tried other flags that might be able to add JSON output: `--debug`, `--log-format internal-json`, `--print-build-logs`, `--verbosity`. - Checked the implementation of `pkgs.nvd` to see if it was using a `JSON` representation anywhere before formatting for `stdout`. - Only other alternative would be to write a separate output parser to translate the current `stdout` into `JSON`. However, it would be much easier to get the `JSON` first then format that for `stdout` rather than in the reverse direction. ## Additional context Many other commands support `JSON` output, and it is useful for building tooling around the Nix CLI. Closure diffs are particularly useful for parsing since that can be used to develop insights about changes and updates.
Owner

In principle I agree that we should have structured output, but I don't think that nix store diff-closures is a terribly well designed command to begin with: it is trying to parse some meaning out of store path names (which is at best fragile) in order to determine whether two derivations are the same package. This is the same mistake made by nix-env (that makes nix-env -u unusably broken); though there is not that much that can be done to do better than that besides pulling stuff out of parsing derivations (kind of an even worse layering violation).

I also think that even if we have json output, it is not necessarily going to be valuable, considering what https://github.com/Gabriella439/nix-diff does.

Useful closure diff info, to me, involves representing the DAG/tree nature of the data as to why a package got into there. That structure information ought to be put into the JSON as well.

For your current use case, you might want to consider nix path-info --recursive --size --closure-size --json then unifying the store path names yourself or using nix-diff (at least it's not hard to do just as well as lix which currently uses a regex).

In principle I agree that we should have structured output, but I don't think that nix store diff-closures is a terribly well designed command to begin with: it is trying to parse some meaning out of store path names (which is at best fragile) in order to determine whether two derivations are the same package. This is the same mistake made by nix-env (that makes `nix-env -u` unusably broken); though there is not that much that can be done to do better than that besides pulling stuff out of parsing derivations (kind of an even worse layering violation). I also think that even if we have json output, it is not necessarily going to be valuable, considering what https://github.com/Gabriella439/nix-diff does. Useful closure diff info, to me, involves representing the DAG/tree nature of the data as to *why* a package got into there. That structure information ought to be put into the JSON as well. For your current use case, you might want to consider `nix path-info --recursive --size --closure-size --json` then unifying the store path names yourself or using nix-diff (at least it's not hard to do just as well as lix which currently uses [a regex](https://git.lix.systems/lix-project/lix/src/12a5838d11f790d36e2ac626e8916a2c19bcb80b/src/nix/diff-closures.cc#L31)).
jade added the
Area/cli
label 2024-10-20 00:58:00 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lix-project/lix#532
No description provided.