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.
This commit is contained in:
Laurence Horrocks-Barlow 2026-05-21 10:33:10 +01:00
parent 0c06a1483c
commit 74b210a702
7 changed files with 718 additions and 0 deletions

135
docs/organise-isos.md Normal file
View file

@ -0,0 +1,135 @@
# `organise-isos.ps1`
Parses ISO filenames, infers `os`, `version`, and `arch`, and moves each file
into `<DestDir>\<os>\<version>\<arch>\`. Pure filename parsing — the ISO
itself is never opened.
## Parameters
| Parameter | Default | Description |
| --- | --- | --- |
| `-SourceDir` | `.` | Directory to scan for `*.iso` files (non-recursive). |
| `-DestDir` | `.\iso-library` | Target root. Subdirectories are created as needed. |
| `-DryRun` | `false` | Print the moves it would make; touch nothing. |
## What it does
1. Enumerates `*.iso` directly under `-SourceDir` (does not recurse).
2. For each file, calls `Get-IsoMeta` to derive `os`, `version`, `arch`.
3. Creates `<DestDir>\<os>\<version>\<arch>\` if missing.
4. Moves the ISO in.
5. Prints a table of the results.
## Parsing rules
### Architecture
Checked in priority order against the **raw** filename. First match wins:
| Pattern | Canonical |
| --- | --- |
| `aarch64`, `arm64` | `aarch64` |
| `arm` (not followed by `64`) | `arm` |
| `x86[_-]64`, `amd64`, `_x64`, `64bit` | `x86_64` |
| `x86` (not followed by `_64`), `i[3-6]86`, `32bit` | `x86` |
| `riscv64`, `riscv32` | `riscv64` / `riscv32` |
| `ppc64le`, `ppc64`, `ppc` | matching |
| `s390x`, `mips64`, `mips`, `loong64`, `ia64`, `sparc64`, `alpha` | matching |
If nothing matches, arch is `noarch`.
### Edition noise stripping
Tokens like `live`, `server`, `desktop`, `dvd`, `netinstall`, `workstation`,
`kde`, `gnome`, `xfce`, language codes (`en_us`, `en_gb`, `international`),
release tags (`lts`, `beta`, `rc1`, `sp2`, `u3`), and similar are stripped
**after** the arch check so they don't pollute the OS-name match. See the
`$noisePattern` regex in the script for the full list.
### OS detection
The cleaned filename is split on `-_.` and the first token (lowercased) is
matched against `$osNormMap`. First regex match wins. If no first-token match
hits, the first **two** tokens joined with `-` are tried (catches `linux-mint`,
`pop-os`, `ms-dos`).
If still no match, the first token is sanitised (`[^a-z0-9-]` removed) and
used as-is, producing a slug like `myweirdspin`.
The map covers Windows, RHEL family, Fedora family, SUSE, Debian/Ubuntu and
derivatives, Arch family, Gentoo family, Slackware, independent Linux (Void,
NixOS, Alpine, etc.), hypervisors (Proxmox, ESXi, XCP-ng), BSD family,
Solaris/illumos, exotic OSes (Haiku, FreeDOS, ReactOS, Plan9), and rescue
tools (Clonezilla, SystemRescue, GParted, Memtest, Hiren's, DBAN, vendor
rescue disks). Full list is in `$osNormMap` in
[`organise-isos.ps1`](../organise-isos.ps1).
### Version detection
Checked in this order, first match wins:
1. **Windows H-series**`25H2`, `24H2`, etc. on the raw filename.
2. **Full date stamp**`YYYYMMDD` → year only (so `20240315``2024`).
3. **Semver / partial semver**`\d+\.\d+(\.\d+)?` on the cleaned name.
Three-part versions are truncated to `major.minor` (so `9.3.1``9.3`).
4. **Bare integer** — final fallback, captures things like `debian-12-...`.
If nothing matches, version is `unknown`.
## Examples
| Input filename | OS | Version | Arch |
| --- | --- | --- | --- |
| `ubuntu-24.04.1-desktop-amd64.iso` | `ubuntu` | `24.04` | `x86_64` |
| `Win11_24H2_English_x64.iso` | `windows` | `24H2` | `x86_64` |
| `debian-12.5.0-amd64-netinst.iso` | `debian` | `12.5` | `x86_64` |
| `Rocky-9.3-aarch64-minimal.iso` | `rocky` | `9.3` | `aarch64` |
| `archlinux-2024.03.01-x86_64.iso` | `arch` | `2024.03` | `x86_64` |
| `clonezilla-live-3.1.2-22-amd64.iso` | `clonezilla` | `3.1` | `x86_64` |
| `proxmox-ve_8.2-1.iso` | `proxmox-ve` | `8.2` | `noarch` |
| `systemrescue-11.00-amd64.iso` | `systemrescue` | `11` | `x86_64` |
## Adding support for a new OS
Edit [`organise-isos.ps1`](../organise-isos.ps1):
```powershell
$osNormMap = [ordered]@{
# ...existing entries...
'^mycoolos|^my.cool.os' = 'mycoolos'
}
```
Then add a display name and category in
[`generate-ventoy-json.ps1`](../generate-ventoy-json.ps1):
```powershell
$displayNames = @{
'mycoolos' = 'My Cool OS'
}
$categoryMap = [ordered]@{
'mycoolos' = 'Independent Linux' # or any existing/new category
}
```
The `$osNormMap` is **ordered** — earlier patterns win, so put more specific
patterns above more general ones (e.g. `^centos.stream` must come before
`^centos`).
## Exit codes
- `0` — success (including dry-run).
- `1` — no ISO files found in `-SourceDir`.
## Idempotency and re-runs
Safe to re-run. The first time moves all ISOs out of `-SourceDir`; subsequent
runs find nothing to move (because the source directory is empty) and exit
with code 1. If you want to add ISOs later, drop them into the same source
directory and run again.
The script does **not** detect duplicates. If you move the same ISO twice
from different sources and they parse to the same target slot, the second
move fails with a `Move-Item` error — by design, since silently
overwriting an ISO would be a footgun.