From 358e68b79a82124df829143a57bf082191b2ef47 Mon Sep 17 00:00:00 2001 From: Tissevert Date: Sun, 26 Mar 2023 17:54:15 +0200 Subject: [PATCH] Make use of guix --- Makefile | 10 +++ README.md | 142 +++++++++++++++++++++++++++++++++++++- deploy.sh | 3 + genevee-in-a-vm.scm | 21 ++++++ guix.scm | 28 ++++++++ index.html | 11 ++- scribish.ttf | Bin 0 -> 32860 bytes src/Hail.js | 17 +++++ src/Main.js | 16 +---- src/{Roots.js => Name.js} | 11 ++- src/Random.js | 8 +++ style.css | 38 ++++++++++ 12 files changed, 284 insertions(+), 21 deletions(-) create mode 100644 Makefile create mode 100755 deploy.sh create mode 100644 genevee-in-a-vm.scm create mode 100644 guix.scm create mode 100644 scribish.ttf create mode 100644 src/Hail.js rename src/{Roots.js => Name.js} (75%) create mode 100644 src/Random.js create mode 100644 style.css diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..48716ea --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +WEBAPP = index.html main.js scribish.ttf style.css + +all: $(WEBAPP) + +main.js: src/ + sjw $^ -o $@ + +install: $(WEBAPP) + mkdir -p $(PREFIX) + cp $^ $(PREFIX) diff --git a/README.md b/README.md index 3da483c..af18c61 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,145 @@ # Génévée -A merovingian king/queen name generator. +A merovingian king/queen name generator. Beyond its (let's face it, limited) +intrinsic usefulness, this project is primarily meant to demonstrate a web +front-end development workflow using [SJW](https://git.marvid.fr/Tissevert/SJW) +and [guix](https://guix.gnu.org/). -## Deploy with [SJW](https://git.marvid.fr/Tissevert/SJW) +## Dependences +The following instructions hence assumes that you already have `guix` +installed. Regarding `SJW`, it is available from the +[loom](https://git.marvid.fr/Tissevert/loom) guix channel. Depending on how you +chose to make it available, the following lines could be slightly different but +to avoid luring you with some irrealistic simplicity, we will assume in what +follows that you have cloned the `loom` channel in a sibling folder from this +repository, so that its root is located at `../loom` relatively to this +repository. The syntax will be lighter if you add the `loom` to your known guix +channels. + +## Build from a local clone of this repository (hacking) + +The Génévée website can be built with this line: + +```sh +$ guix shell -L ../loom -D -f guix.scm -- make ``` -# sjw src -o main.js + +This is of course a one liner, but if you're actually working on an improvement +you'll probably want to spawn a development environment with: + +```sh +$ guix shell -L ../loom -D -f guix.scm ``` + +You improve the code in your favourite text editor, and from time to time +when you want to see your changes applied you simply recompile the site with +`make` in the previously-spawned shell environment: + +```sh +[env]$ make +``` + +which will create or refresh `main.js`. + +Alternatively if your editor handles compilation, calling `make` from some +button or shortcut, you probably just want to run it from an enriched +environment containing it plus the requirements for this package: + +```sh +$ guix shell -L ../loom -D -f guix.scm emacs -- emacs +``` + +Simply opening the `index.html` from your browser lets you see your changes and +work on them. On more complex projects requiring a back-end, you'll want to add +a web server to your own environment and point it to your working copy. You can +of course draw inspiration from the [deployment](#deploy) section below, but +respawning a VM each time you edit a line is by no means practical so even if +your development server lives in a container or virtual machine, you'll be +better off directly writing to the source files it hosts as long as your +tweaking the code. + +## Prepare for distribution (checking) + +You're becoming satisfied with your improvement and are seriously considering +to submit a patch. You commit all your changes and build this site as any +regular `guix` package the usual way: + +```sh +$ guix build -L ../loom -f guix.scm +``` + +The site's files are directly at the root of the directory which path is +displayed by the previous command right before it returns (your hash will be +different and that's ok): + +```sh +… +/gnu/store/f2w493gg7cn94dgbx8dyg2fr0srxm8qa-genevee-0.1.0 +$ ls /gnu/store/f2w493gg7cn94dgbx8dyg2fr0srxm8qa-genevee-0.1.0 +index.html main.js scribish.ttf style.css +``` + +Building the site this way helps you make sure that you haven't forgotten any +implicit dependency, for instance if you have introduced a new `SJW` library in +the code and forgot to add it in Génévée's [`native-input` +field](https://guix.gnu.org/fr/manual/devel/en/html_node/package-Reference.html) +in `guix.scm`. + +If the content of this directory works as expected and is up to your standards, +on to pushing the commit or sending a patch. Otherwise edit, `commit --amend`, +rinse and repeat. + +## Deploy ! + +Maybe you're used to seeing usual UNIX programs built with `guix` and you +expect the content of a `/gnu/store` package's root to look like a profile with +the usual `bin/`, `etc/`, `share/`, etc. directories. The cool thing with the +above structure is that the package becomes directly useful as a kind of +symbolic reference to a given state of the site's source. + +### To a guix system + +Suppose you want to host it on a `guix` server. All you have to do is add a web +server service to its configuration, nginx for the sake of the example, and +point a location to the `genevee` package itself: + +```guile +(define genevee (load "guix.scm")) +``` +… +```guile +(service nginx-service-type + (nginx-configuration + (server-blocks + (list (nginx-server-configuration + (root genevee)))))) +``` + +In fact, have you noticed the `genevee-in-a-vm.scm` in this repository ? This +few lines are actually enough to let you spin a local demo of a server hosting +Génévée in virtually (ahah) no time. + +```sh +$ `guix system vm -L ../loom genevee-in-a-vm.scm` -nic user,model=virtio-net-pci,hostfwd=tcp::8000-:80 +``` + +Once the VM is up, visit [http://localhost:8000](http://localhost:8000) to +admire your local instance of Génévée. + +### Anywhere else + +The target server where you want to deploy Génévée is the last remaining part +of your fleet not (yet) running `guix` ? That's too bad but don't worry, you +can still benefit from this structure and use the cool script `deploy.sh` +(included). Assuming you SSH into your host at `my.vps.net`, and you want to +put Génévée into, say, `/srv/httpd/Génévée/` — where you have write access — +simply call: + +```sh +./deploy.sh my.vps.net:/srv/httpd/Génévée +``` + +Of course this just calls `rsync` with the path expanded from the evaluation of +`guix build` like above. Adapt to taste when you use a different protocol to +sync into production. diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..a883245 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,3 @@ +#!/bin/sh +TARGET="${1%/}/" +[ -n "${TARGET}" ] && rsync -aHP `guix build -f guix.scm`/ "${TARGET}" diff --git a/genevee-in-a-vm.scm b/genevee-in-a-vm.scm new file mode 100644 index 0000000..2f9e802 --- /dev/null +++ b/genevee-in-a-vm.scm @@ -0,0 +1,21 @@ +(use-modules (gnu) + (gnu services web)) + +(let ((genevee (load "guix.scm"))) + (operating-system + (host-name "genevee") + (services + (cons* + (service nginx-service-type + (nginx-configuration + (server-blocks + (list (nginx-server-configuration + (listen '("80")) + (root genevee)))))) + (service static-networking-service-type (list %qemu-static-networking)) + %base-services)) + (bootloader + (bootloader-configuration + (bootloader grub-efi-bootloader) + (targets '("/boot/efi")))) + (file-systems %base-file-systems))) diff --git a/guix.scm b/guix.scm new file mode 100644 index 0000000..98982e3 --- /dev/null +++ b/guix.scm @@ -0,0 +1,28 @@ +(use-modules ((guix build-system gnu) #:select (gnu-build-system)) + ((guix gexp) #:select (gexp local-file)) + ((guix git-download) #:select (git-predicate)) + ((guix licenses) #:select (gpl3+)) + ((guix packages) #:select (package)) + ((loom packages sjw) #:select (sjw))) + +(let ((%source-dir (dirname (current-filename)))) + (package + (name "genevee") + (version "0.1.0") + (source (local-file %source-dir + #:recursive? #t + #:select? (git-predicate %source-dir))) + (build-system gnu-build-system) + (native-inputs (list sjw)) + (arguments + `(#:make-flags ,#~(list (string-append "PREFIX=" #$output)) + #:phases (modify-phases %standard-phases + (delete 'configure) + (delete 'check)))) + (home-page "https://git.marvid.fr/Tissevert/Genevee") + (synopsis "Merovingian king/queen name generator") + (description + "Genevee is a very simple web application meant to demonstrate web +development with SJW and guix. It also generates fun ancient-sounding names +based on frequent morphemes found in real merovingian names.") + (license gpl3+))) diff --git a/index.html b/index.html index 1dd294a..44933ff 100644 --- a/index.html +++ b/index.html @@ -4,10 +4,15 @@ Génévée + -

Générateur de nom de souverain·es mérovingien·nes

- -

+
+

Genevee

+

Générateur de nom de souverain·es mérovingien·nes

+

+

+
+

C'est quoi ce truc ?

diff --git a/scribish.ttf b/scribish.ttf new file mode 100644 index 0000000000000000000000000000000000000000..913f192cb37dff06d909738d7f2a4c3479d2ff19 GIT binary patch literal 32860 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 pnmS37r)b`#G;a$oZ * { + text-align: center; +} + +#about { + position: absolute; + margin: 0.5em; + right: 0; + bottom: 0; +}