commit 8426126b3017585dbeb17c1d6b519a26b7d53714 Author: Ray Miller Date: Thu May 29 15:31:32 2025 +0100 Skeleton CLI using guile-config diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e16f7ad --- /dev/null +++ b/.gitignore @@ -0,0 +1,66 @@ +*.eps +*.go +*.log +*.pdf +*.png +*.tar.xz +*.tar.gz +*.tmp +*~ +.#* +\#*\# +,* +/ABOUT-NLS +/INSTALL +/aclocal.m4 +/autom4te.cache +/build-aux/ar-lib +/build-aux/compile +/build-aux/config.guess +/build-aux/config.rpath +/build-aux/config.sub +/build-aux/depcomp +/build-aux/install-sh +/build-aux/mdate-sh +/build-aux/missing +/build-aux/test-driver +/build-aux/texinfo.tex +/config.status +/configure +/doc/*.1 +/doc/.dirstamp +/doc/contributing.*.texi +/doc/*.aux +/doc/*.cp +/doc/*.cps +/doc/*.fn +/doc/*.fns +/doc/*.html +/doc/*.info +/doc/*.info-[0-9] +/doc/*.ky +/doc/*.pg +/doc/*.toc +/doc/*.t2p +/doc/*.tp +/doc/*.vr +/doc/*.vrs +/doc/stamp-vti +/doc/version.texi +/doc/version-*.texi +/m4/* +/pre-inst-env +/test-env +/test-tmp +/tests/*.trs +GPATH +GRTAGS +GTAGS +Makefile +Makefile.in +config.cache +stamp-h[0-9] +tmp +/.version +/doc/stamp-[0-9] +/.config/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..ce944c7 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# Ordo + +Ordo ab chao: from chaos, comes order. + +## Installing Dependencies + +On a Guix system, you can simply run: + +``` bash +guix package -m manifest.scm +``` + +If Guix is not available where you plan to run ordo, but you have access to a +system running Guix, you can create a tarball containing all the dependencies: + +``` bash +guix pack -RR -m manifest.scm +``` + +Copy the tarball to your system and unpack it (somewhere). + +Find the name of the profile in the tarball and use that to configure paths etc. + +``` bash +export GUIX_PROFILE=$(realpath gnu/store/*-profile) +source "${GUIX_PROFILE}/etc/profile" +``` diff --git a/guix.scm b/guix.scm new file mode 100644 index 0000000..fe59576 --- /dev/null +++ b/guix.scm @@ -0,0 +1,79 @@ +(use-modules + (gnu packages) + (gnu packages bash) + (gnu packages golang-crypto) + (gnu packages guile) + (gnu packages guile-xyz) + (gnu packages ssh) + (gnu packages version-control) + (guix build-system guile) + (guix download) + (guix gexp) + ((guix licenses) #:prefix license:) + (guix packages) + (srfi srfi-1)) + +(package + (name "guile-ordo") + (version "0.1.0") + (source + (local-file + (dirname (current-filename)) + #:recursive? #t + #:select? (lambda (file stat) + (not (any (lambda (my-string) + (string-contains file my-string)) + (list ".git" ".dir-locals.el" "guix.scm")))))) + (build-system guile-build-system) + (arguments + (list + #:phases #~(modify-phases %standard-phases + (add-after 'build 'link-and-wrap-executable + (lambda* (#:key inputs outputs #:allow-other-keys) + (let* ((bin (string-append #$output "/bin")) ; bin directory for PATH. + (site-version (target-guile-effective-version)) + (scm (lambda (p) (string-append p "/share/guile/site/" site-version))) + (go (lambda (p) (string-append p "/lib/guile/" site-version "/site-ccache"))) + (runtime-deps (cons #$output (map (lambda (p) (assoc-ref inputs p)) (list "guile-config" + "guile-dsv" + "guile-filesystem" + "guile-ini" + "guile-irregex" + "guile-libyaml" + "guile-json" + "guile-lib" + "guile-semver" + "guile-srfi-145" + "guile-srfi-158" + "guile-srfi-197" + "guile-srfi-235" + "guile-ssh"))))) + (mkdir-p bin) + (let ((source-script (string-append #$output + "/share/guile/site/" site-version "/" + "ordo.scm")) + (target-command (string-append bin "/ordo"))) + (symlink source-script target-command) + (wrap-program target-command + #:sh (which "bash") + `("GUILE_LOAD_PATH" prefix ,(map scm runtime-deps)) + `("GUILE_LOAD_COMPILED_PATH" prefix ,(map go runtime-deps)))))))))) + (inputs (list guile-3.0 bash-minimal git git-lfs age)) + (propagated-inputs (list guile-config + guile-dsv + guile-filesystem + guile-ini + guile-irregex + guile-libyaml + guile-json-4 + guile-lib + guile-semver + guile-srfi-145 + guile-srfi-158 + guile-srfi-197 + guile-srfi-235 + guile-ssh)) + (synopsis "Ordo configuration management") + (description "") + (home-page "") + (license license:gpl3+)) diff --git a/ordo.scm b/ordo.scm new file mode 100755 index 0000000..38a1697 --- /dev/null +++ b/ordo.scm @@ -0,0 +1,42 @@ +#!/usr/bin/guile \ +--no-auto-compile -e main -s +!# + +(use-modules (config) + (config api) + (config parser sexp) + (ice-9 format) + (ice-9 match) + ((ordo cli run) #:prefix run:) + (srfi srfi-1)) + +(define config + (configuration + (name 'ordo) + (synopsis "From chaos, comes order") + (description "Ordo configuration management.") + (keywords + (list + (setting + (name 'log-level) + (handler string->symbol) + (test symbol?) + (default 'NOTICE) + (example "DEBUG|INFO|NOTICE|WARN|ERROR") + (synopsis "Log level")))) + (parser sexp-parser) + (directory (in-cwd ".config/" #t)) + (version "0.1.0") + (author "Ray Miller") + (license gpl3+) + (copyright (list 2025)) + (subcommands + (list + run:config)))) + +(define (main cmd-line) + (let ((options (getopt-config-auto cmd-line config))) + (match (full-command options) + (("ordo" "run") + (run:handler options)) + (_ (emit-help options))))) diff --git a/ordo/cli/run.scm b/ordo/cli/run.scm new file mode 100644 index 0000000..4098047 --- /dev/null +++ b/ordo/cli/run.scm @@ -0,0 +1,48 @@ +(define-module (ordo cli run) + #:use-module (config) + #:use-module (config api) + #:use-module (srfi srfi-1) + #:export (config handler)) + +(define (valid-tags? x) + (or (null? x) + (and (list? x) (every keyword? x)))) + +(define (parse-tags x) + (map (compose symbol->keyword string->symbol) + (if (list? x) x (list x)))) + +(define config + (configuration + (name 'run) + (wanted '((keywords . (log-level)) directory)) + (keywords + (list + (setting + (name 'inventory) + (default "inventory.scm") + (example "examples/inventory.scm") + (handler identity) + (test file-exists?) + (synopsis "Inventory file")) + (switch + (name 'tag) + (default (list)) + (test valid-tags?) + (handler parse-tags) + (merge-strategy cons) + (synopsis "Limit operations to specified tag(s)")))) + (arguments + (list + (argument + (name 'playbook) + (handler identity) + (test file-exists?)))) + (synopsis "Run a playbook"))) + +(define (handler options) + (format #t "run:handler log-level=~a inventory=~a tags=~a playbook=~a~%" + (option-ref options 'log-level) + (option-ref options 'inventory) + (option-ref options 'tag) + (option-ref options '(playbook))))