nix

configuration files that power my machines
Log | Files | Refs | README | LICENSE

commit 2daced25baec9fe9c60548dd4437db6ab9d84dec
parent 6679c317a86c1bfa293499892be11495ace8aca9
Author: mtmn <miro@haravara.org>
Date:   Mon,  6 Jul 2026 10:37:10 +0200

void: fix otterb

Diffstat:
Ahosts/void/overlays/bin/otterb | 216+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dhosts/void/overlays/bin/xbps-otterb-build | 212-------------------------------------------------------------------------------
2 files changed, 216 insertions(+), 212 deletions(-)

diff --git a/hosts/void/overlays/bin/otterb b/hosts/void/overlays/bin/otterb @@ -0,0 +1,216 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require "fileutils" +require "open3" +require "etc" + +class Builder + REPO = "https://repo-default.voidlinux.org/current" + DEPS = %w[ + cmake + make + gcc + qt5-devel + qt5-svg-devel + qt5-multimedia-devel + qt5-declarative-devel + qt5-webengine + qt5-webengine-devel + qt5-webkit-devel + qt5-webchannel-devel + qt5-location-devel + hunspell-devel + gstreamer1-devel + libxml2-devel + qt5-tools + ] + .freeze + + def initialize(argv) + @outdir = nil + @chroot = "/var/chroot/otter-build" + @keep = false + @quiet = false + parse(argv) + validate + end + + def run + bootstrap + mount_vfs + prep_chroot + install_deps + build + extract + ensure + unmount_vfs + remove_chroot unless @keep + msg("done.") + end + + private + + def parse(argv) + i = 0 + while i < argv.length + case argv[i] + when "-o" + @outdir = argv[i += 1] + when "-c" + @chroot = argv[i += 1] + when "-k" + @keep = true + when "-q" + @quiet = true + when "-h", "--help" + usage(code: 0) + else + usage + end + + i += 1 + end + end + + def usage_lines + [ + "Usage: #{File.basename($0)} [-o DIR] [-c DIR] [-k] [-q]", + " -o DIR output directory (default: invoking user home)", + " -c DIR chroot directory (default: /var/chroot/otter-build)", + " -k keep chroot after build", + " -q quiet" + ] + end + + def usage(code: 1) + usage_lines.each { |l| puts(l) } + exit(code) + end + + def validate + unless Process.uid.zero? + usage_lines.each { |l| puts(l) } + die("must run as root") + end + + @src = Dir.pwd + die("no CMakeLists.txt in #{@src}") unless File.file?(File.join(@src, "CMakeLists.txt")) + + inv = ENV["SUDO_USER"] || ENV["DOAS_USER"] + if inv + @pw = Etc.getpwnam(inv) rescue nil + die("cannot resolve user #{inv}") unless @pw + @outdir ||= @pw.dir + else + @outdir ||= File.expand_path("~") + end + end + + def msg(s) = puts(s) unless @quiet + + def die(s) + $stderr.puts("#{File.basename($0)}: #{s}") + exit(1) + end + + def run_cmd(cmd, fatal: true) + msg(cmd) + _o, e, st = Open3.capture3(cmd) + die("#{cmd}: #{e.strip}") if !st.success? && fatal + st.success? + end + + def chroot_cmd(script) + msg("chroot #{@chroot} /bin/bash -c '#{script}'") + die("chroot command failed") unless system("chroot #{@chroot} /bin/bash -c '#{script}'") + end + + def bootstrap + FileUtils.mkdir_p(@chroot) + return if File.executable?(File.join(@chroot, "bin/bash")) + + msg("bootstrapping chroot...") + kdir = File.join(@chroot, "var/db/xbps/keys") + FileUtils.mkdir_p(kdir) + Dir.glob("/var/db/xbps/keys/*").each { |f| FileUtils.cp(f, kdir) } + + run_cmd("xbps-install -Syu -R #{REPO} -r #{@chroot} base-voidstrap", fatal: false) + die("bootstrap failed") unless File.executable?(File.join(@chroot, "bin/bash")) + msg("bootstrap ok") + end + + def mount_vfs + mounts = { + File.join(@chroot, "proc") => ["-t", "proc", "proc"], + File.join(@chroot, "sys") => ["-t", "sysfs", "sys"], + File.join(@chroot, "dev") => ["--bind", "/dev"] + } + mounts.each do |dst, opts| + FileUtils.mkdir_p(dst) + next if system("mountpoint -q #{dst} 2>/dev/null") + system("mount #{opts.join(" ")} #{dst}") + end + end + + def unmount_vfs + %w[dev sys proc].each { |n| system("umount #{File.join(@chroot, n)} 2>/dev/null") } + end + + def prep_chroot + FileUtils.cp("/etc/resolv.conf", File.join(@chroot, "etc/resolv.conf")) + kdir = File.join(@chroot, "var/db/xbps/keys") + FileUtils.mkdir_p(kdir) + Dir.glob("/var/db/xbps/keys/*").each { |f| FileUtils.cp(f, kdir) } + end + + def install_deps + chroot_cmd("xbps-install -Syu") + chroot_cmd("xbps-install -S #{DEPS.join(" ")}") + end + + def build + dst = File.join(@chroot, "src/otter-browser") + FileUtils.rm_rf(dst) + FileUtils.mkdir_p(File.dirname(dst)) + system("cp -a #{@src} #{dst}") || die("copy failed") + + cm = File.join(dst, "CMakeLists.txt") + txt = File.read(cm) + unless txt.include?("FATAL_ON_MISSING_REQUIRED_PACKAGES") + die("CMakeLists.txt: FATAL_ON_MISSING_REQUIRED_PACKAGES not found") + end + + txt.gsub!("FATAL_ON_MISSING_REQUIRED_PACKAGES", "") + File.write(cm, txt) + + script = "set -e; cd /src/otter-browser; rm -rf build; mkdir build; cd build; cmake -DENABLE_QT5=ON ../; make -j$(nproc)" + chroot_cmd(script) + end + + def extract + bin = File.join(@chroot, "src/otter-browser/build/otter-browser") + die("binary not found") unless File.file?(bin) + + out = File.join(@outdir, "otter-browser") + system("cp #{bin} #{out}") || die("copy binary failed") + FileUtils.chmod("+x", out) + + if @pw + begin + File.chown(@pw.uid, @pw.gid, out) + rescue => e + msg("chown failed: #{e}") + end + end + + msg("binary: #{out}") + end + + def remove_chroot + msg("removing #{@chroot}...") + FileUtils.rm_rf(@chroot) + end +end + +Builder.new(ARGV).run diff --git a/hosts/void/overlays/bin/xbps-otterb-build b/hosts/void/overlays/bin/xbps-otterb-build @@ -1,212 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -require "fileutils" -require "open3" -require "etc" - -class Builder - REPO = "https://repo-default.voidlinux.org/current" - DEPS = %w[ - cmake - make - gcc - qt5-devel - qt5-svg-devel - qt5-multimedia-devel - qt5-declarative-devel - qt5-webkit-devel - hunspell-devel - gstreamer1-devel - libxml2-devel - qt5-tools - ] - .freeze - - def initialize(argv) - @outdir = nil - @chroot = "/var/chroot/otter-build" - @keep = false - @quiet = false - parse(argv) - validate - end - - def run - bootstrap - mount_vfs - prep_chroot - install_deps - build - extract - ensure - unmount_vfs - remove_chroot unless @keep - msg("done.") - end - - private - - def parse(argv) - i = 0 - while i < argv.length - case argv[i] - when "-o" - @outdir = argv[i += 1] - when "-c" - @chroot = argv[i += 1] - when "-k" - @keep = true - when "-q" - @quiet = true - when "-h", "--help" - usage(code: 0) - else - usage - end - - i += 1 - end - end - - def usage_lines - [ - "Usage: #{File.basename($0)} [-o DIR] [-c DIR] [-k] [-q]", - " -o DIR output directory (default: invoking user home)", - " -c DIR chroot directory (default: /var/chroot/otter-build)", - " -k keep chroot after build", - " -q quiet" - ] - end - - def usage(code: 1) - usage_lines.each { |l| puts(l) } - exit(code) - end - - def validate - unless Process.uid.zero? - usage_lines.each { |l| puts(l) } - die("must run as root") - end - - @src = Dir.pwd - die("no CMakeLists.txt in #{@src}") unless File.file?(File.join(@src, "CMakeLists.txt")) - - inv = ENV["SUDO_USER"] || ENV["DOAS_USER"] - if inv - @pw = Etc.getpwnam(inv) rescue nil - die("cannot resolve user #{inv}") unless @pw - @outdir ||= @pw.dir - else - @outdir ||= File.expand_path("~") - end - end - - def msg(s) = puts(s) unless @quiet - - def die(s) - $stderr.puts("#{File.basename($0)}: #{s}") - exit(1) - end - - def run_cmd(cmd, fatal: true) - msg(cmd) - _o, e, st = Open3.capture3(cmd) - die("#{cmd}: #{e.strip}") if !st.success? && fatal - st.success? - end - - def chroot_cmd(script) - msg("chroot #{@chroot} /bin/bash -c '#{script}'") - die("chroot command failed") unless system("chroot #{@chroot} /bin/bash -c '#{script}'") - end - - def bootstrap - FileUtils.mkdir_p(@chroot) - return if File.executable?(File.join(@chroot, "bin/bash")) - - msg("bootstrapping chroot...") - kdir = File.join(@chroot, "var/db/xbps/keys") - FileUtils.mkdir_p(kdir) - Dir.glob("/var/db/xbps/keys/*").each { |f| FileUtils.cp(f, kdir) } - - run_cmd("xbps-install -Syu -R #{REPO} -r #{@chroot} base-voidstrap", fatal: false) - die("bootstrap failed") unless File.executable?(File.join(@chroot, "bin/bash")) - msg("bootstrap ok") - end - - def mount_vfs - mounts = { - File.join(@chroot, "proc") => ["-t", "proc", "proc"], - File.join(@chroot, "sys") => ["-t", "sysfs", "sys"], - File.join(@chroot, "dev") => ["--bind", "/dev"] - } - mounts.each do |dst, opts| - FileUtils.mkdir_p(dst) - next if system("mountpoint -q #{dst} 2>/dev/null") - system("mount #{opts.join(" ")} #{dst}") - end - end - - def unmount_vfs - %w[dev sys proc].each { |n| system("umount #{File.join(@chroot, n)} 2>/dev/null") } - end - - def prep_chroot - FileUtils.cp("/etc/resolv.conf", File.join(@chroot, "etc/resolv.conf")) - kdir = File.join(@chroot, "var/db/xbps/keys") - FileUtils.mkdir_p(kdir) - Dir.glob("/var/db/xbps/keys/*").each { |f| FileUtils.cp(f, kdir) } - end - - def install_deps - chroot_cmd("xbps-install -Syu") - chroot_cmd("xbps-install -S #{DEPS.join(" ")}") - end - - def build - dst = File.join(@chroot, "src/otter-browser") - FileUtils.rm_rf(dst) - FileUtils.mkdir_p(File.dirname(dst)) - system("cp -a #{@src} #{dst}") || die("copy failed") - - cm = File.join(dst, "CMakeLists.txt") - txt = File.read(cm) - unless txt.include?("FATAL_ON_MISSING_REQUIRED_PACKAGES") - die("CMakeLists.txt: FATAL_ON_MISSING_REQUIRED_PACKAGES not found") - end - - txt.gsub!("FATAL_ON_MISSING_REQUIRED_PACKAGES", "") - File.write(cm, txt) - - script = "set -e; cd /src/otter-browser; rm -rf build; mkdir build; cd build; cmake -DENABLE_QT5=ON ../; make -j$(nproc)" - chroot_cmd(script) - end - - def extract - bin = File.join(@chroot, "src/otter-browser/build/otter-browser") - die("binary not found") unless File.file?(bin) - - out = File.join(@outdir, "otter-browser") - system("cp #{bin} #{out}") || die("copy binary failed") - FileUtils.chmod("+x", out) - - if @pw - begin - File.chown(@pw.uid, @pw.gid, out) - rescue => e - msg("chown failed: #{e}") - end - end - - msg("binary: #{out}") - end - - def remove_chroot - msg("removing #{@chroot}...") - FileUtils.rm_rf(@chroot) - end -end - -Builder.new(ARGV).run