instow

:)
git clone https://git.sr.ht/~ashymad/instow
Log | Files | Refs | LICENSE

commit 034e284df35186e21061aa18ac20d21fc77bf9e5
parent 2422940b16479ccfb43816a077f9d50a30dd0311
Author: Szymon Mikulicz <szymon.mikulicz@posteo.net>
Date:   Thu, 26 Feb 2026 13:17:58 +0100

Make instowl installable itself

Diffstat:
A.gitignore | 1+
AMakefile | 11+++++++++++
Minstowl.janet | 150++-----------------------------------------------------------------------------
Rinstowl -> instowl.sh | 0
Asrc/file.janet | 14++++++++++++++
Asrc/libc.janet | 23+++++++++++++++++++++++
Asrc/main.janet | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 176 insertions(+), 148 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +instowl diff --git a/Makefile b/Makefile @@ -0,0 +1,11 @@ +PREFIX?=/usr/local +DESTDIR?=/ + +instowl: instowl.janet + sed 's@\./src/@instowl/@' $< > $@ + +.PHONY: +install: instowl $(wildcard src/*) + install -D -m 755 -T instowl $(DESTDIR)/$(PREFIX)/bin/instowl + install -D -m 644 -t $(DESTDIR)/$(PREFIX)/lib/janet/instowl $(wordlist 2,$(words $^),$^) + diff --git a/instowl.janet b/instowl.janet @@ -1,152 +1,6 @@ #!/usr/bin/env janet -(import spork/sh) - -(ffi/context nil) -(ffi/defbind get_nprocs :int []) -(ffi/defbind-alias dirname libc/dirname :string [path :ptr]) -(ffi/defbind-alias basename libc/basename :string [path :ptr]) -(ffi/defbind-alias mkdtemp libc/mkdtemp :string [template :ptr]) - -(defn dirname [path] - (libc/dirname (string/join [path]))) - -(defn basename [path] - (libc/basename (string/join [path]))) - -(defn mkdtemp [template] - (libc/mkdtemp (string/join [template "XXXXXX"]))) - -(def spinner "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏") -(var ch (string/slice spinner 0 3)) - -(defn rotate [ch] - (def nxt (+ 3 (string/find ch spinner))) - (if (= nxt (length spinner)) - (string/slice spinner 0 3) - (string/slice spinner nxt (+ nxt 3)))) - -(defn file-exists? [path] - (not (nil? (os/stat path)))) - -(defn msg [state line logfile] - (file/write logfile line "\n") - (prinf "\x1b[2K{%s}⸉%s⸊→%s\r" state ch (string/slice line 0 (min 80 (length line)))) - (flush)) - -(defn prinfer [state logfile pipe] - (def buf @"") - (while (ev/read pipe 1024 buf) - (def lines (string/split "\n" buf)) - (def len (length lines)) - (if (> len 1) - (loop [[idx line] :pairs lines] - (if (< idx (- len 1)) - (msg state line logfile) - (do - (buffer/clear buf) - (buffer/push-string buf line))))))) - -(defn runp [state & args] - (def proc (os/spawn args : {:out :pipe :err :pipe})) - (def logfile (file/open "./instowl.log" :a)) - (ev/gather - (prinfer state logfile (proc :out)) - (prinfer state logfile (proc :err)) - (os/proc-wait proc) - (while (= (get proc :return-code) nil) - (ev/sleep 0.2) - (set ch (rotate ch)) - (prinf "{%s}⸉%s⸊\r" state ch) - (flush))) - (def code (get proc :return-code)) - (os/proc-close proc) - (file/close logfile) - code) - -(defmacro checkrun [newstate & args] - ~(if (= (runp state ,;args) 0) - (set state ,newstate) - (set state :error))) - -(defmacro iff [&opt condition iftrue & rest] - (if (nil? iftrue) condition ~(if ,condition ,iftrue (iff ,;rest)))) - -(defn dir-exists? [path] - (= (os/stat path :mode) :directory)) - -(defn mkdirp [path] - (if (not (dir-exists? path)) (do (mkdirp (dirname path)) (os/mkdir path)))) - -(defn move-file [src dst] - (mkdirp (dirname dst)) - (os/rename src dst)) +(import ./src/main) (defn main [& args] - (do - (def target (string/join [(os/getenv "HOME") "/.local"])) - (def stowdir (string/join [target "/pkg"])) - (def pkg (basename (os/getenv "PWD"))) - (def pkgdir (string/join [stowdir "/" pkg])) - (def destdir (mkdtemp "/tmp/instowl.")) - (sh/rm "./instowl.log") - - (var prefix target) - (var state :init) - - (while (not= state :exit) - (case state - :init - (iff - (file-exists? "configure") (set state :conf/configure) - (file-exists? "configure.ac") (set state :conf/autotools) - (set state :error)) - - :conf/autotools - (checkrun :conf/configure "/usr/bin/autoreconf" "-vi") - - :conf/configure - (checkrun :build/make "./configure" (string/join ["--prefix=" prefix])) - - :build/make - (checkrun :install/pre "/usr/bin/make" (string/format "-j%d" (get_nprocs))) - - :install/pre - (do - (set state :install/make)) - - :install/make - (checkrun :install/post - "/usr/bin/make" - "install" - (string/join ["DESTDIR=" destdir]) - (string/join ["PREFIX=" prefix])) - - :install/post - (do - (def logfile (file/open "./instowl.log" :a)) - (def installdir (string/join [destdir prefix])) - (if (dir-exists? installdir) - (do - (loop [file :in (sh/list-all-files installdir)] - (def dst (string/replace installdir pkgdir file)) - (msg state (string/format "MV %s -> %s" file dst) logfile) - (move-file file dst)) - (file/close logfile) - (set state :stow)) - (set state :error))) - - :stow - (checkrun :done "/usr/bin/stow" "-vv" "-d" stowdir "-t" target pkg) - - :error - (do - (sh/rm (string/join [destdir])) - (printf "\x1b[2K⸉!⸊→Error") - (set state :exit)) - - :done - (do - (sh/rm (string/join [destdir])) - (printf "\x1b[2K⸉x⸊→Done") - (set state :exit)))))) + (main/main ;args)) diff --git a/instowl b/instowl.sh diff --git a/src/file.janet b/src/file.janet @@ -0,0 +1,14 @@ +(import ./libc) + +(defn file-exists? [path] + (= (os/stat path :mode) :file)) + +(defn dir-exists? [path] + (= (os/stat path :mode) :directory)) + +(defn mkdirp [path] + (if (not (dir-exists? path)) (do (mkdirp (libc/dirname path)) (os/mkdir path)))) + +(defn move-file [src dst] + (mkdirp (libc/dirname dst)) + (os/rename src dst)) diff --git a/src/libc.janet b/src/libc.janet @@ -0,0 +1,23 @@ +(defmacro bind [name & types] + (with-syms [$fn $sig] + ~(let [,$fn (ffi/lookup (ffi/native) ,name) + ,$sig (ffi/signature :default ,;types)] + (fn [& args] (ffi/call ,$fn ,$sig ;args))))) + +(defmacro defbind [name & types] + ~(def ,name (bind ,(string/join [name]) ,;types))) + +(defmacro bind/str [name] + (with-syms [$fn $sig] + ~(let [,$fn (ffi/lookup (ffi/native) ,name) + ,$sig (ffi/signature :default :string :ptr)] + (fn [arg] (ffi/call ,$fn ,$sig (string/join [arg])))))) + +(defmacro defbind/str [name] + ~(def ,name (bind/str ,(string/join [name])))) + +(defbind get_nprocs :int) +(defbind/str dirname) +(defbind/str basename) +(defbind/str mkdtemp) + diff --git a/src/main.janet b/src/main.janet @@ -0,0 +1,125 @@ +(import spork/sh) +(import ./libc) +(import ./file) + +(def spinner "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏") +(var ch (string/slice spinner 0 3)) + +(defn rotate [ch] + (def nxt (+ 3 (string/find ch spinner))) + (if (= nxt (length spinner)) + (string/slice spinner 0 3) + (string/slice spinner nxt (+ nxt 3)))) + +(defn msg [state line logfile] + (file/write logfile line "\n") + (prinf "\x1b[2K{%s}⸉%s⸊→%s\r" state ch (string/slice line 0 (min 80 (length line)))) + (flush)) + +(defn prinfer [state logfile pipe] + (def buf @"") + (while (ev/read pipe 1024 buf) + (def lines (string/split "\n" buf)) + (def len (length lines)) + (if (> len 1) + (loop [[idx line] :pairs lines] + (if (< idx (- len 1)) + (msg state line logfile) + (do + (buffer/clear buf) + (buffer/push-string buf line))))))) + +(defn runp [state & args] + (def proc (os/spawn args : {:out :pipe :err :pipe})) + (def logfile (file/open "./instowl.log" :a)) + (ev/gather + (prinfer state logfile (proc :out)) + (prinfer state logfile (proc :err)) + (os/proc-wait proc) + (while (= (get proc :return-code) nil) + (ev/sleep 0.2) + (set ch (rotate ch)) + (prinf "{%s}⸉%s⸊\r" state ch) + (flush))) + (def code (get proc :return-code)) + (os/proc-close proc) + (file/close logfile) + code) + +(defmacro checkrun [newstate & args] + ~(if (= (runp state ,;args) 0) + (set state ,newstate) + (set state :error))) + +(defmacro iff [&opt condition iftrue & rest] + (if (nil? iftrue) condition ~(if ,condition ,iftrue (iff ,;rest)))) + +(defn main [& args] + (do + (def target (string/join [(os/getenv "HOME") "/.local"])) + (def stowdir (string/join [target "/pkg"])) + (def pkg (libc/basename (os/getenv "PWD"))) + (def pkgdir (string/join [stowdir "/" pkg])) + (def destdir (libc/mkdtemp "/tmp/instowl.XXXXXX")) + (sh/rm "./instowl.log") + + (var prefix target) + (var state :init) + + (while (not= state :exit) + (case state + :init + (iff + (file/file-exists? "configure") (set state :conf/configure) + (file/file-exists? "configure.ac") (set state :conf/autotools) + (file/file-exists? "Makefile") (set state :build/make) + (set state :error)) + + :conf/autotools + (checkrun :conf/configure "/usr/bin/autoreconf" "-vi") + + :conf/configure + (checkrun :build/make "./configure" (string/join ["--prefix=" prefix])) + + :build/make + (checkrun :install/pre "/usr/bin/make" (string/format "-j%d" (libc/get_nprocs))) + + :install/pre + (do + (set state :install/make)) + + :install/make + (checkrun :install/post + "/usr/bin/make" + "install" + (string/join ["DESTDIR=" destdir]) + (string/join ["PREFIX=" prefix])) + + :install/post + (do + (def logfile (file/open "./instowl.log" :a)) + (def installdir (string/join [destdir prefix])) + (if (file/dir-exists? installdir) + (do + (loop [file :in (sh/list-all-files installdir)] + (def dst (string/replace installdir pkgdir file)) + (msg state (string/format "INST %s" dst) logfile) + (file/move-file file dst)) + (file/close logfile) + (set state :stow)) + (set state :error))) + + :stow + (checkrun :done "/usr/bin/stow" "-vv" "-d" stowdir "-t" target pkg) + + :error + (do + (sh/rm (string/join [destdir])) + (printf "\x1b[2K⸉!⸊→Error") + (set state :exit)) + + :done + (do + (sh/rm (string/join [destdir])) + (printf "\x1b[2K⸉x⸊→Done") + (set state :exit))))))