codeberg-cli 0.5.5

CLI Tool for codeberg similar to gh and glab
Documentation
{ 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);
    };
}