Compare commits

...

7 commits

12 changed files with 284 additions and 21 deletions

10
Makefile Normal file
View file

@ -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)

142
README.md
View file

@ -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.

3
deploy.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
TARGET="${1%/}/"
[ -n "${TARGET}" ] && rsync -aHP `guix build -f guix.scm`/ "${TARGET}"

21
genevee-in-a-vm.scm Normal file
View file

@ -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)))

28
guix.scm Normal file
View file

@ -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+)))

View file

@ -4,10 +4,15 @@
<meta charset="utf-8">
<title>Génévée</title>
<script src="main.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Générateur de nom de souverain·es mérovingien·nes</h1>
<input id="generate" type="button" value="Générer"/>
<p id="result"></p>
<div>
<h1>Genevee</h1>
<p>Générateur de nom de souverain·es mérovingien·nes</p>
<p><input id="generate" type="button" value="Inventer un nom !"/></p>
<p id="result"></p>
</div>
<p id="about">C'est <a href="https://git.marvid.fr/Tissevert/Genevee">quoi</a> ce truc ?</p>
</body>
</html>

BIN
scribish.ttf Normal file

Binary file not shown.

17
src/Hail.js Normal file
View file

@ -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 + ' !';
}

View file

@ -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());
});

View file

@ -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;
}

8
src/Random.js Normal file
View file

@ -0,0 +1,8 @@
return {
element: element
};
function element(elements) {
var i = Math.floor(elements.length * Math.random());
return elements[i];
}

38
style.css Normal file
View file

@ -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;
}