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 0000000..913f192 Binary files /dev/null and b/scribish.ttf differ diff --git a/src/Hail.js b/src/Hail.js new file mode 100644 index 0000000..2c6aecc --- /dev/null +++ b/src/Hail.js @@ -0,0 +1,17 @@ +import Random; + +var greetings = [ + "Gloire à", + "Longue vie à", + "Vive" +]; +var latest = null; + +return { + hail: hail +}; + +function hail(name) { + latest = Random.element(greetings.filter(function(g) {return g != latest})); + return latest + ' ' + name + ' !'; +} diff --git a/src/Main.js b/src/Main.js index dadc5f3..80e2379 100644 --- a/src/Main.js +++ b/src/Main.js @@ -1,19 +1,9 @@ -import Roots; +import hail from Hail; +import Name; var generate = document.getElementById('generate'); var result = document.getElementById('result'); -function random(roots) { - var i = Math.floor(roots.length * Math.random()); - return roots[i]; -} - -function name() { - var prefix = random(Roots.prefixes); - var suffix = random(Roots.suffixes); - return prefix + suffix; -} - generate.addEventListener('click', function() { - result.textContent = "Gloire à " + name() + " !"; + result.textContent = hail(Name.random()); }); diff --git a/src/Roots.js b/src/Name.js similarity index 75% rename from src/Roots.js rename to src/Name.js index 6038c2b..b85cc7f 100644 --- a/src/Roots.js +++ b/src/Name.js @@ -1,3 +1,5 @@ +import Random; + var prefixes = [ "Adal", "Aethel", @@ -51,6 +53,11 @@ var suffixes = [ ]; return { - prefixes: prefixes, - suffixes: suffixes + random: random }; + +function random() { + var prefix = Random.element(prefixes); + var suffix = Random.element(suffixes); + return prefix + suffix; +} diff --git a/src/Random.js b/src/Random.js new file mode 100644 index 0000000..1a9863a --- /dev/null +++ b/src/Random.js @@ -0,0 +1,8 @@ +return { + element: element +}; + +function element(elements) { + var i = Math.floor(elements.length * Math.random()); + return elements[i]; +} diff --git a/style.css b/style.css new file mode 100644 index 0000000..264d61c --- /dev/null +++ b/style.css @@ -0,0 +1,38 @@ +@font-face { + font-family: "Scribish"; + src: url("scribish.ttf") format("truetype"); +} + +body { + margin: 0; + background: #feffeb; + min-height: 100%; + width: 100%; + position: absolute; +} + +h1 { + font-family: "Scribish"; + font-size: 4em; + padding: 20px; + display: block; + margin: 0; + color: #382109; + text-shadow: 3px 0 2px #9b9113, -3px 0 2px #9b9113, 0 3px 2px #9b9113, 0 -3px 2px #cbd34e, 3px 3px 2px #9b9113, -3px 3px 2px #9b9113, 3px -3px 2px #9b9113, -3px -3px 2px #cbd34e; + letter-spacing: 10px; +} + +div { + margin: 40px 0; +} + +div > * { + text-align: center; +} + +#about { + position: absolute; + margin: 0.5em; + right: 0; + bottom: 0; +}