Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Syntax highlighting silently fails (and `Bundle.module` crashes) in SwiftPM CLI-built app bundles

Abierto
#95 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
65/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Tranquilo
Stack tecnológico
macos, swift
Área
devtools

Línea de trabajo

Comienza en CodeLanguage.swift, especialmente en resourceURL y queryURL(for:), y reproduce el problema con swift build y una .app ensamblada manualmente que contenga el bundle de recursos indicado. Verifica que el bundle se encuentre en Contents/Resources, que funcionen ambas disposiciones de las consultas, que los archivos .scm se carguen para el resaltado y que los consumidores compilados con Xcode conserven su comportamiento actual; ejecuta SwiftLint.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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:

  1. Distributed app crashes on the first highlight lookup, because the
    SwiftPM-generated Bundle.module accessor cannot locate the resource
    bundle inside a .app and calls fatalError.
  2. Even with the bundle located, every tree-sitter query file fails to
    load
    because CodeLanguage.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: CodeEditLanguages 0.1.20 (pulled transitively via
    CodeEditSourceEditor 0.15.2).
  • 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 (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)")
}
  • mainPath uses Bundle.main.**bundleURL** — i.e. the .app wrapper root,
    not Contents/Resources. A correctly-formed .app keeps resources in
    Contents/Resources, so this candidate never matches.
  • buildPath is 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
  1. Depend on CodeEditLanguages (directly or via CodeEditSourceEditor).
  2. swift build (no Xcode project).
  3. Assemble a .app and copy CodeEditLanguages_CodeEditLanguages.bundle
    into Contents/Resources/.
  4. Run the .app. First access to a language's queryURL → crash at the
    accessor's fatalError.
  • 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
  1. With Defect 1 worked around (bundle located), open any source file in an
    editor backed by CodeEditSourceEditor.
  2. Observe: no syntax colors; text is uniform gray.
  3. Log CodeLanguage.swift.queryURL and FileManager.fileExists on the
    returned path — the file is not there.
  • Expected: the .scm query loads; tokens are highlighted.
  • Actual: queryURL resolves 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.

  1. 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
    
  2. 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.

Lenguaje dominante
Swift
Estrellas
133
Forks
56
Métricas de merge de PR
Sin PR fusionados en 30 d

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de CodeEditApp/CodeEditLanguages

Todos los issues de CodeEditApp/CodeEditLanguages

Issues similares

Más issues de Swift

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.