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:
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))))))