add new post about this repo packaging.
added: new post folder about how i've packaged this repository with ad hoc env and pdf build process with nix updated: src/configs/presnterm.yaml, modified to handle additional arguments in front matter
This commit is contained in:
parent
438582a21b
commit
b8b8324b10
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
description = "An empty flake template that you can adapt to your own environment";
|
description = "An flake to provide dev and build environnement for presenterm post production";
|
||||||
|
|
||||||
# Flake inputs
|
# Flake inputs
|
||||||
inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1";
|
inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1";
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
options:
|
||||||
|
strict_front_matter_parsing: false
|
||||||
export:
|
export:
|
||||||
dimensions:
|
dimensions:
|
||||||
columns: 108
|
columns: 108
|
||||||
|
|||||||
BIN
src/posts/general_nix/post_packaging/cover.jpg
Normal file
BIN
src/posts/general_nix/post_packaging/cover.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
BIN
src/posts/general_nix/post_packaging/flake_schema.png
Normal file
BIN
src/posts/general_nix/post_packaging/flake_schema.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 312 KiB |
42
src/posts/general_nix/post_packaging/packaging.nix
Normal file
42
src/posts/general_nix/post_packaging/packaging.nix
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
description = "An flake to provide dev and build environnement for presenterm post production";
|
||||||
|
|
||||||
|
inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1";
|
||||||
|
|
||||||
|
outputs = inputs: {
|
||||||
|
devShells = forEachSupportedSystem ( { pkgs }: {
|
||||||
|
default = pkgs.mkShell {
|
||||||
|
packages = with pkgs; [
|
||||||
|
presenterm
|
||||||
|
python313Packages.weasyprint
|
||||||
|
];
|
||||||
|
};
|
||||||
|
} );
|
||||||
|
|
||||||
|
packages = forEachSupportedSystem ( { pkgs }: {
|
||||||
|
default = pkgs.stdenv.mkDerivation {
|
||||||
|
inherit (pkgs) system;
|
||||||
|
name = "linkedin-shoblog-posts";
|
||||||
|
src = ./src;
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
presenterm
|
||||||
|
python313Packages.weasyprint
|
||||||
|
];
|
||||||
|
buildPhase =
|
||||||
|
let
|
||||||
|
font_dir = pkgs.nerd-fonts.jetbrains-mono;
|
||||||
|
config = pkgs.writeTextFile {
|
||||||
|
name = "presenterm.conf";
|
||||||
|
text = ''
|
||||||
|
# presenterm configuration
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
''
|
||||||
|
export PRES_CONFIG=${config}
|
||||||
|
python scripts/build.py
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
}
|
||||||
251
src/posts/general_nix/post_packaging/post_packaging.md
Normal file
251
src/posts/general_nix/post_packaging/post_packaging.md
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
---
|
||||||
|
options:
|
||||||
|
command_prefix: "pr:"
|
||||||
|
strict_front_matter_parsing: false
|
||||||
|
theme:
|
||||||
|
name: tokyonight-storm
|
||||||
|
override:
|
||||||
|
default:
|
||||||
|
# colors:
|
||||||
|
# foreground: "4c4f69"
|
||||||
|
# background: "ffffff"
|
||||||
|
code:
|
||||||
|
alignment: center
|
||||||
|
palette:
|
||||||
|
colors:
|
||||||
|
base00: "24283B"
|
||||||
|
base01: "16161E"
|
||||||
|
base02: "343A52"
|
||||||
|
base03: "444B6A"
|
||||||
|
base04: "787C99"
|
||||||
|
base05: "A9B1D6"
|
||||||
|
base06: "CBCCD1"
|
||||||
|
base07: "D5D6DB"
|
||||||
|
base08: "C0CAF5"
|
||||||
|
base09: "A9B1D6"
|
||||||
|
base0A: "0DB9D7"
|
||||||
|
base0B: "9ECE6A"
|
||||||
|
base0C: "B4F9F8"
|
||||||
|
base0D: "2AC3DE"
|
||||||
|
base0E: "BB9AF7"
|
||||||
|
base0F: "F7768E"
|
||||||
|
lang: fr
|
||||||
|
---
|
||||||
|
presenterm build process with nix
|
||||||
|
===
|
||||||
|
```file +line_numbers
|
||||||
|
path: packaging.nix
|
||||||
|
language: nix
|
||||||
|
```
|
||||||
|
Hier je me suis dit que j'allais faire un petit repo avec les différents posts de
|
||||||
|
cette série, histoire de rendre les textes source accessible entre autre pour les
|
||||||
|
personnes malvoyantes ou juste pour ceux ne souhaitant pas lire des images en 24px * 24px.
|
||||||
|
Problème, mon cerveau un peu mal fichu, c'est aussi dit "tient, et si tu en profitais
|
||||||
|
pour faire un flake avec un environnement dev pour qui voudrait preview tes slides
|
||||||
|
sans avoir à installer presenterm puis "hey mais attend, tu pourrais aussi faire
|
||||||
|
en sorte de générer un package avec nix qui contient tous les PDF", ce qui inclut
|
||||||
|
donc de les générer au moment du packaging.
|
||||||
|
Et donc après quelques heures de trifouillage, me voici pour vous présenter mes
|
||||||
|
bêtises.
|
||||||
|
Vous connaissez la routine, lancez spotify et c'est parti pour un peu de lecture
|
||||||
|
# album du jour
|
||||||
|
## American idiot - Green day
|
||||||
|

|
||||||
|
<!-- pr:end_slide -->
|
||||||
|
OK, comment ça marche ?
|
||||||
|
===
|
||||||
|
Avant de parler de ce que sont les flakes et de leur intérêt dans l'écosystème
|
||||||
|
de nix, commençons par la base, qu'est-ce qu'un package en nix ? "Simplement",
|
||||||
|
une fonction qui décrit un process de build, pour reprendre les exemples des articles
|
||||||
|
précédents, pour le packaging des assets de mon site avec **Vue**, nous avons une
|
||||||
|
fonction prenant en entrée les dépendances nécessaires pour le process de build,
|
||||||
|
puis décrivant ce dernier, puis retournant uniquement les assets builder sous la
|
||||||
|
la forme d'un path dans le store nix. Grossièrement, en terme de code cela donnerais
|
||||||
|
quelque chose du style:
|
||||||
|
```nix
|
||||||
|
# package.nix
|
||||||
|
{ pkgs }: pkgs.stdenv.mkDerivation {
|
||||||
|
pname = "mon super website";
|
||||||
|
version = "3.14";
|
||||||
|
src = pkgs.fetchgit {
|
||||||
|
url = "http://git.shobu.fr/shoblog/front";
|
||||||
|
rev = "069d2a5bfa4c4024063c25551d5201aeaf921cb3";
|
||||||
|
sha256 = "sha256-MlqJOoMSRuYeG+jl8DFgcNnpEyeRgDCK2JlN9pOqBWA=";
|
||||||
|
};
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
node
|
||||||
|
yarn
|
||||||
|
];
|
||||||
|
buildPhase = ''yarn build'';
|
||||||
|
installPHase = ''
|
||||||
|
mkdir -p $out/dist
|
||||||
|
cp dist $out
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
L'exemple est bien sûr quelque peu simplifié, mais dans les grandes lignes :
|
||||||
|
* `{ pkgs }: {}`: constitue notre fonction, avec en argument *pkgs* qui correspond
|
||||||
|
à une instance de nixpkgs.
|
||||||
|
* `pkgs.stdenv.mkDerivation`: est la fonction la plus basique nous permettant de créer
|
||||||
|
un package, les autres fonction, comme mkYarnPackage, étendent cette dernière.
|
||||||
|
Cette fonction prend elle aussi plusieurs arguments qu'elle vas utiliser pour builder
|
||||||
|
notre package
|
||||||
|
* `pname` et `version`: le nom de notre package et sa version
|
||||||
|
* `src`: les fichiers qui serons accessible dans notre environnement de build et
|
||||||
|
qui constituent la source de notre package.
|
||||||
|
* `buildInputs`: les paquets qui serons accessibles dans notre environnement
|
||||||
|
de build.
|
||||||
|
* `buildPhase` et `installPhase`: Les hook qui décrivent comment builder et installer
|
||||||
|
notre paquet. Il existe d'autre hooks pour d'autres usages décris dans la documentation.
|
||||||
|
|
||||||
|
Vous aurez remarqué de votre œil attentif que la fonction s'appelle `mkDerivation`,
|
||||||
|
et non pas `mkPackage` par exemple comme on aurait pu s'y attendre. Pourquoi ça ?
|
||||||
|
Dans nix, la dérivation est le bloc fondamental du système de build de nix, un
|
||||||
|
package n'étant qu'une forme de dérivation. Pour rester simple, je resterais sur
|
||||||
|
l'appellation plus classique de "package".
|
||||||
|
Un souci de cette approche, c'est que le type du retour de notre fonction n'est pas
|
||||||
|
spécialement défini, on pourrait avoir un package comme ici, mais aussi une shell avec
|
||||||
|
mkShell, ou un host dans le cas d'une configuration nixos. Le seul moyen de le savoir,
|
||||||
|
c'est d'avoir une sémantique propre sur ses noms de fichiers. De même, les outils autour
|
||||||
|
de nix vont s'attendre à un certain type de retour, mais vont quand même builder la dérivation
|
||||||
|
avant de pouvoir déterminer celui-ci. Par exemple, nix-shell vas s'attendre à avoir le résultat
|
||||||
|
d'un mkShell pour fonctionner, mais n'aura pas de moyen de le savoir avant d'avoir interprété
|
||||||
|
la fonction fourni.
|
||||||
|
C'est ainsi que pour résoudre ce problème d'uniformité (et quelques autres raisons), les **flakes**
|
||||||
|
on ete mis en place.
|
||||||
|
<!-- pr:end_slide -->
|
||||||
|
les flakes c'est quoi ?
|
||||||
|
===
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
description = "";
|
||||||
|
inputs = {};
|
||||||
|
outputs = inputs: {};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Simplement, un flake est un dossier dans lequel se trouve un fichier `flake.nix`
|
||||||
|
contenant un attribut set avec les attributs suivants :
|
||||||
|
* `description`: la description de ce que fait le flake.
|
||||||
|
* `inputs`: un attribut set contenant les dépendances du flake, typiquement une instance
|
||||||
|
de nixpkgs. Classiquement, chaque input est un repo contenant un autre flake, sur github,
|
||||||
|
gitlab ou en local et peut être pin sur une branche ou un commit specifique.
|
||||||
|
* `outputs`: une fonction ayant pour parametre le résultat de l'interprétation des inputs
|
||||||
|
et retournant un attribut set ou chaque attribut est un résultat possible retourné par
|
||||||
|
notre flake, bien qu'il existe des attributs standard utilisé par les outils de nix
|
||||||
|
(nix build, nix shell, nix develop), le développeur est libre de retourner ce qu'il veut,
|
||||||
|
ce qui permet à des outils comme *colmena* de créer leur propres standards.
|
||||||
|
Pour un package, on vas ainsi retrouver l'attribut `packages.<architecture>.<paquet>` indiquant
|
||||||
|
que le flake peut fournir un ou plusieurs packages pour une architecture donnée.
|
||||||
|
Ainsi, le flake suivant
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
description = "un flake d'exemple";
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
|
||||||
|
};
|
||||||
|
outputs = inputs: {
|
||||||
|
packages."x86_64-linux".default =
|
||||||
|
with import inputs.nixpkgs {system = "x86_64-linux";};
|
||||||
|
writeShellScriptBin "hello" "echo 'world hello'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
On donne ici en input la dernière version stable de nixpkgs. Dans notre fonction
|
||||||
|
d'output, on déclare un package nommé "default" et on fait appel à la fonction
|
||||||
|
`writeShellScriptBin` pour le créer, cette fonction prend en argument un nom
|
||||||
|
de fichier et une chaine de caractère et créer un fichier exécutable contenant
|
||||||
|
le code du deuxième argument, utilisant `sh` pour l'exécution.
|
||||||
|
Une fois notre package builder avec `nix build`, on se retrouve avec notre
|
||||||
|
exécutable rangé dans un `./results/bin/hello`. On peut aussi directement lancer
|
||||||
|
ce dernier avec `nix run`. Ces nouvelles commandes, différentes des classiques
|
||||||
|
`nix-shell` et `nix-build` sont intimement liés aux flakes.
|
||||||
|
En effet, contrairement aux commandes classiques qui lisent juste l'output et tentent de l'interpréter,
|
||||||
|
ces dernières vont plutôt chercher si une output spécifique est présente.
|
||||||
|
Ainsi, un simple `nix build` vas chercher s'il y à une output
|
||||||
|
`packages.<system>`.default, et le cas échéant, builder cette dernière. `<system>`
|
||||||
|
étant l'architecture courante du système, et il est bien sur possible de remplacer
|
||||||
|
**default** par un nom spécifique de paquet dans le cas où la flake expose plusieurs paquets.
|
||||||
|
Quand à `nix run`, elle va d'abord chercher au niveau de l'output
|
||||||
|
`apps.<system>.default`, et si cette dernière n'est pas présente,
|
||||||
|
`packages.<system>.default`.
|
||||||
|
Il existe tout une variété d'output standard dont il est possible de retrouver
|
||||||
|
la liste dans le manuel de nix.
|
||||||
|

|
||||||
|
<!-- pr:end_slide -->
|
||||||
|
Et donc dans notre cas ?
|
||||||
|
===
|
||||||
|
```file +line_numbers {2-4}
|
||||||
|
path: packaging.nix
|
||||||
|
language: nix
|
||||||
|
```
|
||||||
|
Passons rapidement sur les deux premières lignes, on déclare une jolie description
|
||||||
|
ainsi qu'une input nommée `nixpkgs` dont l'url pointera vers le dernier commit
|
||||||
|
de la branche unstable de nixpgks. Une syntaxe plus standard aurait été
|
||||||
|
`github:Nixos/nixpkgs/nixos-unstable`, ici on utilise flakehub qui est un host
|
||||||
|
centralisé pour toute sorte de flakes.
|
||||||
|
<!-- pr:end_slide -->
|
||||||
|
```file +line_numbers {7-14}
|
||||||
|
path: packaging.nix
|
||||||
|
language: nix
|
||||||
|
```
|
||||||
|
Tout d'abord, on déclare une devShell, qui est le système d'environnement temporaire
|
||||||
|
de nix, fournissant presenterm ainsi que la librairie weasyprint permettant
|
||||||
|
d'exporter les slides au format PDF.
|
||||||
|
La fonction `mkShell` peut prendre plusieurs options dont voici les plus courantes:
|
||||||
|
```nix
|
||||||
|
pkgs.mkShell {
|
||||||
|
# Les packages que vous fournissez à votre environnement
|
||||||
|
packages = with pkgs; [ ];
|
||||||
|
|
||||||
|
# Pour set vos variable d'environnement
|
||||||
|
env = { };
|
||||||
|
|
||||||
|
# Et ici vous pouvez définir un bout de code qui sera exécuter au lancement
|
||||||
|
# de l'environnement.
|
||||||
|
shellHook = '''';
|
||||||
|
};
|
||||||
|
```
|
||||||
|
<!-- pr:end_slide -->
|
||||||
|
|
||||||
|
```file +line_numbers {17-24}
|
||||||
|
path: packaging.nix
|
||||||
|
language: nix
|
||||||
|
```
|
||||||
|
Avant de définir le build process, voyons la configuration de notre paquet.
|
||||||
|
Si vous avez déjà lu les articles précédents, cela ne devrait pas avoir trop
|
||||||
|
de secrets !
|
||||||
|
`inherit (pkgs) system;`: Juste du sucre syntaxique pour ne pas taper
|
||||||
|
`system = pkgs.system;`, oui bon dans le cas présent on gagne pas des masses de
|
||||||
|
temps, mais c'est une bonne pratique à avoir >w<.
|
||||||
|
`name`, `src`, `buildInputs`: Le nom de notre paquet, les sources à fournir lors
|
||||||
|
du build, et les paquets que l'ont fournis à ce dernier, rien de neuf !
|
||||||
|
<!-- pr:end_slide -->
|
||||||
|
```file +line_numbers {25-39}
|
||||||
|
path: packaging.nix
|
||||||
|
language: nix
|
||||||
|
```
|
||||||
|
Bon, ici, j'ai omis quelque lignes histoire de garder l'essentiel.
|
||||||
|
Un problème rencontré lors de l'export des slides en PDF est que le process de
|
||||||
|
build se passe dans un environnement "neutre", créer par nix spécifiquement pour
|
||||||
|
cette tâche et avec le moins possible de variable provenant de l'extérieur, ce
|
||||||
|
afin d'assurer la reproductibilité du process. Ainsi, contrairement au fait de
|
||||||
|
juste lancer la commande `presenterm -e machin.md`, lors de l'exécution de la phase
|
||||||
|
de build, l'exécutable de presenterm n'a ni accès à la police de caractère
|
||||||
|
habituellement fournis par l'émulateur de terminal, ainsi qu'à la taille de ce
|
||||||
|
dernier. Heureusement, presenterm nous permet de fournir une taille statique pour
|
||||||
|
l'export en PDF via un fichier de configuration, ainsi que de définir une police
|
||||||
|
de caractère.
|
||||||
|
Le premier est assez simple, on hardcode juste les options correspondantes
|
||||||
|
(pour le moment) dans le fichier de conf que l'on génère avec writeTextFile.
|
||||||
|
pour la police, ont créé une variable qui pointera vers notre police dans le store,
|
||||||
|
puis on interpolera cette dernière à l'option correspondante dans la config.
|
||||||
|
Pour finir, notre **buildPhase** consiste à définir une variable d'environnement
|
||||||
|
pointant vers la config que l'on a générée afin qu'elle puisse être lue par notre
|
||||||
|
script, puis en l'exécution de ce dernier dont le rôle est d'aller crawler chaque
|
||||||
|
dossier contenant nos posts et d'appeler la commande `presenterm -e` dessus.
|
||||||
|
Je n'inclus pas le dit script ici car je compte le refactorer un peu plus tard
|
||||||
|
pour le rendre plus flexible et donner la possibilité de build un post précis au
|
||||||
|
lieu de tous. Mais globalement voila la magie ! Sur des projets plus complexe on
|
||||||
|
peut utiliser ce genre de mécanisme pour pousser nos packages sur un cache binaire
|
||||||
|
afin d'accélérer les déploiements, ou juste dans le cadre d'une CI. Ici, j'avais
|
||||||
|
juste envie d'expérimenter un peu sur ce mécanisme.
|
||||||
2
src/posts/general_nix/post_packaging/presenterm.yml
Normal file
2
src/posts/general_nix/post_packaging/presenterm.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
options:
|
||||||
|
strict_front_matter_parsing: false
|
||||||
Loading…
x
Reference in New Issue
Block a user