ReviewOS

also looking at this

pantry-pm/pantry

feat(webkitgtk): add the GTK3 WebKit provider craft's Linux binary needs

#272
Merged glennmichael123 wants to merge feat/266-webkitgtk-provider into main
7 files +425 -4
packages/ts-pantry/test/webkitgtk-provider.test.tsadded+105-0
Changes to packages/ts-pantry/test/webkitgtk-provider.test.ts
@@ -0,0 +1,105 @@
1// craft-native.org's Linux artifact could not be published: its binary links
2// seven libraries the recipe never provided, and ELF normalization refused it.
3// Three of those sonames belong to a WebKit API that had no owner in the
4// catalog at all, so a dependency declaration alone could not have fixed it.
5// These tests pin the provider's identity and the closure that must exist.
6
7import { describe, expect, it } from 'bun:test'
8import { recipeDepsToSpecs } from '../src/dependency-spec'
9import { pantry } from '../src/packages'
10import { recipe as craft } from '../src/recipes/craft-native.org'
11import { recipe as webkitgtk } from '../src/recipes/webkitgtk.org'
12
13const cmakeArgs = (webkitgtk.build?.env?.CMAKE_ARGS ?? []) as string[]
14const byDomain = new Map(Object.values(pantry).map(entry => [(entry as any).domain, entry as any]))
15
16describe('the WebKitGTK provider owns the API craft actually links', () => {
17 it('selects the GTK3 4.1 API rather than the GTK4 6.0 default', () => {
18 // OptionsGTK.cmake defaults USE_GTK4 ON, which produces webkitgtk-6.0.
19 // Only USE_GTK4=OFF yields WEBKITGTK_API_INFIX "2" and so the
20 // libwebkit2gtk-4.1 / libjavascriptcoregtk-4.1 sonames craft needs.
21 expect(cmakeArgs).toContain('-DUSE_GTK4=OFF')
22 expect(cmakeArgs).toContain('-DPORT=GTK')
23 })
24
25 it('is not a WPE or GTK4 substitute', () => {
26 expect(webkitgtk.domain).toBe('webkitgtk.org')
27 expect(webkitgtk.domain).not.toContain('wpewebkit')
28 expect(JSON.stringify(webkitgtk.dependencies)).not.toContain('wpewebkit')
29 expect(JSON.stringify(webkitgtk.dependencies)).not.toContain('gtk4')
30 })
31
32 it('ships the helper processes and injected bundle its libraries spawn', () => {
33 // libwebkit2gtk does not render in-process: it execs WebKitWebProcess and
34 // WebKitNetworkProcess from PKGLIBEXECDIR and dlopens the injected bundle.
35 // A consumer that bundles only the .so gets a library that fails on the
36 // first page it creates.
37 expect(webkitgtk.runtimeResources).toEqual([
38 'libexec/webkit2gtk-4.1',
39 'lib/webkit2gtk-4.1/injected-bundle',
40 ])
41 })
42
43 it('builds only where the GTK3 stack is published', () => {
44 expect(webkitgtk.platforms).toEqual(['linux/x86-64'])
45 })
46})
47
48describe('the provider only claims a closure the catalog can satisfy', () => {
49 it('disables GStreamer itself, not merely video and web audio', () => {
50 // GStreamerChecks.cmake guards on USE_GSTREAMER and then calls
51 // find_package(GStreamer REQUIRED COMPONENTS app pbutils) with app and
52 // pbutils listed unconditionally — ENABLE_VIDEO=OFF alone still fails
53 // configure. Pantry publishes gstreamer.freedesktop.org/orc and no
54 // GStreamer core, so the subsystem is off until those recipes exist.
55 expect(cmakeArgs).toContain('-DUSE_GSTREAMER=OFF')
56 expect(cmakeArgs).toContain('-DENABLE_VIDEO=OFF')
57 expect(cmakeArgs).toContain('-DENABLE_WEB_AUDIO=OFF')
58 expect(JSON.stringify(webkitgtk.dependencies)).not.toContain('gstreamer')
59 })
60
61 it('turns off every feature whose provider the catalog lacks', () => {
62 // Each has a find_package ... FATAL_ERROR in OptionsGTK.cmake and no
63 // provider here: Enchant, libhyphen, libmanette, libdrm/GBM.
64 for (const flag of ['-DENABLE_SPELLCHECK=OFF', '-DUSE_LIBHYPHEN=OFF', '-DENABLE_GAMEPAD=OFF', '-DUSE_LIBDRM=OFF', '-DUSE_GBM=OFF'])
65 expect(cmakeArgs).toContain(flag)
66 })
67
68 it('requires libsoup3, which is what the 4.1 API is', () => {
69 // 2.54 calls find_package(Soup3 3.0.0 REQUIRED) unconditionally; the
70 // libsoup2 API 4.0 variant is gone.
71 expect((webkitgtk.dependencies as any)['libsoup.org']).toBe('^3')
72 })
73
74 it('names only domains that exist in the catalog', () => {
75 const declared = Object.keys(webkitgtk.dependencies ?? {})
76 expect(declared.length).toBeGreaterThan(0)
77 expect(declared.filter(domain => !byDomain.has(domain))).toEqual([])
78 })
79})
80
81describe("craft declares its Linux runtime closure and nothing on Darwin", () => {
82 const specs = recipeDepsToSpecs(craft.dependencies as any)
83
84 it('covers each unresolved library through its owning provider', () => {
85 // libgtk-3 / libgdk-3 → gtk3; libglib-2.0 / libgobject-2.0 / libgio-2.0 →
86 // glib; libwebkit2gtk-4.1 / libjavascriptcoregtk-4.1 → webkitgtk.
87 expect(specs).toEqual([
88 'linux:gtk.org/gtk3^3.24',
89 'linux:gnome.org/glib^2',
90 'linux:webkitgtk.org^2.54',
91 ])
92 })
93
94 it('adds nothing on Darwin, which uses the system WebKit framework', () => {
95 expect(specs.every(spec => spec.startsWith('linux:'))).toBe(true)
96 expect(specs.some(spec => spec.startsWith('darwin'))).toBe(false)
97 })
98
99 it('points every declared provider at a real catalog entry', () => {
100 for (const spec of specs) {
101 const domain = spec.slice('linux:'.length).replace(/[@^~<>=].*$/, '')
102 expect(byDomain.get(domain)).toBeDefined()
103 }
104 })
105})