summaryrefslogtreecommitdiff
path: root/src/utils.scm
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils.scm')
-rw-r--r--src/utils.scm137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/utils.scm b/src/utils.scm
new file mode 100644
index 0000000..ddcfb3f
--- /dev/null
+++ b/src/utils.scm
@@ -0,0 +1,137 @@
+;; kenku --- crawl and reproduce github actions
+;; Copyright © 2026 bdunahu <bdunahu@operationnull.com>
+;;
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+(define-module (src utils)
+ #:use-module (srfi srfi-1)
+ #:use-module (ice-9 match)
+ #:use-module (web client)
+ #:use-module (web response)
+ #:use-module (rnrs bytevectors)
+ #:use-module (json)
+ #:use-module (ice-9 receive)
+ #:use-module (ice-9 textual-ports)
+ #:use-module (ice-9 pretty-print)
+ #:use-module (ice-9 regex)
+ #:use-module (ice-9 popen)
+ #:export (default-headers
+ url-exists?
+ url->scm
+ shell->str
+ normalize-file
+ append-to-values
+ mkdir-p
+ filter-actions-on-regex))
+
+(define default-headers
+ `((Accept . "application/vnd.github+json")
+ (Authorization . ,(string-append
+ "Bearer "
+ (getenv "TOKEN")))
+ (User-Agent . "curl 8.6.0"))) ;i lied
+
+(define (url-exists? url)
+ (receive (status body)
+ (http-request url #:headers default-headers)
+ (equal? 200 (response-code status))))
+
+(define* (url->scm url #:key (headers default-headers))
+ (receive (status body)
+ (http-request url #:headers headers)
+ (json-string->scm (utf8->string body))))
+
+(define (shell->str . args)
+ (let* ((port (apply open-pipe*
+ (cons OPEN_READ
+ args)))
+ (contents (get-string-all port)))
+ (close-pipe port)
+ contents))
+
+(define (normalize-file file)
+ (let* ((str (call-with-input-file file get-string-all))
+ (str (string-filter (lambda (c)
+ (not (member c (list #\, #\" #\' #\return))))
+ str))
+ (str (string-join
+ (delete-duplicates (string-split str #\newline))
+ "\n"))
+ (output (open-file file "w")))
+ (display str output)
+ (close output)))
+
+(define (append-to-values hashtable k v)
+ (let ((existing (hash-ref hashtable k '())))
+ (hash-set! hashtable k (cons v existing))
+ hashtable))
+
+(define (mkdir-p dir)
+ "Yoinked from https://codeberg.org/guix/guix."
+ (define absolute?
+ (string-prefix? "/" dir))
+ (define not-slash
+ (char-set-complement (char-set #\/)))
+ (let loop ((components (string-tokenize dir not-slash))
+ (root (if absolute?
+ ""
+ ".")))
+ (match components
+ ((head tail ...)
+ (let ((path (string-append root "/" head)))
+ (catch 'system-error
+ (lambda ()
+ (mkdir path)
+ (loop tail path))
+ (lambda args
+ (if (= EEXIST (system-error-errno args))
+ (loop tail path)
+ (apply throw args))))))
+ (() #t))))
+
+(define (filter-actions-on-regex file file->regex parse-f)
+ "This procedure is for the bash drop-ins only, which do not filter their
+outputs into files, but rather output lines which need to be filtered based on
+regex.
+
+FILE: the file to be filtered
+FILE->REGEX: an alist mapping file names to the regex each item (usually a line
+in FILE, should match) would need to match for inclusion to said file name.
+PARSE-F: A function describing how the contents of FILE should be parsed into
+items."
+ (let ((ht (make-hash-table)))
+ (define (hash-actions-to-regex actions)
+ (for-each
+ (lambda (s)
+ (for-each
+ (lambda (pair)
+ (let ((file (car pair))
+ (regex (cdr pair)))
+ (when (string-match regex s)
+ (append-to-values ht file s))))
+ file->regex))
+ actions)
+ ht)
+ (define (hash->files)
+ (hash-for-each (lambda (file actions)
+ (mkdir-p (dirname file))
+ (let ((output (open-file file "w")))
+ (map (lambda (a) (format output "~a~%" a))
+ actions)
+ (close output)))
+ ht))
+ (let* ((str (call-with-input-file file get-string-all))
+ (actions (parse-f str)))
+ (hash-actions-to-regex actions)
+ (hash->files))))