The package lists were stored as config_<version>/packages_<device>_<version>.txt,
but the version dimension was pure duplication: the Linksys MX8500 extras were
byte-identical across 24.10.4, 25.12.0, 25.12.2 and 25.12.4, and the Cudy lists
only ever changed with the device, never with the release.
Your packages now live in packages/<device-id>.txt, one file per device and
independent of the OpenWrt version. The built-in part is fetched per release
anyway, so upgrading needs no file changes at all.
The combined list is a build artefact and moves to .generated/, which is
gitignored, along with the buildinfo saved by --save-buildinfo --offline.
This removes work rather than adding it: because the generated file is now
entirely machine-owned, the sentinel comments, the in-section replacement state
machine and the "line containing base-files and libc is the old generated one"
migration heuristic are all gone. Hand-written content is isolated in the extras
file, generated content in .generated/.
Also fix version detection when a script is run from the helper directory. The
helper checkout is its own git repository inside the OpenWrt worktree, so git
commands there described the helper repo -- a checkout of OpenWrt 25.12.5 was
reported as SNAPSHOT because the helper repo is on main. Version queries are now
anchored to the OpenWrt tree.
The config_* archives are deleted; git history keeps them. That includes
config_24.10.4/apply-dahdi-patches.sh, which only applied to 24.10.4.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The ##built-in section of each package list was copied by hand from the
Firmware Selector for every new release. It is now generated from the
target's profiles.json (default_packages + device_packages, plus the two
packages the Selector adds on top), which reproduces the hand-written list
byte for byte, order included.
New lib-openwrt-upstream.sh holds the shared upstream access: URL
construction, cached fetches, version detection, device search over
.overview.json and profiles.json parsing. It needs python3, not jq.
New gen-package-list.sh writes config_<ver>/packages_<dev>_<ver>.txt,
replacing only the generated block so hand-written extras and the ##module
section survive; --stdout and --apply skip the file entirely.
download-config.sh:
- Look the device up in the official index instead of a hardcoded table of
three devices, so any supported device can be selected by name.
- Build the firmware URLs from profiles.json images[]. The old code pasted
the target into the filename with its '/' intact, so the URL was always
wrong and the check always warned.
- Stage the download in a temp file and validate it before touching
.config, and keep a backup. A 404 used to truncate .config to nothing.
- Fix version detection: `git describe --tags --abbrev=0` returns a tag
whenever any tag is reachable, so the entire fallback chain below it was
unreachable and a branch tip silently produced the wrong release URL.
- Build only the selected device instead of all 35 in the target, and turn
off the buildbot flags (ALL_KMODS, ALL_NONSHARED, SDK, IB,
MAKE_TOOLCHAIN, COLLECT_KERNEL_DEBUG, AUTOREMOVE). Verified not to change
the firmware: the set of packages built into the image is identical
either way (193 packages), while the module packages to build drop from
1248 to 0. --keep-buildbot-flags and --all-profiles restore the old
behaviour.
- Assert the device symbol survived make defconfig, so a tree that does not
match the release fails loudly instead of silently building the default.
add-openwrt-packages.sh:
- Rewrite existing CONFIG_PACKAGE_ lines in place. Repeated runs used to
append duplicates and grow .config every time.
- Support removal via a -pkg prefix or a ##remove section.
- Fix the parser dropping a lone '#' or an unknown ##header into the
package list, where it was reported as a missing package named '#'.
- Read .config once into a map instead of grepping it per package, and
compare package names exactly rather than as regexes.
- After make defconfig, report any package whose final state differs from
what was asked for, which is the only way to see a removal that a
dependency pulled back in.
Delete add-openwrt-packages_old.sh; nothing referenced it and it was a
strict subset of the current script.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every path in the script is relative to the current directory, so running
it from anywhere else cloned the packages into that directory instead.
Now that the helper checkout lives at openwrt/helper/, running it there
would populate helper/package/ rather than the real package/.
Use the same guard the other helper scripts already have.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
prepare-openwrt-env.sh
- Dispatch on the package manager instead of guessing from the distro
version: apt, dnf/yum, pacman, zypper and apk are all supported.
- Probe every package against the running release and skip the ones that
no longer exist. Previously a single dropped package (on Ubuntu 26.04
arm64, gcc-multilib-s390x-linux-gnu) failed the whole apt command and
set -e aborted the script, so nothing was installed at all.
- Align the package lists with the official build system guide, adding
libelf-dev, python3-dev, bc, xsltproc, zstd, u-boot-tools and others.
- Make Go opt-in via --with-go rather than forced on arm64.
- Add -y/--yes, -n/--dry-run and -h/--help; allow running as root.
prepare-openwrt.sh
- Split read-only discovery from mutation. Versions are resolved over
git ls-remote before anything is moved, so aborting at the prompt
leaves the helper checkout untouched.
- Resume an interrupted first run instead of failing forever: a root
with .git but no source tree was previously unrecoverable without a
manual rm -rf. Also restore the worktree when HEAD already points at
the target ref, where checkout is a no-op.
- Detect the relocated layout by content rather than directory name, so
renaming the root no longer triggers a second, nested relocation.
- Replace the staged in-place relocation with a resumable content move,
removing the window that could strand the checkout in a hidden dir.
- Filter release candidates before sorting; sort -V orders v25.12.0-rc1
after v25.12.0, so the newest stable tag could be an rc.
- Follow upstream: snapshots use main (master as fallback) and the dead
-SNAPSHOT tag lookup is gone.
- Use a partial clone (--filter=blob:none) by default.
- Guard version switches on a dirty tree and back up .config first.
- Add /helper/ to .git/info/exclude and warn that git clean -xdff still
deletes it, since -x bypasses ignore rules by design.
- Leave a symlink at the old checkout path so shells and editors whose
working directory still points there keep working.
- Add --stable/--branch/--snapshot plus -y, -n, --force, --full-clone,
--allow-rc, --root, --skip-feeds, --skip-defconfig, --repo-url and
--no-compat-link.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>