ganzua inspect
Usage: ganzua inspect [OPTIONS] [LOCKFILE]
Inspect a lockfile.
The LOCKFILE argument can be any of the following:
- file: use that path as the lockfile (e.g.
uv.lockorpoetry.lock) - directory: look for a lockfile in that directory
- gitrevision: a
<commit>:<path>identifying a lockfile in the Git history
If this argument is not specified, the one in the current working directory will be used.
Options:
--filter LOCKFILE-FILTERInclude/exclude packages to inspect. [default: show all]--format [json|markdown]Choose the output format, e.g. Markdown. [default: json]--[no-]gitWhether to interpret lockfile paths as gitrevisions. [default: enabled]--git-executable EXECUTABLEHow to invoke Git. [default: git]--helpShow this help message and exit.
Changed in Ganzua NEXT: renamed --name to --filter.
Examples
We can load various example lockfiles:
$ ganzua inspect corpus/old-uv-project
{
"packages": [
{
"name": "example",
"version": "0.1.0",
"source": {
"direct": "."
}
},
{
"name": "typing-extensions",
"version": "3.10.0.2",
"source": "pypi"
}
]
}
$ ganzua inspect corpus/new-uv-project
{
"packages": [
{
"name": "annotated-types",
"version": "0.7.0",
"source": "pypi"
},
{
"name": "example",
"version": "0.1.0",
"source": {
"direct": "."
}
},
{
"name": "typing-extensions",
"version": "4.14.1",
"source": "pypi"
}
]
}
$ ganzua inspect corpus/old-poetry-project
{
"packages": [
{
"name": "typing-extensions",
"version": "3.10.0.2",
"source": "default"
}
]
}
$ ganzua inspect corpus/new-poetry-project
{
"packages": [
{
"name": "annotated-types",
"version": "0.7.0",
"source": "default"
},
{
"name": "typing-extensions",
"version": "4.14.1",
"source": "default"
}
]
}
$ ganzua inspect corpus/new-uv-project/pylock.exported.toml
{
"packages": [
{
"name": "annotated-types",
"version": "0.7.0",
"source": "pypi"
},
{
"name": "typing-extensions",
"version": "4.14.1",
"source": "pypi"
}
]
}
Instead of producing JSON output, we can summarize lockfiles as Markdown:
$ ganzua inspect corpus/old-uv-project --format=markdown
| package | version |
|-------------------|----------|
| example | 0.1.0 |
| typing-extensions | 3.10.0.2 |
The input paths may point to directories or lockfiles. The following invocations are all equivalent:
$ ganzua inspect corpus/new-uv-project$ ganzua inspect corpus/new-uv-project/uv.lock
output for the above commands
{
"packages": [
{
"name": "annotated-types",
"version": "0.7.0",
"source": "pypi"
},
{
"name": "example",
"version": "0.1.0",
"source": {
"direct": "."
}
},
{
"name": "typing-extensions",
"version": "4.14.1",
"source": "pypi"
}
]
}
It is possible for a locked package to have no version
(see issue #4).
In this case, Ganzua will use the pseudo-version 0+undefined:
$ ganzua inspect corpus/setuptools-dynamic-version
{
"packages": [
{
"name": "setuptools-dynamic-version",
"version": "0+undefined",
"source": {
"direct": "."
}
}
]
}
Split versions
It is possible for a project to have multiple conflicting requirements, e.g. for different Python versions, extras, or groups:
$ cat $CORPUS/split/pyproject.toml
[project]
name = "split"
version = "0.1.0"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"typing_extensions >=4 ; python_version >= '3.14'",
"typing_extensions >=3,<4 ; python_version < '3.14'",
]
When inspecting the lockfile, Ganzua will show all candidates:
$ ganzua inspect $CORPUS/split/uv.lock
{
"packages": [
{
"name": "split",
"version": "0.1.0",
"source": {
"direct": "."
}
},
{
"name": "typing-extensions",
"version": "3.10.0.2",
"source": "pypi"
},
{
"name": "typing-extensions",
"version": "4.15.0",
"source": "pypi"
}
]
}
$ ganzua inspect $CORPUS/split/poetry.lock
{
"packages": [
{
"name": "typing-extensions",
"version": "3.10.0.2",
"source": "default"
},
{
"name": "typing-extensions",
"version": "4.15.0",
"source": "default"
}
]
}
Split version support was added in Ganzua 0.4.0. For background on this, see the issue ganzua#5.
Filtering
Normally, inspecting a lockfile will show all results:
$ ganzua inspect $EXAMPLE --format=markdown
| package | version |
|-------------------|---------|
| annotated-types | 0.7.0 |
| example | 0.1.0 |
| typing-extensions | 4.14.1 |
However, we can use a --filter to only look at a specific package:
$ ganzua inspect $EXAMPLE --filter=annotated-types --format=markdown
| package | version |
|-----------------|---------|
| annotated-types | 0.7.0 |
Can also use glob patterns to select matching packages:
$ ganzua inspect $EXAMPLE --filter='*ex*' --format=markdown
| package | version |
|-------------------|---------|
| example | 0.1.0 |
| typing-extensions | 4.14.1 |
For further details on filters, see the filter manual.
Filtering was added in Ganzua 0.4.0.
Unstable: there's a hidden --md-links option.
$ ganzua inspect $EXAMPLE --format=markdown --md-links
| package | version |
|-----------------------------------------------------------|---------|
| [annotated-types](https://pypi.org/p/annotated-types) | 0.7.0 |
| example | 0.1.0 |
| [typing-extensions](https://pypi.org/p/typing-extensions) | 4.14.1 |
JSON Schema
Download: schema.inspect.json
Properties:
-
packages: array(LockedPackage)
All packages in the lockfile.In case of split versions, there can be multiple entries with the same package name.
Changed in Ganzua 0.4.0:
packagesis now a list. Previously, it was aname → LockedPackagetable.
type LockedPackage
Properties:
-
name: string
Name of the package.Added in Ganzua 0.4.0: previously, the package name was implicit.
-
version: string -
source:pypi|default|other| SourceRegistry | SourceDirect
type SourceRegistry
The package is sourced from a third party registry.
Properties:
registry: string
URL or path to the registry.
type SourceDirect
The package is sourced from a specific URL or path, e.g. a Git repo or workspace path.
Properties:
direct: string
URL or path to the package (directory or archive).subdirectory?: string | null
Only allowed if the source points to an archive file.