Skip to content

feat(fastfetch): date the updates line and quieten pwsh startup - #654

Merged
DevSecNinja merged 1 commit into
mainfrom
fastfetch-checked-ago-quiet-startup
Jul 30, 2026
Merged

feat(fastfetch): date the updates line and quieten pwsh startup#654
DevSecNinja merged 1 commit into
mainfrom
fastfetch-checked-ago-quiet-startup

Conversation

@DevSecNinja

Copy link
Copy Markdown
Owner

Three papercuts from #645, found after living with it for a day.

1. The Updates line now says how old it is

Updates: 📦 6 update(s) available (winget) · checked 5m ago

Previously "6 updates available" could equally be from a minute or an hour ago.

The Unix script already had machinery for exactly this problem: relative times are stored as absolute epoch tokens and expanded at emit, so they never freeze at whatever they were when the cache was written. This generalises it so a token expands to a bare duration (@ago:5m ago) and the collectors own the wording around it (ran @ago:@, next @in:@, checked @ago:@). Same rendered output as before for the ansible line, and one less token kind to invent next time.

Windows can't expand at emit time — fastfetch reads the cache with cmd /c type. So each section is now stored twice: <name>.src keeps the token, <name> is the rendered copy, and the tokens are expanded on every shell start just before fastfetch runs. A pre-rendered checked 0s ago would otherwise sit there lying for an hour until the next refresh.

Why the render lives in DotfilesHelpers rather than status.ps1: it has to run on every shell start, and dot-sourcing status.ps1 from the profile measured ~60ms (signature block included). The profile already imports the module, so putting it there is free. status.ps1 imports the module after a refresh so a manual status.ps1 refresh also leaves a correctly rendered cache. Side benefit: profile.ps1 gives back the 45-line spawn block it gained in #645.

2/3. A quiet PowerShell startup

Opening a shell printed four lines that fastfetch already covers:

PowerShell 7.6.4
[OK] PowerShell Profile Loaded (1364 ms)
>> Type 'aliases' to see available aliases
Loading personal and system profiles took 1513ms.
  • First and last are printed by pwsh itself, before and after the profile runs — so they're unreachable from profile.ps1. The only lever is the command line the terminal starts, hence a new Set-WindowsTerminalProfileCommandLine + run_onchange script that sets pwsh.exe -NoLogo -NoProfileLoadTime on the PowerShell Core profile. Only that one key is touched, so hand-tuned configs survive. pwsh.exe is left to PATH resolution rather than pinned, so it survives PowerShell upgrades.
  • Middle two are ours, and are now skipped when the fastfetch banner rendered. A light install without fastfetch keeps them, so an interactive shell still confirms the profile loaded — and a timed-out fastfetch also keeps them, since a kill notice is not a banner.

Changes

  • executable_status.sh — generalised token renderer, checked suffix on the updates line
  • status.ps1 — writes updates.src (tokenised) and delegates rendering
  • DotfilesHelpers/Public/FastfetchStatus.ps1 (new) — Update-FastfetchStatusCache, token expansion, duration formatting, detached refresh
  • WindowsTerminal.ps1Set-WindowsTerminalProfileCommandLine
  • run_onchange_set-windows-terminal-powershell-args.ps1.tmpl (new)
  • profile.ps1 — one call instead of the inline block; welcome lines conditional
  • Tests + docs

Testing

  • Bats: 20/20; shellcheck + shfmt clean.
  • Pester: 765 passed, 4 failed — all four are the pre-existing signing-cert tests that also fail on main (baseline: 717/10).
  • PSScriptAnalyzer clean on all changed files.
  • chezmoi apply --dry-run clean; chezmoi managed confirms the new module file and per-OS status scripts ship correctly.

Verified live end to end:

  • fresh refresh renders checked 0s ago; back-dating the source and re-rendering (no refresh) gives checked 1h ago, proving the age tracks the clock rather than the cache.
  • Real shell with fastfetch: no logo, no load-time line, no [OK] Profile Loaded.
  • Real shell with fastfetch removed from PATH: welcome lines still present.
  • Set-WindowsTerminalProfileCommandLine exercised for Updated / AlreadySet / ProfileNotFound / WhatIf against a realistic settings.json.

Note

One commit-time wrinkle worth flagging: the file-set-execution-bit lefthook hook can't launch from Windows (sh: cannot execute: required file not found), so I excluded it for the commit and ran it manually under WSL instead — it passes, and the file is already staged as 100755. Unrelated to this change, but it will bite on any Windows commit that touches a .sh file.

Three papercuts from #645, reported after using it for a day.

The Updates line never said how old its numbers were, so "6 updates
available" could equally be from a minute or an hour ago. Unix already
had a token renderer for exactly this (relative times are stored as
absolute epochs and expanded at emit, so they never freeze in the
cache); generalize it so tokens expand to a bare duration and the
collectors own the wording, then add "checked 5m ago" to the updates
line on both platforms.

Windows cannot expand at emit time -- fastfetch reads the cache with
`cmd /c type` -- so each section is now stored twice: <name>.src keeps
the token and <name> is the rendered copy, re-rendered on every shell
start just before fastfetch runs. That render lives in DotfilesHelpers
because the profile already imports it, where dot-sourcing status.ps1
would add ~60ms to profile load. profile.ps1 loses 45 lines as a result.

Opening a shell also printed four lines that fastfetch already covers:

  PowerShell 7.6.4
  [OK] PowerShell Profile Loaded (1364 ms)
  >> Type 'aliases' to see available aliases
  Loading personal and system profiles took 1513ms.

The first and last are printed by pwsh itself around profile load, so
they cannot be suppressed from profile.ps1; add
Set-WindowsTerminalProfileCommandLine and a run_onchange script that
launches the Windows Terminal profile as
`pwsh.exe -NoLogo -NoProfileLoadTime`. The middle two are ours and are
now skipped when the fastfetch banner rendered -- a light install
without fastfetch keeps them, so an interactive shell still confirms
the profile loaded.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6ff40b19-afbf-48c8-9b80-233b13652222
@DevSecNinja
DevSecNinja merged commit 72d30ce into main Jul 30, 2026
19 checks passed
@DevSecNinja
DevSecNinja deleted the fastfetch-checked-ago-quiet-startup branch July 30, 2026 16:34
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