{ inputs, ... }:
let
sharedLib = inputs.self.sharedLib;
in
{
flake.tapeTestLib =
{
self',
lib,
pkgs,
}:
rec {
scopes = sharedLib.allScopes |> map (scope: "write:${scope}") |> lib.concatStringsSep ",";
# creates a file that is consumable by the `vhs` tool
makeTape =
{
outfile,
setup,
exec,
}:
pkgs.writeTextFile {
name = "${outfile}.tape";
text = ''
# This is an undocumented environment variable to run vhs as root
# see: https://github.com/charmbracelet/vhs/pull/195
Env VHS_NO_SANDBOX "true"
# Set up a 1200x600 terminal with 46px font.
Set FontSize 46
Set Width 1200
Set Height 600
Set TypingSpeed 1ms
Set Theme "Catppuccin Mocha"
# Where should we write the GIF?
Output ${outfile}
Hide
${
setup
|> map (command: ''
Type "${command}"
Enter
Sleep 250ms
'')
|> builtins.concatStringsSep ""
}
Ctrl+L
Sleep 250ms
Show
${exec |> builtins.concatStringsSep "\n"}
'';
};
# creates the test script to execute a `tape` with the `vhs` tool in a dev vm
makeTapeScript =
{
name,
setup ? [ ],
exec,
}:
let
tapefile = "${name}.tape";
outfile = "${name}.gif";
setup' = [
"echo http://${sharedLib.user}:${sharedLib.pass}@${sharedLib.forgejo.hostname}:${toString sharedLib.forgejo.port} >> ~/.git-credentials"
]
++ setup;
tape = makeTape {
setup = setup';
inherit outfile exec;
};
in
''
start_all()
forgejo.wait_for_open_port(${toString sharedLib.forgejo.port})
forgejo.copy_from_host("${tape}", "${tapefile}")
forgejo.succeed("${sharedLib.forgejo.run} create --email ${sharedLib.email} --username ${sharedLib.user} --password ${sharedLib.pass}")
token = forgejo.succeed("${sharedLib.forgejo.run} generate-access-token --username ${sharedLib.user} --scopes '${scopes}' --raw").strip()
forgejo.succeed(f"sed -i \"s|TOKEN|{token}|g\" ${tapefile}")
forgejo.succeed("vhs ${tapefile}")
forgejo.copy_from_vm("${outfile}", "")
'';
tapeTest =
{
name,
extraSetup ? [ ],
exec,
}:
pkgs.testers.runNixOSTest {
name = "${name}-tape";
nodes.forgejo = (sharedLib.forgejo.baseConfig { inherit self' lib pkgs; }) // {
imports = [
{
virtualisation = {
# we run a browser so this needs more mem -> otherwise OOM
memorySize = 1024 * 3;
cores = 2;
};
# without this the output looks shitty
fonts = {
fontDir.enable = true;
fontconfig.enable = true;
packages = [
pkgs.nerd-fonts.iosevka-term
pkgs.nerd-fonts.iosevka-term-slab
];
};
environment.systemPackages = [
pkgs.firefox
pkgs.vhs
];
}
];
};
testScript = makeTapeScript {
inherit name exec;
setup = extraSetup;
};
};
embeddInFlake =
testAttrs:
testAttrs
|> lib.mapAttrs' (
testName: testConfig: {
name = testName + "-tape";
value = testConfig // {
name = testName;
};
}
)
|> builtins.mapAttrs (_: tapeTest);
};
}