ventoy-extras/docs/generate-ventoy-json.md
Laurence Horrocks-Barlow 74b210a702 Add README, runbook, per-script docs, CHANGELOG and LICENSE.
Documents the organise-isos and generate-ventoy-json workflow end-to-end:
quick start in the README, full procedure with troubleshooting and recovery
in docs/RUNBOOK.md, and reference docs for each script covering parameters,
parsing rules, category groupings, and extensibility. Ships a YOLO licence
(no warranty) and seeds CHANGELOG.md for the v0.1.0 release.
2026-05-21 10:33:10 +01:00

146 lines
4.9 KiB
Markdown

# `generate-ventoy-json.ps1`
Walks an `iso-library` directory tree and emits a `ventoy.json` with
per-category submenus. Output is UTF-8, no BOM, ready to drop into
`\ventoy\ventoy.json` on the Ventoy USB.
## Parameters
| Parameter | Default | Description |
| --- | --- | --- |
| `-IsoRoot` | `.\iso-library` | Root of the ISO tree to scan (recursively, for `*.iso`). |
| `-OutFile` | `.\ventoy.json` | Where to write the generated JSON. |
| `-VentoyDrive` | `E` | Cosmetic — currently unused at runtime; kept for forward compat. |
## Expected input tree
```
<IsoRoot>\
<os-slug>\
<version>\
<arch>\
*.iso
```
This is exactly what [`organise-isos.ps1`](organise-isos.md) produces.
Files that don't fit this layout still get included, but with a best-effort
fallback:
- 3 path segments deep → arch defaults to `noarch`.
- < 3 segments `os` and `version` both default to `unknown`.
## Output structure
Each top-level entry in `ventoy.json` is a category submenu, containing one
entry per ISO:
```json
{
"menu_alias": [
{
"name": "Ubuntu Family",
"image": [
{ "image": "/ubuntu/24.04/x86_64/ubuntu-24.04.1-desktop-amd64.iso",
"menu_alias": "Ubuntu 24.04 [x86_64]" },
{ "image": "/lubuntu/24.04/x86_64/lubuntu-24.04-desktop-amd64.iso",
"menu_alias": "Lubuntu 24.04 [x86_64]" }
]
},
{
"name": "Rescue & Tools",
"image": [
{ "image": "/clonezilla/3.1/x86_64/clonezilla-live-3.1.2-22-amd64.iso",
"menu_alias": "Clonezilla 3.1 [x86_64]" }
]
}
]
}
```
## Menu labels
For each ISO, the label is built as:
```
<display name> <version>[ [<arch>]]
```
Where:
- `<display name>` is looked up in `$displayNames` (e.g. `ubuntu` `Ubuntu`,
`proxmox-ve` `Proxmox VE`). Unmapped slugs are title-cased as a fallback.
- The arch suffix `[<arch>]` is omitted when arch is `noarch`.
Examples: `Ubuntu 24.04 [x86_64]`, `Proxmox VE 8.2`, `Memtest86+ 6.20 [x86_64]`.
## Category groupings
Slugs are mapped to category names via `$categoryMap`:
| Category | Slugs included |
| --- | --- |
| Windows | `windows`, `windows-server`, `ms-dos`, `reactos` |
| RHEL Family | `rhel`, `centos`, `rocky`, `almalinux`, `oraclelinux`, `scientific`, `eurolinux`, `navylinux` |
| Fedora Family | `fedora`, `qubes`, `coreos` |
| SUSE Family | `opensuse*`, `sles`, `geckolinux` |
| Debian Family | `debian`, `raspios`, `armbian`, `devuan`, `mx`, `antix`, `deepin`, `pureos`, `grml`, `lmde` |
| Ubuntu Family | `ubuntu*`, `lubuntu`, `kubuntu`, `xubuntu`, `linuxmint`, `pop_os`, `elementary`, `zorin` |
| Arch Family | `arch`, `manjaro`, `endeavouros`, `garuda`, `artix`, `cachyos`, `arcolinux` |
| Gentoo Family | `gentoo`, `funtoo`, `calculate` |
| Slackware Family | `slackware`, `salix`, `porteus` |
| Independent Linux | `void`, `nixos`, `alpine`, `solus`, `clearlinux`, `flatcar` |
| Security | `kali`, `parrot`, `backbox`, `tails`, `whonix`, `blackarch` |
| Network & Firewall | `pfsense`, `opnsense`, `ipfire`, `vyos`, `openwrt`, `ddwrt` |
| Virtualisation | `proxmox-*`, `esxi`, `vsphere`, `xcp-ng`, `xenserver`, `harvester` |
| BSD Family | `freebsd`, `openbsd`, `netbsd`, `dragonflybsd`, `truenas*`, `ghostbsd` |
| Solaris & illumos | `openindiana`, `omnios`, `smartos`, `solaris` |
| Media | `libreelec`, `osmc` |
| Exotic | `haiku`, `freedos`, `reactos` |
| Rescue & Tools | `clonezilla`, `systemrescue`, `gparted`, `memtest`, `memtest86`, `rescuezilla`, `hirens`, `winpe`, `dban`, `ubcd`, vendor rescue disks |
| Other | anything unmapped sorted alphabetically at the end |
Matching is exact-first, then prefix. So `opensuse-leap` matches the exact
`opensuse-leap` entry if present, otherwise falls through to the `opensuse`
prefix.
Category order in the output menu is fixed (see `$categoryOrder` in the
script). Unlisted categories including any new ones you add append
alphabetically after the predefined order.
## Adding a category
Edit [`generate-ventoy-json.ps1`](../generate-ventoy-json.ps1):
```powershell
$categoryMap = [ordered]@{
# ...existing...
'mycoolos' = 'Hobbyist OSes' # new category name appears as-is in the menu
}
# Optional — place it explicitly in the menu order:
$categoryOrder = @(
'Windows',
# ...
'Hobbyist OSes',
# ...
)
```
## Output details
- **Encoding**: UTF-8 without BOM. Ventoy accepts this.
- **Indentation**: `ConvertTo-Json -Depth 10` default formatting.
- **Path separators**: forward slashes, leading `/`. Ventoy paths are
rooted at the Ventoy data partition root, not at filesystem root.
## Exit codes
- `0` always. The script prints to stderr but does not exit non-zero
on parsing edge cases; "unknown" categories are silently bucketed into
`Other`.
## Idempotency
Pure function of the directory tree. Re-running over the same tree always
produces byte-identical output (modulo line endings if you edited the
script). Safe to run on every Ventoy refresh.