Syntax highlighting silently fails (and `Bundle.module` crashes) in SwiftPM CLI-built app bundles
还没有人认领这个 Issue。
评估
调研方向
从 CodeLanguage.swift 开始,重点查看 resourceURL 和 queryURL(for:),然后使用 swift build 和一个包含指定资源包的手动组装 .app 重现问题。验证能在 Contents/Resources 下找到该 bundle、两种 query 布局都能正常工作、.scm 文件能为语法高亮加载,并确认使用 Xcode 构建的使用方保持当前行为;运行 SwiftLint。
由索引模型根据 Issue 内容生成。
描述
Summary
When CodeEditLanguages is consumed by an app that is built and packaged
with swift build (plus a hand-rolled bundle-assembly step) rather than
Xcode, two resource-resolution problems surface:
- Distributed app crashes on the first highlight lookup, because the
SwiftPM-generatedBundle.moduleaccessor cannot locate the resource
bundle inside a.appand callsfatalError. - Even with the bundle located, every tree-sitter query file fails to
load becauseCodeLanguage.queryURL(for:)hardcodes a path layout that
only matches the Xcode-produced bundle. The editor renders as plain gray
text with no error.
Both stem from the same assumption — that the package is always built and
embedded by Xcode. Dev builds on the build machine work, which is why this is
easy to miss.
Environment
- Package:
CodeEditLanguages0.1.20 (pulled transitively via
CodeEditSourceEditor0.15.2). - Build:
swift buildfrom the command line. No.xcodeproj. The app is
assembled into a.appby a custom script that copies the SwiftPM resource
bundle (CodeEditLanguages_CodeEditLanguages.bundle) into
MyApp.app/Contents/Resources/. - macOS, Apple Silicon, current Swift toolchain.
Defect 1 — Bundle.module fatalErrors in a distributed .app
Root cause
The SwiftPM-generated accessor
(.build/…/CodeEditLanguages.build/DerivedSources/resource_bundle_accessor.swift)
probes exactly two locations:
let mainPath = Bundle.main.bundleURL.appendingPathComponent("CodeEditLanguages_CodeEditLanguages.bundle").path
let buildPath = "/Users/<build-machine>/…/.build/arm64-apple-macosx/debug/CodeEditLanguages_CodeEditLanguages.bundle"
let preferredBundle = Bundle(path: mainPath)
guard let bundle = preferredBundle ?? Bundle(path: buildPath) else {
Swift.fatalError("could not load resource bundle: from \(mainPath) or \(buildPath)")
}
mainPathusesBundle.main.**bundleURL**— i.e. the.appwrapper root,
notContents/Resources. A correctly-formed.appkeeps resources in
Contents/Resources, so this candidate never matches.buildPathis a hardcoded absolute path on the build machine. It
resolves during local development, but obviously not on any other machine.
Result on an end user's machine: neither candidate exists →
Swift.fatalError → the app crashes the first time a CodeLanguage's
resourceURL / query is accessed.
Bundle.module (CodeLanguage.resourceURL) is used here:
// CodeLanguage.swift
internal var resourceURL: URL? = Bundle.module.resourceURL
Repro
- Depend on
CodeEditLanguages(directly or viaCodeEditSourceEditor). swift build(no Xcode project).- Assemble a
.appand copyCodeEditLanguages_CodeEditLanguages.bundle
intoContents/Resources/. - Run the
.app. First access to a language'squeryURL→ crash at the
accessor'sfatalError.
- Expected: the bundle is found under
Contents/Resources; no crash. - Actual:
fatalError("could not load resource bundle …").
Defect 2 — query path assumes the Xcode bundle layout
Root cause
// CodeLanguage.swift
internal func queryURL(for highlights: String = "highlights") -> URL? {
return resourceURL?
.appendingPathComponent("Resources/tree-sitter-\(tsName)/\(highlights).scm")
}
The "Resources/" segment is unconditionally prepended. That matches the
directory nesting Xcode produces, but under the SwiftPM command-line build the
grammar files do not live at that relative path from the resolved
resourceURL, so queryURL points at a file that does not exist. The lookup
returns a URL that never resolves, no error is thrown, and highlighting
silently degrades to plain text.
Repro
- With Defect 1 worked around (bundle located), open any source file in an
editor backed byCodeEditSourceEditor. - Observe: no syntax colors; text is uniform gray.
- Log
CodeLanguage.swift.queryURLandFileManager.fileExistson the
returned path — the file is not there.
- Expected: the
.scmquery loads; tokens are highlighted. - Actual:
queryURLresolves to a non-existent path; queries silently
fail.
Proposed fix
Both are small and, importantly, change nothing for Xcode consumers — the
new code paths only engage when the current lookup fails.
-
Bundle resolution — before falling back to
Bundle.module, probe
Bundle.main.resourceURL(i.e.Contents/Resources), where a
CLI-assembled app copies the SwiftPM resource bundle:private static let queryBundleResourceURL: URL? = { if let bundled = Bundle.main.resourceURL? .appendingPathComponent("CodeEditLanguages_CodeEditLanguages.bundle"), let bundle = Bundle(url: bundled) { return bundle.resourceURL } return Bundle.module.resourceURL }() internal var resourceURL: URL? = CodeLanguage.queryBundleResourceURL -
Layout-aware query path — resolve against whichever layout exists on
disk, probing the nested (Resources/…) layout first so Xcode behavior is
byte-for-byte unchanged, then the flat layout:guard let base = resourceURL else { return nil } let relativePath = "tree-sitter-\(tsName)/\(highlights).scm" let nested = base.appendingPathComponent("Resources/\(relativePath)") if FileManager.default.fileExists(atPath: nested.path) { return nested } return base.appendingPathComponent(relativePath)
Offer to contribute
We are already running these two changes as a local patch against 0.1.20 and
they resolve both issues with no observed regression for Xcode-built consumers.
Per the CodeEdit contribution convention (open an issue first, ask to be
assigned), we'd be glad to submit the PR — could you assign this to us? The
patch passes SwiftLint and keeps the existing code paths as the primary
lookup. Happy to adjust the approach if you'd prefer a different shape.
Thanks for maintaining CodeEditLanguages.
- 主要语言
- Swift
- 星标
- 133
- 派生
- 56
- PR 合并指标
- 30 天内没有已合并 PR
贡献指南
这个仓库没有索引到贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
CodeEditApp/CodeEditLanguages 的其他 Issue
-
难度 1/5 1 小时以内 新手友好度 78/100
-
难度 4/5 3-5 天 新手友好度 35/100
CodeEditApp/CodeEditLanguages#94 · 1 条评论 · 1 个 reaction ·
-
难度 3/5 半天 新手友好度 45/100
CodeEditApp/CodeEditLanguages#93 · 1 条评论 ·
-
难度 3/5 1-2 天 新手友好度 35/100
-
bug
难度 3/5 1-2 天 新手友好度 35/100
查看 CodeEditApp/CodeEditLanguages 的全部 Issue
相似的 Issue
-
enhancement
难度 2/5 1-3 小时 新手友好度 68/100
-
type: docs
难度 1/5 1 小时以内 新手友好度 95/100
googleapis/google-cloud-swift#971 ·
-
难度 2/5 1-3 小时 新手友好度 76/100
bitcoindevkit/bdk-ffi#1125 ·
-
难度 2/5 1-3 小时 新手友好度 72/100
mozilla-mobile/firefox-ios#35743 ·
-
难度 2/5 1-3 小时 新手友好度 84/100
manaflow-ai/cmux#13417 ·