Skip to content

Add json output to uv tool list#20516

Open
ThiefMaster wants to merge 6 commits into
astral-sh:mainfrom
ThiefMaster:tool-list-json
Open

Add json output to uv tool list#20516
ThiefMaster wants to merge 6 commits into
astral-sh:mainfrom
ThiefMaster:tool-list-json

Conversation

@ThiefMaster

@ThiefMaster ThiefMaster commented Jul 18, 2026

Copy link
Copy Markdown

No tests etc yet until the JSON format etc is fine. Added tests after it turned out to be trivial, snapshot tests FTW! :)

Sample output:

without --outdated:

Details
{
  "schema": {
    "version": "preview"
  },
  "tools": [
    {
      "name": "httpie",
      "version": "3.2.3",
      "latest_version": null,
      "path": "/home/adrian/.local/share/uv/tools/httpie",
      "commands": [
        {
          "name": "http",
          "path": "/home/adrian/.local/bin/http"
        },
        {
          "name": "httpie",
          "path": "/home/adrian/.local/bin/httpie"
        },
        {
          "name": "https",
          "path": "/home/adrian/.local/bin/https"
        }
      ],
      "extras": [],
      "version_specifiers": "",
      "with": [],
      "python": {
        "implementation": "cpython",
        "version": "3.12.2",
        "key": "cpython-3.12.2-linux-x86_64-gnu"
      }
    },
    {
      "name": "twine",
      "version": "6.2.0",
      "latest_version": null,
      "path": "/home/adrian/.local/share/uv/tools/twine",
      "commands": [
        {
          "name": "twine",
          "path": "/home/adrian/.local/bin/twine"
        }
      ],
      "extras": [
        "keyring"
      ],
      "version_specifiers": ">=6.2.0, !=69",
      "with": [
        "markupsafe!=69",
        "werkzeug"
      ],
      "python": {
        "implementation": "cpython",
        "version": "3.13.3",
        "key": "cpython-3.13.3-linux-x86_64-gnu"
      }
    },
  ]
}

with --outdated:

Details
{
  "schema": {
    "version": "preview"
  },
  "tools": [
    {
      "name": "httpie",
      "version": "3.2.3",
      "latest_version": "3.2.4",
      "path": "/home/adrian/.local/share/uv/tools/httpie",
      "commands": [
        {
          "name": "http",
          "path": "/home/adrian/.local/bin/http"
        },
        {
          "name": "httpie",
          "path": "/home/adrian/.local/bin/httpie"
        },
        {
          "name": "https",
          "path": "/home/adrian/.local/bin/https"
        }
      ],
      "extras": [],
      "version_specifiers": "",
      "with": [],
      "python": {
        "implementation": "cpython",
        "version": "3.12.2",
        "key": "cpython-3.13.2-linux-x86_64-gnu"
      }
    }
  ]
}

closes #10219

path: PathBuf,
commands: Vec<CommandPrintData>,
extras: Vec<String>,
version_specifiers: String,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Should this be an Option that's None when there aren't any version specifiers to get null instead of an empty string in the JSON data?

Comment on lines +307 to +309
// XXX I don't think we'll ever have more than 1 element here, since multiple
// specifiers like in 'twine[keyring]>=6.2.0,!=69' are all in the same string
.join(", "),

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I kept this because it's used in the existing text output code. I could not find any case where we'd get multiple items here, because we only have one requirement as input here, and source.to_string already produces a single string.

}

#[derive(Debug, Serialize)]
struct PythonPrintData {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I limited this to useful data like in the text output but included the key to allow matching it with data from uv python list

@ThiefMaster
ThiefMaster marked this pull request as ready for review July 19, 2026 10:54
@codspeed-hq

codspeed-hq Bot commented Jul 19, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 5.03%

⚡ 1 improved benchmark
✅ 20 untouched benchmarks
⏩ 6 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime resolve_warm_jupyter 18.1 ms 17.3 ms +5.03%

Tip

Curious why this is faster? Use the CodSpeed MCP and ask your agent.


Comparing ThiefMaster:tool-list-json (2b9efca) with main (336535f)

Open in CodSpeed

Footnotes

  1. 6 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

"name": "flask",
"version": "3.0.2",
"latest_version": null,
"path": "[TEMP_DIR]/tools/flask",

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This fails on windows, not sure where this slash nonsense is coming from, so no idea how to fix it (besides not running these tests on windows which is probably not a good idea)...

       13       │-      "path": "[TEMP_DIR]/tools/flask",
             13 │+      "path": "D:\/uv-tmp\/uv\/tests\/[TMP]/flask",

"python": {
"implementation": "cpython",
"version": "3.12.[X]",
"key": "cpython-3.12.[X]-linux-x86_64-gnu"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Of course this also fails on Windows, because it has -windows- instead of -linux- in the key...

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Option to output uv tool list into JSON format

2 participants