buninu-linux 0.14.57 → 0.16.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/linux-firmware/LICENCE.nvidia +131 -0
- package/LICENSES/linux-firmware/LICENSE.amdgpu +51 -0
- package/LICENSES/linux-firmware/LICENSE.amdisp +31 -0
- package/LICENSES/linux-firmware/LICENSE.i915 +39 -0
- package/LICENSES/linux-firmware/LICENSE.radeon +51 -0
- package/LICENSES/linux-firmware/LICENSE.xe +39 -0
- package/LICENSES/linux-firmware/WHENCE +10280 -0
- package/NOTICE.md +64 -46
- package/README.md +378 -87
- package/README.zh.md +2041 -0
- package/build-image.sh +10 -1
- package/build-uki.sh +3 -1
- package/fetch-alpine.sh +14 -0
- package/graphics.md +31 -0
- package/index.js +28 -11
- package/initramfs/bin/buninu-browser +4 -1
- package/initramfs/bin/buninu-land +1 -1
- package/initramfs/bin/bunterm +3 -3
- package/initramfs/bin/chroot +13 -0
- package/initramfs/bin/chvt +11 -0
- package/initramfs/bin/mount +4 -0
- package/initramfs/bin/umount +6 -0
- package/initramfs/bin/xdg-open +33 -0
- package/initramfs/buninu/CHANGELOG.md +66 -0
- package/initramfs/buninu/apps/bunmsh/CHANGELOG.md +4 -0
- package/initramfs/buninu/apps/bunmsh/package.json +1 -1
- package/initramfs/buninu/apps/bunmsh/src/main.js +1 -1
- package/initramfs/buninu/apps/jsgotty/LICENSES/MIT-jsmdcui.txt +22 -0
- package/initramfs/buninu/apps/jsgotty/NOTICE +5 -0
- package/initramfs/buninu/apps/jsgotty/README.en.md +61 -0
- package/initramfs/buninu/apps/jsgotty/README.md +61 -0
- package/initramfs/buninu/apps/jsgotty/client-modes.mjs +117 -0
- package/initramfs/buninu/apps/jsgotty/client.mjs +100 -10
- package/initramfs/buninu/apps/jsgotty/clipboard-powershell.js +18 -0
- package/initramfs/buninu/apps/jsgotty/clipboard.js +148 -0
- package/initramfs/buninu/apps/jsgotty/gotty.js +13 -0
- package/initramfs/buninu/apps/jsgotty/package-lock.json +2 -2
- package/initramfs/buninu/apps/jsgotty/package.json +1 -1
- package/initramfs/buninu/apps/jsgotty/static/css/index.css +14 -1
- package/initramfs/buninu/apps/jsgotty/static/index.html +1 -0
- package/initramfs/buninu/apps/jsgotty/static/js/gotty.js +187 -23
- package/initramfs/buninu/apps/jsgotty/static/js/kitty-keyboard.js +193 -0
- package/initramfs/buninu/apps/jsgotty/static/js/kitty.js +115 -7
- package/initramfs/buninu/apps/jsgotty/terminal-modes.js +332 -0
- package/initramfs/buninu/apps/jsgotty/tests/android-alt.test.js +115 -0
- package/initramfs/buninu/apps/jsgotty/tests/arrow-modifiers.test.js +80 -0
- package/initramfs/buninu/apps/jsgotty/tests/client-exit.test.mjs +45 -0
- package/initramfs/buninu/apps/jsgotty/tests/client-modes.test.mjs +105 -0
- package/initramfs/buninu/apps/jsgotty/tests/clipboard-browser.test.js +81 -0
- package/initramfs/buninu/apps/jsgotty/tests/clipboard.test.js +75 -0
- package/initramfs/buninu/apps/jsgotty/tests/kitty-keyboard-browser.test.js +53 -0
- package/initramfs/buninu/apps/jsgotty/tests/kitty-keyboard.test.js +102 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual/README.md +20 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual/keyboard-collector.cjs +55 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual/keyboard-debug.js +74 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual/kitty-keyboard.js +80 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual/zoom-collector.cjs +55 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual/zoom-debug.js +39 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual-touch-diagnostics.js +33 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual-touch-diagnostics.mjs +22 -0
- package/initramfs/buninu/apps/jsgotty/tests/nested-cli-pty.test.mjs +116 -0
- package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes-browser.test.js +144 -0
- package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes.md +44 -0
- package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes.test.js +166 -0
- package/initramfs/buninu/apps/jsgotty/tests/touch-drag-browser.test.js +106 -0
- package/initramfs/buninu/apps/jsgotty/tests/wheel-browser.test.js +60 -0
- package/initramfs/buninu/apps/jsmdcui/CHANGELOG.md +44 -0
- package/initramfs/buninu/apps/jsmdcui/package.json +1 -1
- package/initramfs/buninu/apps/jsmdcui/src/highlight/go-regexp.js +83 -0
- package/initramfs/buninu/apps/jsmdcui/src/highlight/highlighter.js +49 -62
- package/initramfs/buninu/apps/jsmdcui/src/highlight/parser.js +8 -5
- package/initramfs/buninu/apps/jsmdcui/tests/go-regexp.test.js +98 -0
- package/initramfs/buninu/apps/jsmdcui/tests/heading-ids.test.js +21 -16
- package/initramfs/buninu/apps/jsmdcui/tests/highlight-regions.test.js +73 -0
- package/initramfs/buninu/apps/jsmdcui/tests/id-collision.test.js +32 -9
- package/initramfs/buninu/apps/jsmdcui/tests/markdown-behavior.mjs +9 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/NORMAL-HTML.md +46 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/README.md +85 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/REPORT.md +328 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/compare.mjs +75 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/go.mod +5 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/normal-html-report.json +619 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/normal-html.html +9 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/oracle.go +49 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/report.json +2174 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/PowerShell.txt +39 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ada.txt +25 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/apacheconf.txt +49 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/arduino.txt +38 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/asciidoc.txt +33 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/asm.txt +77 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ats.txt +48 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/awk.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/b.txt +27 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/bat.txt +39 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/c.txt +34 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/caddyfile.txt +14 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cake.txt +7 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/clojure.txt +18 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cmake.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/coffeescript.txt +32 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/colortest.txt +19 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/conky.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cpp.txt +46 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/crontab.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/crystal.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/csharp.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/css.txt +19 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/csx.txt +7 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cuda.txt +37 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cython.txt +22 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/d.txt +52 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dart.txt +27 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/default.txt +8 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dockerfile.txt +10 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dot.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/elixir.txt +23 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/elm.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/erb.txt +32 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/erlang.txt +23 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fish.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/forth.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fortran.txt +40 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/freebsd-kernel.txt +10 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fsharp.txt +27 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gdscript.txt +26 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gemini.txt +11 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gentoo-ebuild.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gentoo-etc-portage.txt +14 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-commit.txt +19 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-config.txt +11 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-rebase-todo.txt +10 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gleam.txt +44 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/glsl.txt +18 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gnuplot.txt +11 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/go.txt +33 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/godoc.txt +9 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/golo.txt +50 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gomod.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/graphql.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/groff.txt +18 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/groovy.txt +42 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/haml.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/hare.txt +31 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/haskell.txt +26 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/hc.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html.txt +26 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html4.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html5.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ini.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/inputrc.txt +14 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/java.txt +18 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/javascript.txt +41 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/jinja2.txt +13 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/json.txt +21 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/jsonnet.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/julia.txt +24 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/justfile.txt +26 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/keymap.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kickstart.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kotlin.txt +30 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kvlang.txt +37 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ledger.txt +13 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lfe.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lilypond.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lisp.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/log.txt +45 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lua.txt +48 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mail.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/makefile.txt +25 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/man.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/markdown.txt +21 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mc.txt +11 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/meson.txt +29 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/micro.txt +25 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mpdconf.txt +13 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/msbuild.txt +7 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nanorc.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nftables.txt +22 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nginx.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nim.txt +23 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nix.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nu.txt +92 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/objc.txt +36 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ocaml.txt +25 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/octave.txt +35 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/odin.txt +35 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pascal.txt +22 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/patch.txt +13 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/peg.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/perl.txt +27 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/php.txt +44 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pkg-config.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/po.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pony.txt +29 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pov.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-action.txt +14 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-config.txt +10 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-filter.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/proto.txt +22 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/prql.txt +42 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/puppet.txt +22 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/python2.txt +24 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/python3.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/r.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/raku.txt +19 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/reST.txt +18 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/renpy.txt +11 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/rpmspec.txt +31 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ruby.txt +34 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/rust.txt +27 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sage.txt +24 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/scad.txt +23 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/scala.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sed.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sh.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sls.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/smalltalk.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/solidity.txt +26 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sql.txt +35 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/stata.txt +32 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/svelte.txt +10 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/swift.txt +53 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/systemd.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/tcl.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/terraform.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/tex.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/toml.txt +31 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/twig.txt +29 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/typescript.txt +32 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/v.txt +47 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vala.txt +22 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/verilog.txt +37 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vhdl.txt +37 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vi.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vue.txt +29 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/xml.txt +14 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/xresources.txt +14 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/yaml.txt +19 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/yum.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zig.txt +24 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zscript.txt +31 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zsh.txt +21 -0
- package/initramfs/buninu/package.json +1 -1
- package/initramfs/init.js +19 -3
- package/initramfs/lib/bunterm/clipboard.js +14 -0
- package/initramfs/lib/bunterm/commands.js +37 -0
- package/initramfs/lib/bunterm/fps.js +38 -0
- package/initramfs/lib/bunterm/images.js +14 -6
- package/initramfs/lib/bunterm/input.js +58 -15
- package/initramfs/lib/bunterm/keyboard.js +62 -0
- package/initramfs/lib/bunterm/keycodes.js +104 -0
- package/initramfs/lib/bunterm/kitty-keyboard.cjs +195 -0
- package/initramfs/lib/bunterm/raw-protocol.js +111 -0
- package/initramfs/lib/bunterm/renderer.js +116 -28
- package/initramfs/lib/bunterm/selection.js +60 -0
- package/initramfs/lib/bunterm/terminal.js +157 -12
- package/initramfs/lib/bunterm/vt-menu.js +181 -0
- package/initramfs/lib/bunterm/vt.js +27 -1
- package/initramfs/lib/canvas.js +99 -0
- package/initramfs/lib/chvt.js +31 -0
- package/initramfs/lib/fbdev.js +32 -8
- package/initramfs/lib/gpu.js +77 -0
- package/initramfs/lib/mapped-frame.js +28 -0
- package/initramfs/lib/raw-image.js +71 -0
- package/initramfs/lib/xdg-open.js +42 -0
- package/initramfs/usr/share/doc/buninu-linux/bunterm.md +85 -11
- package/initramfs/usr/share/doc/buninu-linux/chvt.md +34 -0
- package/initramfs/usr/share/doc/buninu-linux/xdg-open.md +43 -0
- package/package.json +1 -1
- package/scripts/arch.js +7 -5
- package/scripts/arch.sh +5 -5
- package/scripts/build.js +16 -3
- package/scripts/fetch-gpu.js +105 -0
- package/scripts/fetch.js +11 -1
- package/scripts/gpu-firmware.json +22 -0
- package/scripts/modules.js +4 -1
- package/scripts/npm-packages.md +18 -17
- package/test/bunterm-fps.test.js +17 -0
- package/test/bunterm-image-bytes.test.js +15 -0
- package/test/bunterm-keyboard.test.js +116 -0
- package/test/bunterm-mapped-lifetime.test.js +147 -0
- package/test/bunterm-next-vt.test.js +9 -0
- package/test/bunterm-raw-protocol.test.js +39 -0
- package/test/bunterm-renderer.test.js +167 -0
- package/test/bunterm-selection.test.js +38 -0
- package/test/bunterm-vt-menu.test.js +178 -0
- package/test/chroot-bind.test.js +40 -2
- package/test/chvt.test.js +46 -0
- package/test/fbdev-sync.test.js +42 -0
- package/test/fetch-npm.test.js +2 -2
- package/test/gpu.test.js +155 -0
- package/test/image-size.test.js +17 -0
- package/test/manual-bunterm-image-paths.js +31 -0
- package/test/mount-libc-lifetime.test.js +50 -0
- package/test/no-gpu.test.js +43 -0
- package/test/readme-cli.test.js +29 -0
- package/test/stage-npm.test.js +11 -4
- package/test/xdg-open.test.js +55 -0
package/test/gpu.test.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { test, expect, afterEach } from "bun:test";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { configureGpu, framebufferUsers, isGpuPath } from "../initramfs/lib/gpu.js";
|
|
6
|
+
import { extractFirmware, firmwareLinkTarget } from "../scripts/fetch-gpu.js";
|
|
7
|
+
import { readTar } from "../scripts/fetch.js";
|
|
8
|
+
import { requests, select } from "../scripts/modules.js";
|
|
9
|
+
|
|
10
|
+
const dirs = [];
|
|
11
|
+
const temporary = () => { const p = fs.mkdtempSync(join(tmpdir(), "buninu-gpu-test-")); dirs.push(p); return p; };
|
|
12
|
+
afterEach(() => { for (const dir of dirs.splice(0)) fs.rmSync(dir, { recursive: true, force: true }); });
|
|
13
|
+
const archive = (files, links = {}) => ({ entries: () => Object.entries(files).map(([n,b]) => [n, Buffer.from(b)]), links: () => Object.entries(links) });
|
|
14
|
+
const soft = target => ({ target, hard: false });
|
|
15
|
+
|
|
16
|
+
test("firmware preserves directory aliases, cross-package links and hardlinks", () => {
|
|
17
|
+
const root = temporary();
|
|
18
|
+
const files = extractFirmware([
|
|
19
|
+
archive({ "lib/firmware/nvidia/ad102/gsp.bin.zst": "firmware", "lib/firmware/amdgpu/a.bin.zst": "amd" }),
|
|
20
|
+
archive({}, {
|
|
21
|
+
"lib/firmware/nvidia/ad103": soft("ad102"),
|
|
22
|
+
"lib/firmware/nvidia/alias.bin.zst": soft("ad103/gsp.bin.zst"),
|
|
23
|
+
"lib/firmware/radeon/alias.bin.zst": soft("../amdgpu/a.bin.zst"),
|
|
24
|
+
"lib/firmware/nvidia/hard.bin.zst": { target: "lib/firmware/nvidia/ad102/gsp.bin.zst", hard: true },
|
|
25
|
+
}),
|
|
26
|
+
], root);
|
|
27
|
+
expect(files).toHaveLength(6);
|
|
28
|
+
expect(fs.readFileSync(join(root, "lib/firmware/nvidia/ad103/gsp.bin.zst"), "utf8")).toBe("firmware");
|
|
29
|
+
expect(fs.readFileSync(join(root, "lib/firmware/nvidia/alias.bin.zst"), "utf8")).toBe("firmware");
|
|
30
|
+
expect(fs.readFileSync(join(root, "lib/firmware/nvidia/hard.bin.zst"), "utf8")).toBe("firmware");
|
|
31
|
+
expect(fs.readFileSync(join(root, "lib/firmware/radeon/alias.bin.zst"), "utf8")).toBe("amd");
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("firmware rejects escaping, missing and cyclic links before extraction", () => {
|
|
35
|
+
for (const target of ["/etc/passwd", "../../../etc/passwd", "..\\etc\\passwd"])
|
|
36
|
+
expect(() => firmwareLinkTarget("lib/firmware/nvidia/x", soft(target))).toThrow();
|
|
37
|
+
for (const links of [
|
|
38
|
+
{ "lib/firmware/a": soft("missing") },
|
|
39
|
+
{ "lib/firmware/a": soft("b"), "lib/firmware/b": soft("a") },
|
|
40
|
+
{ "lib/firmware/a": soft("a/child") },
|
|
41
|
+
]) expect(() => extractFirmware([archive({}, links)], temporary())).toThrow();
|
|
42
|
+
expect(() => extractFirmware([archive({"lib/firmware/../../escape": "bad"})], temporary())).toThrow();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test.skipIf(!Bun.which("tar"))("APK tar reader retains GNU long symlinks and hardlinks", () => {
|
|
46
|
+
const root = temporary(), tree = join(root, "tree"); fs.mkdirSync(tree);
|
|
47
|
+
const name = "x".repeat(120);
|
|
48
|
+
fs.writeFileSync(join(tree, name), "firmware");
|
|
49
|
+
fs.linkSync(join(tree, name), join(tree, "hard"));
|
|
50
|
+
fs.symlinkSync(name, join(tree, "alias"));
|
|
51
|
+
const pkg = join(root, "package.tar.gz");
|
|
52
|
+
expect(Bun.spawnSync(["tar", "--format=gnu", "-czf", pkg, "-C", tree, name, "hard", "alias"]).exitCode).toBe(0);
|
|
53
|
+
const tar = readTar(pkg), links = new Map(tar.links());
|
|
54
|
+
expect(tar.get(name).toString()).toBe("firmware");
|
|
55
|
+
expect(links.get("alias")).toEqual({ target: name, hard: false });
|
|
56
|
+
expect(links.get("hard")).toEqual({ target: name, hard: true });
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const runtime = () => {
|
|
60
|
+
const root = temporary(), calls = [], logs = [];
|
|
61
|
+
fs.mkdirSync(join(root, "proc/1/fd"), { recursive:true });
|
|
62
|
+
fs.writeFileSync(join(root, "proc/1/maps"), "");
|
|
63
|
+
fs.mkdirSync(join(root, "dev/dri"), { recursive:true });
|
|
64
|
+
fs.writeFileSync(join(root, "dev/dri/renderD129"), "node");
|
|
65
|
+
fs.writeFileSync(join(root, "dev/fb0"), "node");
|
|
66
|
+
const io = {...fs,
|
|
67
|
+
statSync: path => path.includes("renderD") ? { isCharacterDevice: () => true } : fs.statSync(path),
|
|
68
|
+
chownSync: (path, uid, gid) => calls.push(["chown", uid, gid]),
|
|
69
|
+
chmodSync: (path, mode) => calls.push(["chmod", mode]),
|
|
70
|
+
};
|
|
71
|
+
const options = { root, io, env: {}, log: s => logs.push(s),
|
|
72
|
+
tryModprobe: name => calls.push(["transport", name]),
|
|
73
|
+
autoload: options => {
|
|
74
|
+
const candidates = [ ["amdgpu", "kernel/drivers/gpu/drm/amd/amdgpu/amdgpu.ko"], ["simpledrm", "kernel/drivers/gpu/drm/sysfb/simpledrm.ko"], ["e1000", "kernel/drivers/net/e1000.ko"] ];
|
|
75
|
+
const modules = candidates.filter(x => options.acceptModule(...x)).map(x => x[0]);
|
|
76
|
+
calls.push(["autoload", modules]);
|
|
77
|
+
return [{ bus:"pci", device:"0000:01:00.0", modules, loaded:modules, error:null }];
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
return { root, calls, logs, options };
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
test("cfg.gpu matches only GPU leaf drivers and configures actual render node names", () => {
|
|
84
|
+
const { options, calls } = runtime(); options.env.BUNINU_RENDER_GID = "107";
|
|
85
|
+
const result = configureGpu(options);
|
|
86
|
+
expect(result.errors).toEqual([]);
|
|
87
|
+
expect(result.renderNodes).toEqual([{path:"/dev/dri/renderD129", driver:"unknown", gid:107}]);
|
|
88
|
+
expect(calls).toContainEqual(["autoload", ["amdgpu"]]);
|
|
89
|
+
expect(calls).toContainEqual(["chown", 0, 107]);
|
|
90
|
+
expect(calls).toContainEqual(["chmod", 0o660]);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test("virtio render nodes report the GPU child driver rather than the PCI transport", () => {
|
|
94
|
+
const { root, options } = runtime();
|
|
95
|
+
const device = join(root, "sys/class/drm/renderD129/device");
|
|
96
|
+
fs.mkdirSync(join(device, "virtio0"), {recursive:true});
|
|
97
|
+
fs.symlinkSync("/sys/bus/pci/drivers/virtio-pci", join(device, "driver"));
|
|
98
|
+
fs.symlinkSync("/sys/bus/virtio/drivers/virtio_gpu", join(device, "virtio0/driver"));
|
|
99
|
+
expect(configureGpu(options).renderNodes[0].driver).toBe("virtio_gpu");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("no matching GPU and no render node is diagnosed without claiming acceleration", () => {
|
|
103
|
+
const { root, options, logs } = runtime();
|
|
104
|
+
fs.unlinkSync(join(root, "dev/dri/renderD129"));
|
|
105
|
+
options.autoload = () => [];
|
|
106
|
+
const result = configureGpu(options);
|
|
107
|
+
expect(result.errors).toEqual([]);
|
|
108
|
+
expect(result.renderNodes).toEqual([]);
|
|
109
|
+
expect(logs.some(s=>s.includes("no accessible render node"))).toBe(true);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("framebuffer fd or surviving mmap prevents GPU takeover before loading anything", () => {
|
|
113
|
+
for (const mapped of [false, true]) {
|
|
114
|
+
const { root, options, calls } = runtime();
|
|
115
|
+
if (mapped) fs.writeFileSync(join(root, "proc/1/maps"), "abc-def rw-s 00000000 00:01 3 /dev/fb0\n");
|
|
116
|
+
else fs.symlinkSync("/dev/fb0", join(root, "proc/1/fd/4"));
|
|
117
|
+
expect(framebufferUsers(options)).toEqual(["1"]);
|
|
118
|
+
expect(configureGpu(options).blocked).toBe(true);
|
|
119
|
+
expect(calls).toEqual([]);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("missing hardware, driver failure and invalid permissions do not escape cfg.gpu", () => {
|
|
124
|
+
const { options, calls } = runtime();
|
|
125
|
+
options.env.BUNINU_RENDER_GID = "bad";
|
|
126
|
+
expect(configureGpu(options).errors.length).toBe(1); expect(calls).toEqual([]);
|
|
127
|
+
options.env = {};
|
|
128
|
+
options.autoload = () => { throw Error("driver failed"); };
|
|
129
|
+
expect(configureGpu(options).errors).toEqual(["driver failed"]);
|
|
130
|
+
options.autoload = () => []; options.io.chownSync = () => { throw Error("permission denied"); };
|
|
131
|
+
expect(configureGpu(options).errors[0]).toContain("permission denied");
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test("cfg.all's actual loader excludes GPU modules and still loads network/sound", () => {
|
|
135
|
+
const source = fs.readFileSync(new URL("../initramfs/init.js", import.meta.url), "utf8");
|
|
136
|
+
const body = source.match(/const configureModules = \(\) => \{([\s\S]*?)\n\};/)[1];
|
|
137
|
+
const chosen = [];
|
|
138
|
+
const require = () => ({ isGpuPath, modprobeAll: ({accept}) => {
|
|
139
|
+
for (const path of ["kernel/drivers/gpu/drm/amd/amdgpu/amdgpu.ko", "kernel/drivers/net/e1000.ko", "kernel/sound/snd.ko"])
|
|
140
|
+
if (accept("",path)) chosen.push(path);
|
|
141
|
+
return {inserted:chosen,errors:[]};
|
|
142
|
+
}});
|
|
143
|
+
new Function("require", "console", body)(require, {log(){}});
|
|
144
|
+
expect(chosen).toEqual(["kernel/drivers/net/e1000.ko", "kernel/sound/snd.ko"]);
|
|
145
|
+
expect(source).toContain("gpu: { enumerable: true, get: configureGraphics }");
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("GPU leaves are optional for kernels without them and their dependencies are selected", () => {
|
|
149
|
+
const target = {arch:"x86_64",flavor:"lts",real:false};
|
|
150
|
+
const dep = requests(target).filter(x=>!x.optional).map(({name})=>`kernel/${name}.ko.gz:`);
|
|
151
|
+
dep.push("kernel/drivers/gpu/drm/amd/amdgpu/amdgpu.ko.gz: kernel/drivers/gpu/drm/ttm/ttm.ko.gz", "kernel/drivers/gpu/drm/ttm/ttm.ko.gz:");
|
|
152
|
+
const result = select({...target,dep:dep.join("\n"),builtin:"",packageName:"test"});
|
|
153
|
+
expect(result.selected).toContain("kernel/drivers/gpu/drm/ttm/ttm.ko.gz");
|
|
154
|
+
expect(result.notes.some(x=>x.includes("i915"))).toBe(true);
|
|
155
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { test, expect } from "bun:test";
|
|
2
|
+
import { imageBytes } from "../scripts/build.js";
|
|
3
|
+
import { layout } from "../initramfs/lib/fat.js";
|
|
4
|
+
const MiB = 1024 * 1024;
|
|
5
|
+
test("image sizing preserves small images and fits GPU firmware payloads plus FAT metadata", () => {
|
|
6
|
+
expect(imageBytes(80 * MiB)).toBe(128 * MiB);
|
|
7
|
+
// Actual no-gpu EFI: the former 16 MiB reserve incorrectly made this 192 MiB.
|
|
8
|
+
expect(imageBytes(113646592)).toBe(128 * MiB);
|
|
9
|
+
expect(imageBytes(266 * MiB)).toBe(320 * MiB);
|
|
10
|
+
for (const payload of [0, 100 * MiB, 120 * MiB, 240 * MiB, 266 * MiB, 512 * MiB, 0xffffffff]) {
|
|
11
|
+
const size = imageBytes(payload);
|
|
12
|
+
const geometry = layout(size / 512 - 34 - 2048 + 1);
|
|
13
|
+
expect((geometry.clusters - 3) * geometry.perCluster * 512).toBeGreaterThan(payload);
|
|
14
|
+
expect(size % (64 * MiB)).toBe(0);
|
|
15
|
+
}
|
|
16
|
+
expect(() => imageBytes(0x100000000)).toThrow("FAT32");
|
|
17
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {runGraphics} from '/lib/fbdev.js';
|
|
2
|
+
import {loadCanvasKit,openCanvas} from '/lib/canvas.js';
|
|
3
|
+
import {claimVirtualConsole} from '/lib/bunterm/vt.js';
|
|
4
|
+
// Manual native Linux benchmark; takes over tty6 temporarily.
|
|
5
|
+
// bun test/manual-bunterm-image-paths.js /path/to/1920x1080.png
|
|
6
|
+
if(!process.argv[2])throw Error('Pass a 1920x1080 PNG filename');
|
|
7
|
+
const CK=await loadCanvasKit(), results=[];
|
|
8
|
+
await runGraphics(async(display,{onRelease,onAcquire})=>{
|
|
9
|
+
const screen=openCanvas(CK,display);let active=true;onRelease(()=>active=false);onAcquire(()=>active=true);
|
|
10
|
+
const bytes=await Bun.file(process.argv[2]).bytes();
|
|
11
|
+
const image=CK.MakeImageFromEncoded(bytes),w=image.width(),h=image.height();
|
|
12
|
+
if(w!==1920||h!==1080||display.width!==1920||display.height!==1080||display.bitsPerPixel!==32)throw Error("This comparison requires a 1920x1080 image and 32-bit 1920x1080 framebuffer");
|
|
13
|
+
const src=CK.LTRBRect(0,0,w,h), native=CK.LTRBRect(0,0,w,h),scaled=CK.LTRBRect(0,26,1920,1066);
|
|
14
|
+
const info={width:w,height:h,colorType:CK.ColorType.RGBA_8888,alphaType:CK.AlphaType.Unpremul,colorSpace:CK.ColorSpace.SRGB};
|
|
15
|
+
const start=performance.now(),pixels=image.readPixels(0,0,info);
|
|
16
|
+
if(!pixels)throw Error('readPixels failed');
|
|
17
|
+
if(screen.colorType===CK.ColorType.BGRA_8888)for(let i=0;i<pixels.length;i+=4){const r=pixels[i];pixels[i]=pixels[i+2];pixels[i+2]=r;}results.push({readPixelsMs:performance.now()-start,width:w,height:h,bytes:pixels?.length});
|
|
18
|
+
const actions={
|
|
19
|
+
'rows-scaled':()=>{for(let y=0;y<1080;y+=26){screen.canvas.save();screen.canvas.clipRect(CK.LTRBRect(0,y,1920,Math.min(1080,y+26)),CK.ClipOp.Intersect,false);screen.canvas.drawImageRectOptions(image,src,scaled,CK.FilterMode.Linear,CK.MipmapMode.Linear,null);screen.canvas.restore();}},
|
|
20
|
+
'single-scaled':()=>screen.canvas.drawImageRectOptions(image,src,scaled,CK.FilterMode.Linear,CK.MipmapMode.Linear,null),
|
|
21
|
+
'single-1to1':()=>screen.canvas.drawImageRectOptions(image,src,native,CK.FilterMode.Linear,CK.MipmapMode.Linear,null),
|
|
22
|
+
'drawImage-1to1':()=>screen.canvas.drawImage(image,0,0),
|
|
23
|
+
'decode-copy-1to1':()=>{const fresh=CK.MakeImageFromEncoded(bytes);try{const p=fresh.readPixels(0,0,info);if(!p)throw Error('decode failed');if(screen.colorType===CK.ColorType.BGRA_8888)for(let i=0;i<p.length;i+=4){const r=p[i];p[i]=p[i+2];p[i+2]=r;}screen.restoreRegion({x:0,y:0,height:Math.min(h,1080),rowBytes:w*4,pixels:p});}finally{fresh.delete();}},
|
|
24
|
+
'copy-1to1':()=>screen.restoreRegion({x:0,y:0,height:Math.min(h,1080),rowBytes:w*4,pixels}),
|
|
25
|
+
};
|
|
26
|
+
try {for(const [name,draw] of Object.entries(actions)){
|
|
27
|
+
screen.canvas.clear(CK.BLACK);draw();screen.flush();
|
|
28
|
+
const t=performance.now();let count=0,total=0;while(performance.now()-t<2500){if(!active)throw Error('VT switched');const t0=performance.now();draw();screen.flush();total+=performance.now()-t0;count++;await Bun.sleep(16);}
|
|
29
|
+
results.push({name,ms:total/count,count});await Bun.write('/tmp/bunterm-image-paths.json',JSON.stringify(results,null,2));
|
|
30
|
+
}}finally{image.delete();screen.close();}
|
|
31
|
+
},{console:['/dev/tty6'],prepareConsole:claimVirtualConsole});process.exit(0);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {test,expect} from 'bun:test';
|
|
2
|
+
import {mkdtempSync,writeFileSync,readFileSync,rmSync} from 'node:fs';
|
|
3
|
+
import {tmpdir} from 'node:os';
|
|
4
|
+
import {join} from 'node:path';
|
|
5
|
+
|
|
6
|
+
// Run the real command with a libc whose path disappears after the first
|
|
7
|
+
// successful mount change. Never mount or unmount anything on the host.
|
|
8
|
+
async function invoke(name,args){
|
|
9
|
+
const dir=mkdtempSync(join(tmpdir(),'buninu-mount-libc-'));
|
|
10
|
+
const mock=join(dir,'libc.mjs');
|
|
11
|
+
writeFileSync(mock,`
|
|
12
|
+
let hidden=false;
|
|
13
|
+
const bound=new Map();
|
|
14
|
+
const functions={mount:()=>{if(hidden)return -1;hidden=true;return 0;},
|
|
15
|
+
umount2:()=>{if(hidden)return -1;hidden=true;return 0;},
|
|
16
|
+
errno:()=>5,strerror:()=> 'mock I/O error'};
|
|
17
|
+
export const libc={symbols:new Proxy({}, {get(_target,name){
|
|
18
|
+
if(!bound.has(name)){
|
|
19
|
+
if(hidden)throw Error('Cannot load libc symbol '+name);
|
|
20
|
+
bound.set(name,functions[name]);
|
|
21
|
+
}
|
|
22
|
+
return bound.get(name);
|
|
23
|
+
}})};
|
|
24
|
+
export const ptr=x=>x,cString=x=>x,errno=()=>libc.symbols.errno(),
|
|
25
|
+
strerror=code=>libc.symbols.strerror(code),Errno={},SysError=class extends Error{};
|
|
26
|
+
`);
|
|
27
|
+
const source=readFileSync(new URL('../initramfs/bin/'+name,import.meta.url),'utf8')
|
|
28
|
+
.replace('"../lib/dlopen.js"',JSON.stringify(mock))
|
|
29
|
+
.replace('import { showDocument } from "../lib/document.js";','const showDocument=async()=>{};')
|
|
30
|
+
.replace('import { modprobe, tryModprobe, modulesDirectory, ModuleNotFound } from "../lib/modprobe.js";',
|
|
31
|
+
'const modprobe=()=>[],tryModprobe=()=>[],modulesDirectory=()=>"";class ModuleNotFound extends Error{}');
|
|
32
|
+
const entry=join(dir,'command.mjs');writeFileSync(entry,source);
|
|
33
|
+
try{
|
|
34
|
+
const child=Bun.spawn([process.execPath,entry,...args],{stdout:'pipe',stderr:'pipe'});
|
|
35
|
+
const stderr=new Response(child.stderr).text();
|
|
36
|
+
return {status:await child.exited,stderr:await stderr};
|
|
37
|
+
}finally{rmSync(dir,{recursive:true,force:true});}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
test('read-only bind reports remount failure after the libc path is hidden',async()=>{
|
|
41
|
+
const r=await invoke('mount',['--bind','-o','ro','/fake-source','/fake-target']);
|
|
42
|
+
expect(r.status).toBe(32);expect(r.stderr).toContain('mount: mock I/O error');
|
|
43
|
+
expect(r.stderr).not.toContain('Cannot load libc symbol');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('later unmount failure reports strerror after an earlier target hides libc',async()=>{
|
|
47
|
+
const r=await invoke('umount',['/fake-lib','/fake-missing']);
|
|
48
|
+
expect(r.status).toBe(32);expect(r.stderr).toContain('umount: /fake-missing: mock I/O error.');
|
|
49
|
+
expect(r.stderr).not.toContain('Cannot load libc symbol');
|
|
50
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {test,expect} from "bun:test";
|
|
2
|
+
import {mkdtempSync,mkdirSync,writeFileSync,existsSync,rmSync} from "node:fs";
|
|
3
|
+
import {tmpdir} from "node:os";
|
|
4
|
+
import {join} from "node:path";
|
|
5
|
+
import {requests,select} from "../scripts/modules.js";
|
|
6
|
+
import {config} from "../scripts/arch.js";
|
|
7
|
+
import {fetchGpuFirmware,gpuReady} from "../scripts/fetch-gpu.js";
|
|
8
|
+
const additions=new Set(["virtio-gpu","vmwgfx","i915","xe","amdgpu","radeon","nouveau"]);
|
|
9
|
+
test("no-gpu only removes new explicit requests across target configurations",()=>{
|
|
10
|
+
for(const arch of ["x86_64","aarch64"])for(const flavor of ["lts","virt"])for(const real of [true,false]){
|
|
11
|
+
const cfg={arch,flavor,real};
|
|
12
|
+
expect(requests({...cfg,noGpu:true})).toEqual(requests(cfg).filter(r=>!additions.has(r.name)));
|
|
13
|
+
}
|
|
14
|
+
expect(config({noGpu:true}).noGpu).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
test("no-gpu retains a GPU-directory dependency when an original module needs it",()=>{
|
|
17
|
+
const cfg={arch:"x86_64",flavor:"lts",real:false,noGpu:true};
|
|
18
|
+
const dep=requests(cfg).map(({name})=>`kernel/test/${name}.ko.gz:${name==="snd-hda-intel"?" kernel/drivers/gpu/drm/shared.ko.gz":""}`).join("\n")+"\nkernel/drivers/gpu/drm/shared.ko.gz:";
|
|
19
|
+
expect(select({...cfg,dep,builtin:"",packageName:"test"}).selected).toContain("kernel/drivers/gpu/drm/shared.ko.gz");
|
|
20
|
+
});
|
|
21
|
+
test("no-gpu clears generated firmware and caches cannot cross GPU modes",async()=>{
|
|
22
|
+
const root=mkdtempSync(join(tmpdir(),"no-gpu-"));
|
|
23
|
+
try{
|
|
24
|
+
const cfg={...config({arch:"x86_64",flavor:"lts",real:true,noGpu:true}),nativeDir:root,modulesRoot:join(root,"modules")};
|
|
25
|
+
mkdirSync(cfg.modulesRoot,{recursive:true});
|
|
26
|
+
writeFileSync(join(cfg.modulesRoot,"modules.dep"),"");
|
|
27
|
+
writeFileSync(join(cfg.modulesRoot,"modules.builtin"),"kernel/drivers/gpu/drm/i915/i915.ko\n");
|
|
28
|
+
mkdirSync(join(root,"lib/firmware"),{recursive:true});
|
|
29
|
+
writeFileSync(join(root,"lib/firmware/stale"),"old firmware");
|
|
30
|
+
await fetchGpuFirmware(cfg);
|
|
31
|
+
expect(existsSync(join(root,"lib/firmware"))).toBe(false);
|
|
32
|
+
expect(gpuReady(cfg)).toBe(true);
|
|
33
|
+
expect(gpuReady({...cfg,noGpu:false})).toBe(false);
|
|
34
|
+
mkdirSync(join(root,"lib/firmware"));
|
|
35
|
+
expect(gpuReady(cfg)).toBe(false);
|
|
36
|
+
}finally{rmSync(root,{recursive:true,force:true});}
|
|
37
|
+
});
|
|
38
|
+
test("launcher documents no-gpu and rejects it without fetch/build",()=>{
|
|
39
|
+
const help=Bun.spawnSync([process.execPath,"index.js","--help"]);
|
|
40
|
+
expect(help.exitCode).toBe(0);expect(help.stdout.toString()).toContain("--no-gpu");
|
|
41
|
+
const invalid=Bun.spawnSync([process.execPath,"index.js","-r","--no-gpu"]);
|
|
42
|
+
expect(invalid.exitCode).not.toBe(0);expect(invalid.stderr.toString()).toContain("only make sense");
|
|
43
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { expect, test } from "bun:test";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
|
|
4
|
+
const entry = fileURLToPath(new URL("../index.js", import.meta.url));
|
|
5
|
+
|
|
6
|
+
for (const [flag, filename] of [
|
|
7
|
+
["--readme", "README.md"],
|
|
8
|
+
["--readme-zh", "README.zh.md"],
|
|
9
|
+
["--docs", "README.zh.md"],
|
|
10
|
+
]) {
|
|
11
|
+
test(`${flag} flushes the complete document to a pipe before exiting`, async () => {
|
|
12
|
+
const markdown = await Bun.file(new URL(`../${filename}`, import.meta.url)).text();
|
|
13
|
+
const rendered = Bun.markdown.ansi(markdown, { hyperlinks: true });
|
|
14
|
+
const expected = rendered.endsWith("\n") ? rendered : `${rendered}\n`;
|
|
15
|
+
// Both real documents exceed the pipe chunk that was previously truncated.
|
|
16
|
+
expect(Buffer.byteLength(expected)).toBeGreaterThan(65536);
|
|
17
|
+
const child = Bun.spawn([process.execPath, entry, flag], {
|
|
18
|
+
stdout: "pipe", stderr: "pipe",
|
|
19
|
+
});
|
|
20
|
+
const [output, errors, status] = await Promise.all([
|
|
21
|
+
new Response(child.stdout).text(),
|
|
22
|
+
new Response(child.stderr).text(),
|
|
23
|
+
child.exited,
|
|
24
|
+
]);
|
|
25
|
+
expect(status).toBe(0);
|
|
26
|
+
expect(errors).toBe("");
|
|
27
|
+
expect(output).toBe(expected);
|
|
28
|
+
});
|
|
29
|
+
}
|
package/test/stage-npm.test.js
CHANGED
|
@@ -101,9 +101,16 @@ test("distribution launcher ensures resources then forwards to local casty witho
|
|
|
101
101
|
`);
|
|
102
102
|
writeFileSync(join(root, "usr/lib/node_modules/@drxiaozhi/casty/index.js"),
|
|
103
103
|
"console.log(JSON.stringify({args:process.argv.slice(2),engine:process.env.CASTY_BROWSER}));");
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
for (const args of [
|
|
105
|
+
["https://example.test", "--", "--chromium"],
|
|
106
|
+
["--", "--help"],
|
|
107
|
+
["--", "--version"],
|
|
108
|
+
["--", "--window-size=160,90"],
|
|
109
|
+
]) {
|
|
110
|
+
const result = spawnSync(process.execPath, [join(root, "bin/buninu-browser"), "--casty", ...args], { encoding: "utf8" });
|
|
111
|
+
expect(result.status).toBe(0);
|
|
112
|
+
expect(JSON.parse(result.stdout)).toEqual({ args, engine: join(browser, "buninu-browser.js") });
|
|
113
|
+
}
|
|
107
114
|
});
|
|
108
115
|
|
|
109
116
|
test("land launcher selects bundled casty and preserves package frontend dispatch", async () => {
|
|
@@ -130,7 +137,7 @@ test("land launcher selects bundled casty and preserves package frontend dispatc
|
|
|
130
137
|
});
|
|
131
138
|
expect(result.status).toBe(0);
|
|
132
139
|
expect(JSON.parse(result.stdout)).toEqual({
|
|
133
|
-
args: args[0] === '--casty' ? args.slice(1) : args,
|
|
140
|
+
args: ['--no-shortcuts', ...(args[0] === '--casty' ? args.slice(1) : args)],
|
|
134
141
|
engine: join(land, "compositor.js"),
|
|
135
142
|
});
|
|
136
143
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {afterAll, expect, test} from 'bun:test';
|
|
2
|
+
import {mkdtempSync,writeFileSync,symlinkSync,rmSync,chmodSync} from 'node:fs';
|
|
3
|
+
import {tmpdir} from 'node:os';
|
|
4
|
+
import {join} from 'node:path';
|
|
5
|
+
import {pathToFileURL} from 'node:url';
|
|
6
|
+
import {browserTarget,parseOpenArgs} from '../initramfs/lib/xdg-open.js';
|
|
7
|
+
const dir=mkdtempSync(join(tmpdir(),'buninu-xdg-open-'));
|
|
8
|
+
afterAll(()=>rmSync(dir,{recursive:true,force:true}));
|
|
9
|
+
const file=join(dir,'中文 # %.html');writeFileSync(file,'<p>test</p>');
|
|
10
|
+
symlinkSync(file,join(dir,'alias.html'));
|
|
11
|
+
test('HTTP and HTTPS remain browser URLs',()=>{
|
|
12
|
+
expect(browserTarget('https://buninu.org/path?q=one#two')).toBe('https://buninu.org/path?q=one#two');
|
|
13
|
+
expect(browserTarget('http://localhost:8080')).toBe('http://localhost:8080/');
|
|
14
|
+
expect(()=>browserTarget('http://')).toThrow();
|
|
15
|
+
});
|
|
16
|
+
test('local files resolve symlinks and escape URL-special characters',()=>{
|
|
17
|
+
expect(browserTarget('alias.html',dir)).toBe(pathToFileURL(file).href);
|
|
18
|
+
expect(browserTarget(pathToFileURL(file).href)).toBe(pathToFileURL(file).href);
|
|
19
|
+
expect(()=>browserTarget('missing',dir)).toThrow();
|
|
20
|
+
expect(()=>browserTarget(dir)).toThrow('regular file');
|
|
21
|
+
expect(()=>browserTarget('javascript:alert(1)')).toThrow('Unsupported');
|
|
22
|
+
expect(()=>browserTarget('mailto:test@example.com')).toThrow('Unsupported');
|
|
23
|
+
});
|
|
24
|
+
test('argument validation',()=>{
|
|
25
|
+
expect(parseOpenArgs(['--help'])).toEqual({help:true});
|
|
26
|
+
expect(()=>parseOpenArgs([])).toThrow('Usage');
|
|
27
|
+
expect(()=>parseOpenArgs(['a','b'])).toThrow('Usage');
|
|
28
|
+
});
|
|
29
|
+
test('launcher passes a single URL argument to a new bunterm and maps launch failure to status 4',async()=>{
|
|
30
|
+
const stub=join(dir,'bunterm');writeFileSync(stub,`#!${process.execPath}\nconsole.log(JSON.stringify(process.argv.slice(2)));process.exit(7);`);chmodSync(stub,0o755);
|
|
31
|
+
const browser=join(dir,'buninu-browser');writeFileSync(browser,'#!/bin/sh\nexit 0');chmodSync(browser,0o755);
|
|
32
|
+
const url='https://example.test/?q=$(touch%20bad)&x=1';
|
|
33
|
+
const p=Bun.spawn([process.execPath,new URL('../initramfs/bin/xdg-open',import.meta.url).pathname,url],{env:{...process.env,PATH:dir+':'+process.env.PATH},stdout:'pipe',stderr:'pipe'});
|
|
34
|
+
expect(await p.exited).toBe(4);
|
|
35
|
+
expect(JSON.parse(await new Response(p.stdout).text())).toEqual(['-e','buninu-browser',url]);
|
|
36
|
+
expect(await new Response(p.stderr).text()).toBe('');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('about URLs pass through; Markdown remains a browser file URL',()=>{
|
|
40
|
+
for(const url of ['about:blank','about:audio','about:custom?x=1#part'])
|
|
41
|
+
expect(browserTarget(url)).toBe(url);
|
|
42
|
+
const markdown=join(dir,'note.md');writeFileSync(markdown,'# Note');
|
|
43
|
+
expect(browserTarget(markdown)).toBe(pathToFileURL(markdown).href);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('manual aliases, version and standard failure codes work through the command',async()=>{
|
|
47
|
+
const run=async args=>{const p=Bun.spawn([process.execPath,new URL('../initramfs/bin/xdg-open',import.meta.url).pathname,...args],{env:{...process.env,PATH:'/nonexistent'},stdout:'pipe',stderr:'pipe'});return {code:await p.exited,out:await new Response(p.stdout).text()}};
|
|
48
|
+
for(const flag of ['-h','--help','--manual']){const r=await run([flag]);expect(r.code).toBe(0);expect(r.out).toContain('Exit codes');}
|
|
49
|
+
const v=await run(['--version']);expect(v.code).toBe(0);expect(v.out).toContain('xdg-open (Buninu Linux)');
|
|
50
|
+
expect((await run([])).code).toBe(1);
|
|
51
|
+
expect((await run(['http://'])).code).toBe(1);
|
|
52
|
+
expect((await run([join(dir,'absent')])).code).toBe(2);
|
|
53
|
+
expect((await run(['https://buninu.org'])).code).toBe(3);
|
|
54
|
+
expect((await run(['mailto:a@example.com'])).code).toBe(4);
|
|
55
|
+
});
|