From a5b0d0f31943bc95b20db0a9da17a7bca6094921 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 19 Jun 2026 14:13:53 +0000 Subject: [PATCH 1/4] Preserve script order in generated README (#1991) `devbox generate readme` listed scripts in alphabetical order instead of the order they are defined in devbox.json. This happened because scripts are stored in a map and the README template ranged over it directly; Go's text/template (like map iteration generally) visits keys in sorted order, so user-defined ordering was lost. Add order-preserving APIs driven by the existing hujson AST: - configAST.objectKeysInOrder walks to an object and returns its member names in source order. - ConfigFile.ScriptOrder / Config.ScriptOrder expose the script names in the order they appear (included plugins first, then the root config, matching Scripts' merge precedence). - Scripts.InOrder turns the script map into an ordered []ScriptWithName, appending any scripts not covered by the order slice alphabetically so output stays deterministic. docgen now renders scripts via this ordered slice, and the README template ranges over it. Adds unit tests covering source-order preservation, the alphabetical fallback, and de-duplication of unknown scripts. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_012kMnjYNx5Y5YzyqLPzeroQ --- internal/devbox/docgen/docgen.go | 18 ++-- internal/devbox/docgen/readme.tmpl | 10 +-- internal/devconfig/config.go | 13 +++ internal/devconfig/configfile/ast.go | 28 ++++++ internal/devconfig/configfile/scripts.go | 60 +++++++++++++ internal/devconfig/configfile/scripts_test.go | 90 +++++++++++++++++++ 6 files changed, 207 insertions(+), 12 deletions(-) create mode 100644 internal/devconfig/configfile/scripts_test.go diff --git a/internal/devbox/docgen/docgen.go b/internal/devbox/docgen/docgen.go index 957a22f7821..9408a37e8b1 100644 --- a/internal/devbox/docgen/docgen.go +++ b/internal/devbox/docgen/docgen.go @@ -50,14 +50,18 @@ func GenerateReadme( return err } + cfg := devbox.Config() + scripts := cfg.Scripts(). + WithRelativePaths(devbox.ProjectDir()). + InOrder(cfg.ScriptOrder()) + return tmpl.Execute(f, map[string]any{ - "Name": devbox.Config().Root.Name, - "Description": devbox.Config().Root.Description, - "Scripts": devbox.Config().Scripts(). - WithRelativePaths(devbox.ProjectDir()), - "EnvVars": devbox.Config().Env(), - "InitHook": devbox.Config().InitHook(), - "Packages": devbox.TopLevelPackages(), + "Name": cfg.Root.Name, + "Description": cfg.Root.Description, + "Scripts": scripts, + "EnvVars": cfg.Env(), + "InitHook": cfg.InitHook(), + "Packages": devbox.TopLevelPackages(), // TODO add includes }) } diff --git a/internal/devbox/docgen/readme.tmpl b/internal/devbox/docgen/readme.tmpl index ad3306f58cd..61f1a86457c 100644 --- a/internal/devbox/docgen/readme.tmpl +++ b/internal/devbox/docgen/readme.tmpl @@ -28,8 +28,8 @@ devbox run