(λ (x) (create x) '(knowledge))

toAPK -v template

Adding VOID Template Support to toAPK · May 9, 2020

As I guessed in my last post, I spent a large portion of the drive up to Maine working on toAPK, specifically on my little Nokia N900. I had brought a GPD Pocket with me, but I wasn't aware that I couldn't get a fast enough charge in the car to keep it alive. That really only limited me to being unable to build docker containers, which could have been solved by pushing it through a droplet on DigitalOcean. The fact that I can be as productive on a phone as I am with a laptop will always be thrilling.

VOID Linux handles their packages a far sight differently from Arch Linux. The XBPS packaging system uses a template file, which at first glance looks a lot like an Arch PKGBUILD, but it further breaks down into INSTALL, pre/post installation, and various other configuration files. What this means is that the logic for a template parser is kind of like an Arch package, but has to account for finding install/configuration functions in different files.

I was pleased to find that the PKGBUILDstrip function was larger compatible with the VOID template style, I only had to change some of the search symbols to associate with APKBUILD symbols. In my mind, this means there's a better way to handle this entirely. I need to convert the PKGBUILDstrip function into a macro function that expands on a table/list to create the association. I haven't gotten around to that just yet, once I have the void parsing working I'll loop back around to it. Macro programming in Fennel is a little weird for me, since I'm used to working in LISP-2 implamentation.

Really the only thing I've needed to adjust thus far has been the PKGBUILDrest function, which needed some additional logic handling to ensure it doesn't error out and attempt to math nil when grep returns nothing.

(fn PKGBUILDrest [pkg] (local start (assert (io.popen (.. "grep -m 1 -n '() {' " pkg "| awk -F ':' '{print $1}' ")))) (local sret (assert (start:read "*a"))) ;;If grep returns nothing, don't do math (if (= sret "") (do (tset APKBUILDtbl "REST" ""))) (if (not= sret "") (do (local total (assert (io.popen (.. "wc -l " pkg " | awk '{print $1}'")))) (local tret (assert (total:read "*a"))) ;; We attempt to convert the string returned from grep to number and math the end of the file (local funtot (- (tonumber tret) (tonumber sret))) (local end (assert (io.popen (.. "grep -A" funtot " '() {' " pkg)))) (local eret (assert (end:read "*a"))) (tset APKBUILDtbl "REST" eret))))

For Arch PKGBUILDs we can almost always be certain we will have some sort of install/check/something function () { string inside of the package file. However some VOID templates are so dead simple that they only contain a series of symbols and values without any defined functions. When attempting to parse, initially I would run into an error attempting to run (- (tonumber tret) (tonumber sret)) where sret would end up being NIL because grep couldn't find any '() {' strings in the file. Adding this handling logic now lets us parse these simpler template files using more or less the same code as we use for PKGBUILD parsing.

The only other real change that needed to be made to handle these simpler VOID templates was a couple of switches. The main toAPK function is called with (toAPK ...) in Lua that calls an argument with all argv options. Since toAPK only takes two options typ, and pkg, we can look at argv[1] and check whether or not it is "-v" for VOID or "-a" for ARCH. Dead simple (if (= typ "string")) switches allow toAPK to parse multiple types of files in a user friendly way.

(if (= typ "-v") (do (configure) (TEMPLATEstrip pkg) (PKGBUILDrest pkg) (TEMPLATEclean) (printAPKBUILD typ)))

(if (= typ "-v") (do (if (not= APKBUILDtbl.MDEP "makedepends=") (print APKBUILDtbl.MDEP)) (if (not= APKBUILDtbl.CDEP "checkdepends=") (print APKBUILDtbl.CDEP)) (if (not= APKBUILDtbl.DEP "depends=") (print APKBUILDtbl.DEP))))

Part of me wishes I had done this in Common Lisp, but I think choosing Fennel has allowed me to create a more accessible tool in the end. It runs quickly even on my ancient ARMv7 proc in my Nokia, and it runs anywhere Lua can run. Whereas I'm still struggling to get SBCL to build on aarch64, so it's only available on x86_64 & armv7 for Alpine, a much shallower availability zone overall. In the end, I think that limitation is helping me branch out and try to create tools that are better able to reach more people. A trek on which I see Clojure looming, something I feel is likely foreshadowed by the beginning of my new job.

In other news, Maine is absolutely beautiful. I'm swelling with artistic fervor, which means I need to expand the blog to include a photo gallery of some sort, and some pages to explain the projects I'm working on in better depth, since I've started linking lambdacreate to my Alpine Packages..