Skip to content

fix(v2): load settings at first use, not while amber is required - #1424

Draft
crimson-knight wants to merge 4 commits into
v2-devfrom
fix/v2-settings-read-at-require-time
Draft

crimson-knight wants to merge 4 commits into
v2-devfrom
fix/v2-settings-read-at-require-time

Conversation

@crimson-knight

Copy link
Copy Markdown
Member

What changed and why

In 2.0.0-beta.5, require "amber" read Amber.settings and cached it. The read was in the class body of Amber::Pipe::Logger: Colorize.enabled = Amber.settings.logging.colorize. Settings were therefore loaded before an app's config/initializers could call Amber::Configuration.register. A compiled probe in a generated sqlite app showed the result: the registered custom section came back missing, and only a forced reload returned its YAML value. The early read also locked in Amber.path and Amber.env before config/application.cr could set them.

  • No settings read during require. The logger class body no longer touches settings. The logger reads logging.colorize, filter and skip when the pipe is built, which happens in config/routes.cr, after the initializers. I searched the rest of src/amber/** (class bodies, constants, class property defaults, top-level code) and found no other read of Amber.settings or Amber.env that runs at require time. Codex reached the same result.
  • Color without changing global state. Amber no longer sets the process-wide Colorize.enabled flag. The new Amber::Support::LogColor.paint colors Amber's own log lines according to logging.colorize. The logger, server start, error pipe and ClientReload all use it. With colorize: false, Amber's lines are plain, and an app that turns Colorize off (for example with NO_COLOR) gets plain lines everywhere. The EncryptionKeyMissing message is now plain text.
  • Specs.
    • spec/amber/environment/require_time_settings_spec.cr compiles spec/fixtures/require_time_settings/probe_app.cr and runs it from an empty directory. The probe requires amber and amber/testing, then sets AMBER_ENV and Amber.path and registers a custom probe section. One example checks that the section's YAML value (from-yaml) loads. The other checks that the name and environment come from the settings path and environment the probe set after require. Either check fails if any require-time read returns. With the old class-body read restored, both examples fail (MISSING, Amber_App).
    • spec/amber/pipes/logger_spec.cr and spec/amber/support/log_color_spec.cr cover colorize: true and colorize: false, the default taken from settings, and the global flag staying unchanged.
  • CI. The probe builds with CRYSTAL when it is set, and otherwise with crystal-alpha. If neither is available, it raises a clear error. The CI spec step now sets CRYSTAL: crystal, the compiler that runs the suite there.
  • Action pins. This branch includes the SHA pins for actions/checkout and oprypin/install-crystal (cherry-picked 8b8f0a9c from chore(v2): clear the 25 compiler warnings so the build is GREEN #1421) so the branch passes the dependency-pin gate.

Spec result

Codex review (gpt-6-sol, xhigh, two passes)

Pass Severity Finding Resolution
1 BLOCKER none n/a
1 MAJOR Building the logger and starting the server changed the process-wide Colorize.enabled Fixed: LogColor colors per line, and Amber never writes the global flag
1 MINOR The logger spec covered only colorize: true Fixed: the false, true and default cases are covered, plus a check that the global flag is left alone
2 BLOCKER none n/a
2 MAJOR ClientReload and EncryptionKeyMissing still colored their output directly Fixed: ClientReload uses LogColor, and the exception message is plain text
2 MAJOR The probe spec fell back to mainline crystal Fixed: it uses CRYSTAL or crystal-alpha and gives a clear error when neither is found; CI sets CRYSTAL
2 MINOR The logger spec adds /logger_spec to the shared router Accepted: the router has no API for removing a route, existing specs draw into it the same way, and the path is used only by this spec
2 MINOR The nil guard in the Colorize restore was dead code Fixed: the previous value is captured before begin and always restored

Codex found no other require-time read of Amber.settings or Amber.env.

Unblocks

Amber::Pipe::Logger set Colorize.enabled from Amber.settings in its class
body, so requiring amber loaded and cached the settings before an app's
config/initializers could register custom sections or set Amber.path.
The colorize setting now applies when the logger pipe is built and when
the server starts.

A compiled fixture checks that a section registered after require loads
from YAML, and that require leaves Amber.settings and Amber.env unread.
Building the logger pipe or starting the server set the process-wide
Colorize.enabled flag, which could reverse a color choice the app made
itself. Amber::Support::LogColor now colors Amber's own log lines from
the logging.colorize setting, and the logger, server and error pipe use
it. A colorize: false setting keeps Amber's lines plain, and an app that
disables Colorize keeps every line plain.
actions/checkout@v4 and oprypin/install-crystal@v1 were movable refs that their
owners can repoint. Each is now pinned to the commit its ref points to today
(checkout v4.4.0, install-crystal v1.9.4), so CI runs the same code as before.
ClientReload now colors its log lines through LogColor, and the
EncryptionKeyMissing message is plain text, so logging.colorize: false
leaves no ANSI codes in Amber's output. The require-time settings spec
needs CRYSTAL or crystal-alpha to build its fixture; CI sets CRYSTAL to
the compiler that runs the suite.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant