Skip to content

fix(icons): emit warning instead of silent no-op when Assets.car generation is unsupported - #5309

Merged
leaanthony merged 2 commits into
masterfrom
agent/engineer-mac/0956e707
May 3, 2026
Merged

leaanthony merged 2 commits into
masterfrom
agent/engineer-mac/0956e707

Conversation

@leaanthony

@leaanthony leaanthony commented May 3, 2026 •

Copy link
Copy Markdown
Member

Closes #5260.

Problem

wails3 generate icons -iconcomposerinput appicon.icon -macassetdir darwin exited 0 with no output when Assets.car couldn't be generated (wrong platform, macOS < 26, or actool unavailable). Users assumed the command worked because there was no error, but darwin/Assets.car was never updated.

Changes

v3/internal/commands/icons.go

  • Each bare return ErrMacAssetNotSupported in generateMacAsset() is now a descriptive fmt.Errorf("...: %w", ErrMacAssetNotSupported), covering platform, macOS version, actool availability, and actool version. errors.Is(err, ErrMacAssetNotSupported) semantics preserved via %w.
  • GenerateIcons() now prints Warning: <reason> to stderr on the fallthrough path instead of silently swallowing the error.
  • -iconcomposerinput and -macassetdir flag descriptions mention the macOS 26 + Xcode actool 26+ requirement.

v3/internal/commands/icons_test.go

  • requireDarwin skip also checks actool functionality (handles macOS 26 machines with CLT but not full Xcode).
  • New TestGenerateIconsFallthrough: verifies .ico is still produced when Assets.car is unavailable.

Before

$ wails3 generate icons -input appicon.png -macfilename darwin/icons.icns \
  -windowsfilename windows/icon.ico \
  -iconcomposerinput appicon.icon -macassetdir darwin
$   # exit 0, no output, Assets.car unchanged — silent no-op

After

$ wails3 generate icons -input appicon.png -macfilename darwin/icons.icns \
  -windowsfilename windows/icon.ico \
  -iconcomposerinput appicon.icon -macassetdir darwin
Warning: Assets.car generation requires actool 26 or later (actool not found at /usr/bin/actool — install Xcode): mac asset generation is only supported on macOS
$   # exit 0, .icns and .ico regenerated, warning explains why Assets.car was skipped

Test results

go test ./internal/commands/ -run "TestGenerateIcon|TestGenerateIconsFallthrough" -v -count=1
--- PASS: TestGenerateIcon (0.29s)  — 10 pass, 1 skip (actool not functional)
--- PASS: TestGenerateIconsFallthrough (0.09s)
PASS  ok  github.com/wailsapp/wails/v3/internal/commands  1.034s

Summary by CodeRabbit

  • New Features

    • Icon generation now falls back to alternative formats when macOS asset generation is unavailable.
  • Bug Fixes

    • Improved error handling and warnings when macOS 26+ with Xcode CLT 26+ is required.
    • Updated system requirements documentation.
  • Tests

    • Added test coverage for icon generation fallback behavior.

…ration is unsupported

`wails3 generate icons -iconcomposerinput appicon.icon -macassetdir darwin`
previously exited 0 with no output when Assets.car could not be
generated (wrong platform, macOS < 26, or actool unavailable). Users
assumed the command worked because there was no error, but their icon
artwork did not update.

Each early-exit in generateMacAsset() now returns a descriptive wrapped
error preserving errors.Is(err, ErrMacAssetNotSupported) semantics via
%w. GenerateIcons() prints a Warning: line to stderr on the fallthrough
path instead of silently swallowing it. Flag help text for
-iconcomposerinput and -macassetdir surfaces the macOS 26 / actool 26+
requirement. Test skip condition for the Assets.car test also checks
actool functionality. New TestGenerateIconsFallthrough verifies .ico is
still produced when Assets.car is unavailable.
Copilot AI review requested due to automatic review settings May 3, 2026 01:45
@coderabbitai

coderabbitai Bot commented May 3, 2026 •

Copy link
Copy Markdown
Contributor

Walkthrough

The PR enhances the icon generation command to gracefully handle unsupported platforms when generating macOS assets via Icon Composer. When Assets.car generation fails on platforms lacking macOS 26+ or actool 26+, the code now emits a warning to stderr and continues generating icons from alternate input if available, preventing silent failures while maintaining backward compatibility.

Changes

Icon Generation Fallback and Error Handling

Layer / File(s) Summary
Documentation & Metadata
v3/internal/commands/icons.go (lines 30–35)
IconsOptions field descriptions for IconComposerInput and MacAssetDir are updated to document macOS 26+ and Xcode CLT actool 26+ requirements.
Core Fallback Logic
v3/internal/commands/icons.go (lines 37–81)
GenerateIcons now catches ErrMacAssetNotSupported errors from mac asset generation, emits a warning to os.Stderr, and continues with input-based icon generation when options.Input is provided; only returns an error if input is unavailable.
Contextual Error Wrapping
v3/internal/commands/icons.go (lines 162–215)
generateMacAsset replaces bare ErrMacAssetNotSupported returns with wrapped fmt.Errorf calls that include context (current runtime.GOOS, specific failure points during version checks and actool validation) while preserving errors.Is compatibility.
Test Coverage & Validation
v3/internal/commands/icons_test.go (lines 319–372)
Existing test now gates on actool availability via /usr/bin/actool --version execution; new TestGenerateIconsFallthrough verifies that .ico generation succeeds even when macOS Assets.car generation is unsupported.

Sequence Diagram

sequenceDiagram
    participant User
    participant GenerateIcons
    participant generateMacAsset
    participant stderr
    participant Filesystem

    User->>GenerateIcons: Call with Input + IconComposerInput
    GenerateIcons->>generateMacAsset: Attempt Assets.car generation
    
    alt Mac Asset Unsupported
        generateMacAsset-->>GenerateIcons: ErrMacAssetNotSupported (wrapped)
        GenerateIcons->>stderr: Emit warning message
        GenerateIcons->>GenerateIcons: Check options.Input available
        
        alt Input Available
            GenerateIcons->>Filesystem: Generate .ico from Input
            GenerateIcons-->>User: Success with .ico only
        else Input Empty
            GenerateIcons-->>User: Error (no Input fallback)
        end
    else Mac Asset Supported
        generateMacAsset->>Filesystem: Write Assets.car
        generateMacAsset-->>GenerateIcons: Success
        GenerateIcons->>Filesystem: Generate .ico from Input
        GenerateIcons-->>User: Success with both Assets.car and .ico
    end
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related Issues

Possibly Related PRs

Poem

🐰 Hop through the assets with grace and with care,
When macOS fails, we don't just despair—
A warning we whisper, a path we still take,
The icons still shimmer, for fallback's sake! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: emitting a warning instead of silently failing when Assets.car generation is unsupported, which is the core behavioral fix in this PR.
Description check ✅ Passed The description provides a clear problem statement, detailed changes to two files, before/after examples, and test results. It directly addresses the linked issue.
Linked Issues check ✅ Passed The PR fully addresses issue #5260 by emitting a warning to stderr when Assets.car generation is unsupported, updating flag descriptions to document the macOS 26+ requirement, and adding fallthrough test coverage.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the silent failure of Assets.car generation: improved error messages, warning emission, flag documentation, and corresponding test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 agent/engineer-mac/0956e707

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.11.4)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

Copilot AI 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.

Pull request overview

Updates the wails3 generate icons command to surface when macOS Assets.car generation is skipped (unsupported platform/version/tooling), instead of silently doing nothing, while keeping the rest of icon generation working.

Changes:

  • Wrap ErrMacAssetNotSupported with descriptive context in generateMacAsset() while preserving errors.Is(..., ErrMacAssetNotSupported) via %w.
  • Print a warning to stderr (and continue with input-based icon generation) when Assets.car generation is unsupported but -input is provided.
  • Update tests to skip macOS asset generation when actool isn’t functional, and add a fallthrough test ensuring .ico generation still succeeds.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
v3/internal/commands/icons.go Adds contextual unsupported-reason errors and emits a stderr warning instead of silently swallowing unsupported Assets.car generation.
v3/internal/commands/icons_test.go Improves darwin-only skip conditions and adds a test ensuring .ico generation still works when mac asset generation is unavailable.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +33 to +34
IconComposerInput string `description:"The input Icon Composer file (.icon) [requires macOS 26 or later with Xcode CLT actool 26+]"`
MacAssetDir string `description:"The output directory for the Mac assets (Assets.car and icons.icns) [requires macOS 26 or later with Xcode CLT actool 26+]"`
versionPlist, err := cmd.Output()
if err != nil {
return ErrMacAssetNotSupported
return fmt.Errorf("Assets.car generation requires actool 26 or later (actool not found at /usr/bin/actool — install Xcode): %w", ErrMacAssetNotSupported)

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
v3/internal/commands/icons_test.go (1)

346-372: ⚡ Quick win

TestGenerateIconsFallthrough doesn't assert that the warning was emitted to os.Stderr.

The primary behavioral change in this PR — printing "Warning: …" to stderr — is never verified. If the fmt.Fprintf(os.Stderr, …) call were accidentally removed or guarded by a wrong condition, this test would still pass as long as the .ico file is produced.

Capturing stderr in a Go test is straightforward with os.Pipe():

🧪 Proposed stderr-capture addition
 func TestGenerateIconsFallthrough(t *testing.T) {
 	_, thisFile, _, _ := runtime.Caller(0)
 	localDir := filepath.Dir(thisFile)
 	exampleIcon := filepath.Join(localDir, "build_assets", "appicon.png")
 	exampleIconFile := filepath.Join(localDir, "build_assets", "appicon.icon")
 	tmpDir := t.TempDir()
 	icoOut := filepath.Join(tmpDir, "appicon.ico")

+	// Capture os.Stderr to verify the warning is emitted on the fallthrough path.
+	origStderr := os.Stderr
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Fatalf("os.Pipe: %v", err)
+	}
+	os.Stderr = w

 	options := &IconsOptions{
 		Input:             exampleIcon,
 		WindowsFilename:   icoOut,
 		IconComposerInput: exampleIconFile,
 		MacAssetDir:       tmpDir,
 	}

-	if err := GenerateIcons(options); err != nil {
+	genErr := GenerateIcons(options)
+	w.Close()
+	os.Stderr = origStderr
+	var stderrBuf strings.Builder
+	io.Copy(&stderrBuf, r)
+
+	if genErr != nil {
 		t.Fatalf("GenerateIcons() unexpected error: %v", err)
 	}

+	// On platforms where Assets.car is unsupported the warning must be emitted.
+	// On macOS 26+ with actool 26+ the happy path runs and no warning is expected.
+	if runtime.GOOS != "darwin" {
+		if !strings.Contains(stderrBuf.String(), "Warning:") {
+			t.Errorf("expected a Warning on stderr, got: %q", stderrBuf.String())
+		}
+	}

 	f, err := os.Stat(icoOut)
 	if err != nil {
 		t.Fatalf("expected %s to exist: %v", icoOut, err)
 	}
 	if f.Size() == 0 {
 		t.Fatal("appicon.ico is empty")
 	}
 }

You'll also need "io" and "strings" in the import block.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@v3/internal/commands/icons_test.go` around lines 346 - 372, Update
TestGenerateIconsFallthrough to capture and assert stderr output: wrap the
GenerateIcons(options) call with an os.Pipe-based capture of os.Stderr (save
original os.Stderr, replace with pipe writer, close writer and read from pipe
after call), then assert the captured string (use strings.Contains or similar)
includes the expected "Warning:" message; keep test flow and file existence/size
checks intact and restore os.Stderr afterwards. Target symbols:
TestGenerateIconsFallthrough, GenerateIcons, IconsOptions and the
fmt.Fprintf(os.Stderr, ...) warning emission.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@v3/internal/commands/icons_test.go`:
- Around line 346-372: Update TestGenerateIconsFallthrough to capture and assert
stderr output: wrap the GenerateIcons(options) call with an os.Pipe-based
capture of os.Stderr (save original os.Stderr, replace with pipe writer, close
writer and read from pipe after call), then assert the captured string (use
strings.Contains or similar) includes the expected "Warning:" message; keep test
flow and file existence/size checks intact and restore os.Stderr afterwards.
Target symbols: TestGenerateIconsFallthrough, GenerateIcons, IconsOptions and
the fmt.Fprintf(os.Stderr, ...) warning emission.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e9c7486c-8b92-486b-8706-79ad97f4974d

📥 Commits

Reviewing files that changed from the base of the PR and between 19398e4 and 7b9dd91.

📒 Files selected for processing (2)
  • v3/internal/commands/icons.go
  • v3/internal/commands/icons_test.go

@leaanthony leaanthony added Bug Something isn't working go Pull requests that update Go code Ready For Testing A fix is available and needs testing v3 labels May 3, 2026
@leaanthony

Copy link
Copy Markdown
Member Author

Mac test: ✅ PASS — macOS 26.3, Xcode CLT only (no actool)

Tested on a clean macOS 26.3 VM with Xcode Command Line Tools installed (no full Xcode, actool absent at /usr/bin/actool).

Build: go build ./internal/commands/ — clean, exit 0.

Unit tests: go test -v ./internal/commands/ -run 'TestGenerateIcon|TestGenerateIconsFallthrough'

  • All TestGenerateIcon subtests pass; the Assets.car subtest is correctly skipped (actool not functional — install full Xcode).
  • New TestGenerateIconsFallthrough passes: warning emitted, .ico produced, exit 0.

Smoke test (wails3 generate icons -input appicon.png -windowsfilename appicon.ico -iconcomposerinput appicon.icon -macassetdir assets):

  • Exit 0
  • appicon.ico produced (non-empty)
  • stderr: Warning: Assets.car generation requires actool 26 or later (actool not found at /usr/bin/actool — install Xcode): mac asset generation is only supported on macOS

The fix behaves exactly as described: users on CLT-only setups now receive an actionable warning instead of a silent no-op. Full package test: ok github.com/wailsapp/wails/v3/internal/commands 0.519s.

@leaanthony

Copy link
Copy Markdown
Member Author

Linux CI — PR #5309 test results ✅

Tested on Ubuntu 24.04, Go 1.25.0, commit 7b9dd915.

Build

go install ./cmd/wails3 — success (wails3 v3.0.0-dev)

Unit tests

go test -v -count=1 ./internal/commands/ — all pass

Key results for the changed package:

Test Result
TestCFBundleIconNameDetection ✅ PASS
TestGenerateIcon (10 subtests) ✅ PASS (Assets.car subtest correctly SKIPPED — not macOS)
TestGenerateIconsFallthrough (new) ✅ PASS

The new TestGenerateIconsFallthrough test confirms the fix works on Linux — the warning is emitted to stderr and .ico generation succeeds:

Warning: Assets.car generation is only supported on macOS (current platform: linux): mac asset generation is only supported on macOS
--- PASS: TestGenerateIconsFallthrough (0.14s)

Smoke test

wails3 generate icons --input appicon.png --windowsfilename appicon.ico → exit 0, appicon.ico produced (1.7 KB).

Help text correctly shows updated descriptions:

-iconcomposerinput  [requires macOS 26 or later with Xcode CLT actool 26+]
-macassetdir        [requires macOS 26 or later with Xcode CLT actool 26+]

Linux verdict: PR-READY — no regressions, warning path verified.

@leaanthony

Copy link
Copy Markdown
Member Author

Windows test results — PR #5309

Tested on: Windows 11, Go 1.26.2 windows/amd64, wails3 built from commit 7b9dd915785eebaeb6a6106db8338faf8aac7bbc.

Unit tests

go test -v ./internal/commands/... from the v3/ module root:

43 PASS, 2 SKIP, 0 FAIL ✅

Key results:

  • TestGenerateIconsFallthrough — PASS — warning correctly emitted on stderr, .ico generated with exit 0
  • TestGenerateIcon/should_generate_a_Assets.car_and_icons.icns_file... — SKIP (expected — actool unavailable on Windows)

CLI smoke test (fallthrough path)

$ wails3 generate icons --input appicon.png --iconcomposerinput appicon.icon --macassetdir ./mac-assets --windowsfilename appicon.ico
Warning: Assets.car generation is only supported on macOS (current platform: windows): mac asset generation is only supported on macOS
Exit code: 0
.ico file created: ✅ (21,677 bytes)

Verdict

The fix works correctly on Windows:

  • Fallthrough path (both --input and --iconcomposerinput supplied): emits warning, generates .ico, exits 0 — no more silent no-op.
  • Mac-only path (--iconcomposerinput without --input): exits 1 with a descriptive error message.
  • Normal Windows path (--input + --windowsfilename): unaffected, continues to work.

No issues found on Windows. ✅

@leaanthony
leaanthony merged commit 4320c93 into master May 3, 2026
14 of 15 checks passed
@leaanthony
leaanthony deleted the agent/engineer-mac/0956e707 branch May 3, 2026 08:38
wayneforrest pushed a commit to wayneforrest/wails that referenced this pull request May 3, 2026
…mit warning instead of silent no-op when Assets.car generation is unsupported
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working go Pull requests that update Go code Ready For Testing A fix is available and needs testing v3

Projects

None yet

Development

Successfully merging this pull request may close these issues.

wails3 generate icons silently no-ops on Assets.car generation (-iconcomposerinput / -macassetdir)

2 participants