summarylogtreecommitdiffstats
path: root/PKGBUILD
blob: 4c1502f02371f0e2478751a9087a088c5eb201cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# Maintainer: ChHsich <hsichingchang@gmail.com>
pkgname=note-gen
_pkgname=note-gen
pkgver=0.37.1
pkgrel=1
pkgdesc="A cross-platform Markdown note-taking application with AI integration (X11/Wayland compatible)"
arch=('x86_64')
url="https://github.com/codexu/note-gen"
license=('MIT')
depends=('gtk3' 'webkit2gtk-4.1' 'libappindicator-gtk3' 'librsvg' 'libvips' 'libxcb' 'libxrandr' 'dbus' 'pipewire' 'wayland' 'libglvnd' 'glib2' 'mesa' 'sqlite')
makedepends=('rust' 'nodejs' 'npm' 'pnpm' 'pkgconf' 'clang')
checkdepends=('patchelf')
provides=('note-gen')
conflicts=('note-gen-bin')
options=('!strip' '!lto')
source=("$pkgname-$pkgver.tar.gz::$url/archive/note-gen-v$pkgver.tar.gz")
sha256sums=('d9f4a80a39b68b7f322186b24b41bd3864672edc21599071b160901b2d609435')

install=$pkgname.install

prepare() {
    cd "$pkgname-$pkgname-v$pkgver"
    # Set up build environment
    export npm_config_build_from_source=true
    export CARGO_HOME="$srcdir/.cargo"

    # Approve dependency build scripts: pnpm 10 blocks them silently,
    # pnpm 11 (strictDepBuilds) fails the install outright with
    # ERR_PNPM_IGNORED_BUILDS. Since 0.37.0 upstream ships its own
    # pnpm-workspace.yaml (monorepo, packages/*) defining the workspace
    # members that workspace:* deps resolve against — append our
    # approvals, never overwrite the file.
    touch pnpm-workspace.yaml
    grep -q '^onlyBuiltDependencies:' pnpm-workspace.yaml || cat >> pnpm-workspace.yaml <<'EOF'
onlyBuiltDependencies:
  - esbuild
  - sharp
  - unrs-resolver
  - "@parcel/watcher"
EOF
    grep -q '^allowBuilds:' pnpm-workspace.yaml || cat >> pnpm-workspace.yaml <<'EOF'
allowBuilds:
  esbuild: true
  sharp: true
  unrs-resolver: true
  "@parcel/watcher": true
EOF

    # pnpm 11 no longer reads the "pnpm" field from package.json, so
    # upstream's pnpm.overrides are ignored — which makes a frozen
    # install fail with ERR_PNPM_LOCKFILE_CONFIG_MISMATCH and a plain
    # install re-resolve open specifiers (e.g. @tauri-apps/api >=2.0.0
    # jumps to 2.11.x and the tauri CLI aborts on the crate/npm version
    # mismatch). Carry the overrides into pnpm-workspace.yaml, where
    # pnpm 11 does read them, so the lockfile config matches again.
    grep -q '^overrides:' pnpm-workspace.yaml || node -e '
const fs = require("fs");
const overrides = (JSON.parse(fs.readFileSync("package.json", "utf8")).pnpm || {}).overrides;
if (overrides) {
  const lines = ["overrides:"];
  for (const [k, v] of Object.entries(overrides)) lines.push(`  ${JSON.stringify(k)}: ${JSON.stringify(String(v))}`);
  fs.appendFileSync("pnpm-workspace.yaml", lines.join("\n") + "\n");
}'

    # Upstream's monorepo releases reference their own npm packages
    # published hours earlier; pnpm 11's default supply-chain policy
    # (minimumReleaseAge) rejects anything published within the last
    # 24h. The lockfile is frozen (integrity-pinned), so relax the age
    # policy for this build.
    grep -q '^minimumReleaseAge:' pnpm-workspace.yaml || \
        echo 'minimumReleaseAge: 0' >> pnpm-workspace.yaml

    # libspa-sys 0.8.0 pins bindgen 0.69, which cannot lay out
    # spa_pod_builder from pipewire >= 1.6 headers and emits an opaque
    # type, breaking the libspa 0.8.0 build. Vendor the crate with the
    # bindgen requirement bumped until upstream moves xcap (=0.6.0)
    # past pipewire-rs 0.8. If libspa-sys 0.8.0 is gone from the tree,
    # the patch is skipped (pointing [patch] at nothing breaks cargo).
    cd src-tauri
    cargo fetch || return 1
    local crate_src=""
    local reg
    for reg in "$CARGO_HOME"/registry/src/*/libspa-sys-0.8.0; do
        [ -d "$reg" ] && crate_src="$reg" && break
    done
    if [ -z "$crate_src" ]; then
        # cargo fetch downloads .crate archives without necessarily
        # extracting them to registry/src; extract the archive ourselves
        local cache
        for cache in "$CARGO_HOME"/registry/cache/*/libspa-sys-0.8.0.crate; do
            [ -f "$cache" ] || continue
            rm -rf vendor && mkdir -p vendor
            tar xf "$cache" -C vendor
            mv vendor/libspa-sys-0.8.0 vendor/libspa-sys
            crate_src="vendor/libspa-sys"
            break
        done
    fi
    if [ -n "$crate_src" ] && [ "$crate_src" != "vendor/libspa-sys" ]; then
        rm -rf vendor && mkdir -p vendor
        cp -r "$crate_src" vendor/libspa-sys
    fi
    if [ -n "$crate_src" ]; then
        rm -f vendor/libspa-sys/.cargo-checksum.json
        sed -i 's/version = "0.69"/version = "0.72"/' vendor/libspa-sys/Cargo.toml
        grep -q 'patch.crates-io' Cargo.toml || \
            printf '\n[patch.crates-io]\nlibspa-sys = { path = "vendor/libspa-sys" }\n' >> Cargo.toml
    fi
    cd ..
}

build() {
    cd "$pkgname-$pkgname-v$pkgver"
    export CARGO_HOME="$srcdir/.cargo"
    export npm_config_build_from_source=true

    # Build strictly following upstream tauri-action approach
    # 1. Install frontend dependencies. --frozen-lockfile installs the
    # locked tree as-is: plain install re-resolves open specifiers and
    # the newer @tauri-apps/* packages then fail tauri's npm/crate
    # version consistency check.
    pnpm install --frozen-lockfile

    # 2. Build Tauri application (tauri will handle beforeBuildCommand automatically)
    pnpm tauri build --no-bundle
}

package() {
    cd "$pkgname-$pkgname-v$pkgver/src-tauri"
    export CARGO_HOME="$srcdir/.cargo"

    # Install binary file (renamed to note-gen-real)
    install -Dm755 "target/release/$_pkgname" "$pkgdir/usr/bin/$_pkgname-real"

    # Create professional wrapper script
    install -Dm755 /dev/stdin "$pkgdir/usr/bin/$_pkgname-wrapper" << 'WRAPPER_EOF'
#!/usr/bin/env bash
# NoteGen wrapper script for Linux X11 compatibility
# Automatically detects graphics session environment and applies GBM fix when needed
# Usage: DEBUG=1 note-gen-wrapper [args...]

# Logging function
log() {
    local message="$*"
    if [ "$DEBUG" = "1" ]; then
        echo "$message" >&2
    fi
    logger -t note-gen-wrapper "$message"
}

# Check if GBM fix should be enabled
should_enable_gbm_fix() {
    # Wayland environment (via session type detection)
    [ "$XDG_SESSION_TYPE" = "wayland" ] && { log "Wayland session detected, no GBM fix needed"; return 1; }

    # Wayland environment (via environment variable detection)
    [ -n "$WAYLAND_DISPLAY" ] && { log "Wayland display detected, no GBM fix needed"; return 1; }
    [ -n "$WAYLAND_SOCKET" ] && { log "Wayland socket detected, no GBM fix needed"; return 1; }

    # X11 environment with display
    [ -n "$DISPLAY" ] && { log "X11 environment detected, applying GBM fix"; return 0; }

    # Headless/SSH environment
    log "No graphics environment detected, no modification needed"
    return 1
}

# Define package name
_pkgname="note-gen"

# Check if executable exists
check_executable() {
    local exec_path="/usr/bin/$_pkgname-real"
    if [ ! -x "$exec_path" ]; then
        logger -p err -t note-gen-wrapper "Executable not found: $exec_path"
        if [ "$DEBUG" = "1" ]; then
            echo "Error: Executable not found: $exec_path" >&2
        fi
        exit 127
    fi
}

# Main logic
log "NoteGen wrapper starting with arguments: $*"

# Detect and set environment variables
if should_enable_gbm_fix; then
    export WEBKIT_DISABLE_DMABUF_RENDERER=1
    log "Applied WEBKIT_DISABLE_DMABUF_RENDERER=1 for X11 compatibility"
fi

# Verify executable
check_executable

# Execute original program with all arguments
log "Executing: $_pkgname-real $*"
exec "$_pkgname-real" "$@"
WRAPPER_EOF

    # Create compatibility symlink
    ln -sf "$_pkgname-wrapper" "$pkgdir/usr/bin/$_pkgname"

    # Install icons - based on actual source code structure
    cd ..

    # Install existing icon sizes (according to actual source files)
    for size in 32x32 64x64 128x128; do
        if [ -f "src-tauri/icons/$size.png" ]; then
            install -Dm644 "src-tauri/icons/$size.png" "$pkgdir/usr/share/icons/hicolor/${size}/apps/$_pkgname.png"
        fi
    done

    # Install HiDPI icons (according to actual source files)
    if [ -f "src-tauri/icons/128x128@2x.png" ]; then
        install -Dm644 "src-tauri/icons/128x128@2x.png" "$pkgdir/usr/share/icons/hicolor/128x128@2x/apps/$_pkgname.png"
    fi

    # Create desktop entry and fallback icon (using actually existing files)
    if [ -f "public/app-icon.png" ]; then
        install -Dm644 "public/app-icon.png" "$pkgdir/usr/share/pixmaps/$_pkgname.png"
    elif [ -f "src-tauri/icons/128x128.png" ]; then
        install -Dm644 "src-tauri/icons/128x128.png" "$pkgdir/usr/share/pixmaps/$_pkgname.png"
    fi
    install -Dm644 /dev/stdin "$pkgdir/usr/share/applications/$_pkgname.desktop" << EOF
[Desktop Entry]
Name=NoteGen
Comment=A cross-platform Markdown note-taking application with AI integration
Exec=$_pkgname-wrapper %U
Icon=$_pkgname
Type=Application
Categories=Office;Utility;TextEditor;
StartupNotify=true
EOF

  }