Skip to content

refactor(makefile): extract host detection into a script - #2107

Closed
shunkakinoki wants to merge 1 commit into
mainfrom
claude/extract-host-detection
Closed

refactor(makefile): extract host detection into a script#2107
shunkakinoki wants to merge 1 commit into
mainfrom
claude/extract-host-detection

Conversation

@shunkakinoki

@shunkakinoki shunkakinoki commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Follow-up to #2105.

Detection moves to a script

Machine detection was a 27-line $(shell ...) blob inline in the Makefile. It was testable only indirectly, by driving make build with a mocked nix and grepping the resulting command log.

It now lives in scripts/detect-host.sh, matching the existing scripts/*.sh + spec/*_spec.sh convention. It reads OS, ARCH, DMI_SYS_VENDOR, DMI_PRODUCT_NAME and RUNPOD_POD_ID from the environment, so spec/detect_host_spec.sh can exercise detection directly instead of through a build. That spec covers the Framework 13 DMI match, the RunPod override, a non-matching Framework model, matching product data from another vendor, and the various no-host cases.

make detect-host prints what the current machine maps to:

$ make detect-host
Detected host: galactica
Resolved host: galactica

$ make detect-host HOST=viper
Detected host: galactica
Resolved host: viper (from HOST=viper)

Note on shape: detection can't be a make target that the Makefile itself invokes — DETECTED_HOST := $(shell $(MAKE) ...) would re-enter the Makefile during parsing and recurse. So the script is what does the work, and detect-host is a thin target over it.

Resolution collapses onto one variable

The HOST -> DETECTED_HOST -> fallback chain was repeated 11 times across nix-build and nix-switch, once per (CI x non-CI) x (Darwin, nixos, home). That duplication is exactly what caused #2105: #2100 updated the non-CI copies and missed the CI ones.

All 11 now read a single RESOLVED_HOST := $(or $(HOST),$(DETECTED_HOST)), which halves the branch count and makes it structurally impossible to update one arm without the other. This is in the same commit because it rewrites the same block.

One behavior note: the Darwin branches previously ran the NIXOS_NAMED_HOSTS check only for an explicit HOST, and always built darwinConfigurations for a detected host. Now both go through the case. This is equivalent, because the Darwin detection path only ever yields galactica, which is not in NIXOS_NAMED_HOSTS and so falls to the same default branch.

Deliberately not changed

The guard-style checks ([ "$(DETECTED_HOST)" = x ] || [ "$(HOST)" = x ]) and the build-vm / run-vm / build-iso targets still use DETECTED_HOST directly. Switching those to RESOLVED_HOST would change their semantics — e.g. make ... HOST=viper on the galactica machine currently satisfies a galactica guard, and would stop doing so. That is arguably more correct, but it is a real behavior change and doesn't belong in a refactor.

Verification

  • shellspec full suite: 1645 examples, 0 failures
  • CI=true shellspec full suite: 1645 examples, 0 failures
  • make shell-check (repo shellcheck): clean
  • make detect-host on this machine still resolves galactica, matching pre-refactor behavior

Summary by cubic

Extracted host detection from the Makefile into scripts/detect-host.sh and unified host selection via RESOLVED_HOST. This removes duplicated logic in nix-build/nix-switch, makes detection testable, and keeps behavior the same.

  • Refactors

    • Replaced the Makefile $(shell ...) blob with scripts/detect-host.sh reading OS, ARCH, DMI_SYS_VENDOR, DMI_PRODUCT_NAME, RUNPOD_POD_ID.
    • Collapsed HOST/DETECTED_HOST into RESOLVED_HOST := $(or $(HOST),$(DETECTED_HOST)) used across CI and non-CI paths.
    • Darwin paths now use RESOLVED_HOST; behavior unchanged since detection only yields galactica (not in NIXOS_NAMED_HOSTS).
    • Kept guard checks and build-vm/run-vm/build-iso on DETECTED_HOST to avoid behavior changes.
  • New Features

    • Added make detect-host to print detected and resolved host.
    • Added spec/detect_host_spec.sh covering Framework 13, RunPod override, kyber/matic, and no-host cases.

Written for commit 65043cc. Summary will update on new commits.

Review in cubic

Machine detection was a 27-line $(shell ...) blob inline in the Makefile,
testable only indirectly by driving 'make build' with a mocked nix and
grepping the resulting command log.

Move it to scripts/detect-host.sh, which reads OS, ARCH, DMI_SYS_VENDOR,
DMI_PRODUCT_NAME and RUNPOD_POD_ID from the environment so spec/detect_host_spec.sh
can exercise detection directly. Add 'make detect-host' to show what the
current machine maps to.

Also collapse the HOST -> DETECTED_HOST -> fallback chain, which was repeated
11 times across nix-build and nix-switch, onto a single RESOLVED_HOST variable.
That duplication is what caused #2105: #2100 updated the non-CI copies and
missed the CI ones. The two changes touch the same block, so they land together.

The guard-style checks ('$(DETECTED_HOST)' = x || '$(HOST)' = x) and the
build-vm/build-iso targets keep using DETECTED_HOST directly -- switching those
to RESOLVED_HOST would change their semantics.
@indent-zero

indent-zero Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor
PR Summary

Extracts the machine-detection heuristic that computes DETECTED_HOST from a 27-line inline $(shell ...) block in the Makefile into scripts/detect-host.sh so it can be exercised directly by spec/detect_host_spec.sh. Also collapses the HOST/DETECTED_HOST/fallback ladder that was duplicated 11 times across nix-build and nix-switch onto a single RESOLVED_HOST := $(or $(HOST),$(DETECTED_HOST)) — that duplication is what caused #2105 (PR #2100 updated the non-CI copies and missed the CI ones). Behavior is preserved: guard-style targets (service restarts, refresh-*-daemon) and build-vm/run-vm/build-iso intentionally keep referencing DETECTED_HOST directly because switching them to RESOLVED_HOST would change their semantics.

  • Add scripts/detect-host.sh reading OS, ARCH, DMI_SYS_VENDOR, DMI_PRODUCT_NAME, RUNPOD_POD_ID from the environment, preserving all four detection paths (Darwin arm64 + shunkakinoki + scutil ComputerName → galactica; Linux RUNPOD_POD_IDpod; Linux hostname kyber/matic; Linux Framework 13 AMD Ryzen AI 300 DMI → matic).
  • Rewrite the DETECTED_HOST Makefile assignment to call the script with the four env vars piped in, and introduce RESOLVED_HOST := $(or $(HOST),$(DETECTED_HOST)).
  • Replace every if HOST elif DETECTED_HOST else fallback block in nix-build and nix-switch (CI and non-CI, across Darwin/NixOS/Home branches) with a single if RESOLVED_HOST else fallback check.
  • Add make detect-host diagnostic target that prints Detected host and Resolved host (with (from HOST=…) when set explicitly).
  • Add spec/detect_host_spec.sh covering Linux DMI match, RunPod precedence, non-Framework vendor rejection, wrong Framework product, empty DMI, Darwin non-arm64, unknown OS, and unset OS.

Issues

No issues found.

CI Checks

Waiting for CI checks...

@cursor

cursor Bot commented Jul 18, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@mesa-dot-dev

mesa-dot-dev Bot commented Jul 18, 2026

Copy link
Copy Markdown

You do not have enough credits to review this pull request. Please purchase more credits to continue.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added automatic host detection across supported macOS and Linux environments.
    • Added a detect-host command to display detected and resolved host values.
    • Explicit host selections now take precedence over automatic detection.
    • Build, switch, and home-manager workflows consistently use the resolved host.
  • Bug Fixes

    • Improved CI behavior by skipping NixOS switching when the runner is not a NixOS system.
  • Tests

    • Added coverage for supported hardware, platforms, containers, and unknown environments.

Walkthrough

Changes

Host resolution and Nix integration

Layer / File(s) Summary
Environment-based host detection
scripts/detect-host.sh, spec/detect_host_spec.sh
Adds strict Bash host detection for Darwin and Linux environments, with tests for supported mappings and empty-result cases.
Centralized Make host resolution
Makefile
Uses scripts/detect-host.sh, prefers explicit HOST through RESOLVED_HOST, and adds the detect-host target.
RESOLVED_HOST Nix workflows
Makefile
Updates CI and non-CI nix-build and nix-switch paths to select configurations from RESOLVED_HOST.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Makefile
  participant DetectHostScript as scripts/detect-host.sh
  participant NixWorkflow as nix-build/nix-switch
  Makefile->>DetectHostScript: detect host from OS and machine identity
  DetectHostScript-->>Makefile: return detected host or empty result
  Makefile->>Makefile: prefer HOST over DETECTED_HOST as RESOLVED_HOST
  Makefile->>NixWorkflow: select configuration using RESOLVED_HOST
  NixWorkflow-->>Makefile: build or switch selected configuration
Loading

Possibly related PRs

Suggested labels: enhancement

Poem

I sniffed the hosts beneath the sun,
Found matic, pod, and galactica one by one.
A chosen host now leads the way,
Through Nix builds bright and switches gay.
Tests guard each burrowed track—
Hop, hop, and never look back!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: moving host detection out of the Makefile into a script.
Description check ✅ Passed The description matches the refactor and testing updates described in the diff.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/extract-host-detection

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mesa-dot-dev

mesa-dot-dev Bot commented Jul 18, 2026

Copy link
Copy Markdown

Mesa Description

TL;DR

Extracted inline Makefile machine detection into a dedicated, testable script and unified host resolution into a single RESOLVED_HOST variable to eliminate duplication.

What changed?

  • Makefile:
    • Extracted 27-line inline $(shell ...) machine detection block to an external script.
    • Added a thin detect-host target to output detected and resolved hosts.
    • Unified 11 duplicate host-resolution fallback chains across nix-build and nix-switch into a single RESOLVED_HOST := $(or $(HOST),$(DETECTED_HOST)) variable.
  • scripts/detect-host.sh:
    • New script containing host detection logic, reading OS, ARCH, DMI_SYS_VENDOR, DMI_PRODUCT_NAME, and RUNPOD_POD_ID from the environment.
  • spec/detect_host_spec.sh:
    • New test spec exercising host detection directly (covers Framework 13 match, RunPod override, non-matching Framework, other vendors, and no-host cases).

Description generated by Mesa. Update settings

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the machine detection logic for automatic host mapping out of the Makefile and into a dedicated bash script scripts/detect-host.sh, while adding a comprehensive test suite in spec/detect_host_spec.sh. It also introduces a RESOLVED_HOST variable to simplify host selection across build and switch targets. The review feedback highlights potential shell syntax issues in the Makefile when passing variables inline that might contain single quotes, suggesting using export instead. Additionally, it recommends replacing echo with printf in the bash script when outputting system-provided variables to ensure robust handling of hyphens and backslashes.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread Makefile
Comment on lines +95 to +97
DETECTED_HOST := $(shell OS='$(OS)' ARCH='$(ARCH)' \
DMI_SYS_VENDOR='$(DMI_SYS_VENDOR)' DMI_PRODUCT_NAME='$(DMI_PRODUCT_NAME)' \
bash ./scripts/detect-host.sh)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Passing variables inline to $(shell ...) using single quotes can break the shell syntax if any of the variables (especially DMI_PRODUCT_NAME or DMI_SYS_VENDOR which are read from system files) contain single quotes (e.g., Shun's Laptop).

Instead of passing them inline, you can use the export directive in the Makefile. This makes the variables automatically available in the environment of the $(shell ...) subshell, eliminating any quoting or escaping issues entirely.

export OS ARCH DMI_SYS_VENDOR DMI_PRODUCT_NAME
DETECTED_HOST := $(shell bash ./scripts/detect-host.sh)

Comment thread scripts/detect-host.sh

local computer_name
computer_name="$(scutil --get ComputerName 2>/dev/null || true)"
if echo "$computer_name" | grep -q "Shun's MacBook M4"; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using echo to output arbitrary system-provided variables (like computer_name) can be problematic if the value starts with a hyphen (which echo might interpret as an option) or contains backslashes. Using printf '%s\n' is the standard, robust way to output variable values safely.

Suggested change
if echo "$computer_name" | grep -q "Shun's MacBook M4"; then
if printf '%s\n' "$computer_name" | grep -q "Shun's MacBook M4"; then

Comment thread scripts/detect-host.sh
Comment on lines +50 to +51
if [ "$DMI_SYS_VENDOR" = "Framework" ] &&
echo "$DMI_PRODUCT_NAME" | grep -q "Laptop 13.*AMD Ryzen AI 300"; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using echo to output arbitrary system-provided variables (like DMI_PRODUCT_NAME) can be problematic if the value starts with a hyphen or contains backslashes. Using printf '%s\n' is the standard, robust way to output variable values safely.

Suggested change
if [ "$DMI_SYS_VENDOR" = "Framework" ] &&
echo "$DMI_PRODUCT_NAME" | grep -q "Laptop 13.*AMD Ryzen AI 300"; then
if [ "$DMI_SYS_VENDOR" = "Framework" ] &&
printf '%s\n' "$DMI_PRODUCT_NAME" | grep -q "Laptop 13.*AMD Ryzen AI 300"; then

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/detect-host.sh`:
- Around line 20-31: Update the machine-probe logic used by detect_darwin_host
and the related hostname detection to accept environment overrides for whoami,
scutil ComputerName, and hostname, falling back to the existing commands only
when each override is unset. Update spec/detect_host_spec.sh to explicitly
neutralize or set these overrides for deterministic Linux and Darwin detection
cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fb6334ca-1de7-498c-986a-6d3848b7887f

📥 Commits

Reviewing files that changed from the base of the PR and between 80320ac and 65043cc.

📒 Files selected for processing (3)
  • Makefile
  • scripts/detect-host.sh
  • spec/detect_host_spec.sh

Comment thread scripts/detect-host.sh
Comment on lines +20 to +31
detect_darwin_host() {
if [ "$(whoami 2>/dev/null || true)" != "shunkakinoki" ] || [ "$ARCH" != "arm64" ]; then
return 0
fi

local computer_name
computer_name="$(scutil --get ComputerName 2>/dev/null || true)"
if echo "$computer_name" | grep -q "Shun's MacBook M4"; then
echo "galactica"
fi
return 0
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the machine probes injectable for deterministic detection tests.

The script still reads whoami, scutil, and hostname directly. Consequently, the Linux specs expecting DMI or empty output can fail on a machine named kyber or matic, while the positive Darwin mapping cannot be isolated in tests.

Accept environment overrides for these values, falling back to the commands only when the overrides are unset; then explicitly neutralize/set them in spec/detect_host_spec.sh.

Also applies to: 39-46

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/detect-host.sh` around lines 20 - 31, Update the machine-probe logic
used by detect_darwin_host and the related hostname detection to accept
environment overrides for whoami, scutil ComputerName, and hostname, falling
back to the existing commands only when each override is unset. Update
spec/detect_host_spec.sh to explicitly neutralize or set these overrides for
deterministic Linux and Darwin detection cases.

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