CodeEditApp / CodeEditApp/CodeEditSymbols

`swift build` fails without Xcode: `Symbols.xcassets` not declared as a resource, and `Bundle.module` unreachable in distributed apps

Open
#22 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Swift
Stars
25
Forks
15
PR merge metrics
No merged PRs in 30d

Description

## Summary

`CodeEditSymbols` builds cleanly under Xcode but has two problems for consumers
who build with `swift build` on the command line and package their own `.app`:

1. **The build fails outright.** `Package.swift` never declares
`Symbols.xcassets` as a resource, so SwiftPM's command-line build does not
process the asset catalog and does not synthesize `Bundle.module`. (Xcode
auto-detects asset catalogs, which is why this is invisible in an Xcode
build.) This is a one-line manifest fix.
2. **Once building, a distributed `.app` crashes** on first symbol access,
because the generated `Bundle.module` accessor cannot find the resource
bundle inside a `.app`.

## Environment

- Package: `CodeEditSymbols` 0.2.3.
- Build: `swift build` from the command line. **No `.xcodeproj`.** The app is
assembled into a `.app` by a custom script that copies the SwiftPM resource
bundle (`CodeEditSymbols_CodeEditSymbols.bundle`) into
`MyApp.app/Contents/Resources/`.
- macOS, Apple Silicon, current Swift toolchain.

## Defect 1 — `swift build` fails: asset catalog not declared as a resource

### Root cause

`Package.swift` declares the target with no `resources:` rule:

```swift
.target(
name: "CodeEditSymbols",
dependencies: []
),
```

`Sources/CodeEditSymbols/Symbols.xcassets` is therefore not treated as a
package resource by the SwiftPM command-line build, `Bundle.module` is not
generated, and `CodeEditSymbols.swift` (which references `Bundle.module`)
fails to compile / the resource is never processed. Xcode papers over this by
auto-detecting `.xcassets`; `swift build` does not.

### Repro

1. `swift build` a target that depends on `CodeEditSymbols` (no Xcode project).
2. Build fails:

```text
Sources/CodeEditSymbols/CodeEditSymbols.swift:47:16: error: type 'Bundle' has no member 'module'
```

- **Expected:** `swift build` succeeds and bundles the symbol assets.
- **Actual:** build failure.

### Fix

Declare the asset catalog as a processed resource. `.process` has been
available since swift-tools-version 5.3, so **no tools-version bump is needed**
(the manifest stays at 5.5):

```swift
.target(
name: "CodeEditSymbols",
dependencies: [],
resources: [
.process("Symbols.xcassets")
]
),
```

## Defect 2 — `Bundle.module` fatalErrors in a distributed `.app`

### Root cause

Same shape as the companion `CodeEditLanguages` issue. The SwiftPM-generated
accessor probes only `Bundle.main.bundleURL/.bundle` (the `.app` wrapper
root) and a hardcoded absolute build-machine path, then `fatalError`s.
`Contents/Resources/.bundle` — where a CLI-assembled app copies the
resource bundle — is not among the probed locations.

`Bundle.module` is used in `CodeEditSymbols.swift`:

```swift
init(symbol: String) {
self.init(symbol, bundle: Bundle.module) // Image
}
static func symbol(named: String) -> NSImage? {
Bundle.module.image(forResource: named) // NSImage
}
```

### Repro

1. With Defect 1 fixed, assemble a `.app` and copy
`CodeEditSymbols_CodeEditSymbols.bundle` into `Contents/Resources/`.
2. Run the `.app`; access any `Image(symbol:)` / `.symbol(named:)`.
3. Crash at the accessor's `fatalError`.

- **Expected:** the symbol renders; no crash.
- **Actual:** `fatalError("could not load resource bundle …")`.

### Fix

Resolve the bundle from `Bundle.main.resourceURL` (i.e. `Contents/Resources`)
first, then fall back to `Bundle.module` (which still serves `swift build` /
`swift test` on the build machine). This changes nothing for Xcode consumers:

```swift
let symbolsBundle: Bundle = {
if let bundled = Bundle.main.resourceURL?
.appendingPathComponent("CodeEditSymbols_CodeEditSymbols.bundle"),
let bundle = Bundle(url: bundled) {
return bundle
}
return Bundle.module
}()
```

…and route the two `Bundle.module` references through `symbolsBundle`.

## Offer to contribute

We're already running both changes as a local patch against 0.2.3 with no
observed regression. Per the CodeEdit contribution convention (open an issue
first, ask to be assigned), we'd be happy to submit the PR — could you assign
this to us? The patch passes SwiftLint. Glad to adjust if you'd prefer a
different approach.

Thanks for maintaining CodeEditSymbols.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.