Make use of guix
This commit is contained in:
parent
d1383c5dc0
commit
358e68b79a
12 changed files with 284 additions and 21 deletions
10
Makefile
Normal file
10
Makefile
Normal 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
142
README.md
|
@ -1,9 +1,145 @@
|
||||||
# Génévée
|
# 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
3
deploy.sh
Executable 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
21
genevee-in-a-vm.scm
Normal 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
28
guix.scm
Normal 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+)))
|
|
@ -4,10 +4,15 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Génévée</title>
|
<title>Génévée</title>
|
||||||
<script src="main.js"></script>
|
<script src="main.js"></script>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Générateur de nom de souverain·es mérovingien·nes</h1>
|
<div>
|
||||||
<input id="generate" type="button" value="Générer"/>
|
<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>
|
<p id="result"></p>
|
||||||
|
</div>
|
||||||
|
<p id="about">C'est <a href="https://git.marvid.fr/Tissevert/Genevee">quoi</a> ce truc ?</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
BIN
scribish.ttf
Normal file
BIN
scribish.ttf
Normal file
Binary file not shown.
17
src/Hail.js
Normal file
17
src/Hail.js
Normal 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 + ' !';
|
||||||
|
}
|
16
src/Main.js
16
src/Main.js
|
@ -1,19 +1,9 @@
|
||||||
import Roots;
|
import hail from Hail;
|
||||||
|
import Name;
|
||||||
|
|
||||||
var generate = document.getElementById('generate');
|
var generate = document.getElementById('generate');
|
||||||
var result = document.getElementById('result');
|
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() {
|
generate.addEventListener('click', function() {
|
||||||
result.textContent = "Gloire à " + name() + " !";
|
result.textContent = hail(Name.random());
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Random;
|
||||||
|
|
||||||
var prefixes = [
|
var prefixes = [
|
||||||
"Adal",
|
"Adal",
|
||||||
"Aethel",
|
"Aethel",
|
||||||
|
@ -51,6 +53,11 @@ var suffixes = [
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
prefixes: prefixes,
|
random: random
|
||||||
suffixes: suffixes
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function random() {
|
||||||
|
var prefix = Random.element(prefixes);
|
||||||
|
var suffix = Random.element(suffixes);
|
||||||
|
return prefix + suffix;
|
||||||
|
}
|
8
src/Random.js
Normal file
8
src/Random.js
Normal 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
38
style.css
Normal 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;
|
||||||
|
}
|
Loading…
Reference in a new issue