67 lines
2.0 KiB
Nix
67 lines
2.0 KiB
Nix
# Builds a skill source directory into a derivation, `SKILL.md` at the `$out` root.
|
|
{
|
|
pkgs,
|
|
src,
|
|
name ? builtins.baseNameOf (toString src),
|
|
commands ? [ ],
|
|
}:
|
|
let
|
|
lib = pkgs.lib;
|
|
|
|
patchEnvDefault = command: envName: value:
|
|
let
|
|
marker = "# mkSkill:${envName}";
|
|
replacement = '': "''${${envName}:=${value}}" ${marker}'';
|
|
in
|
|
''
|
|
if ! awk -v marker=${lib.escapeShellArg marker} -v replacement=${lib.escapeShellArg replacement} '
|
|
index($0, marker) { print replacement; found = 1; next }
|
|
{ print }
|
|
END { if (!found) exit 42 }
|
|
' "$_mkskill_command" > "$_mkskill_command.tmp"; then
|
|
rm -f "$_mkskill_command.tmp"
|
|
echo "mkSkill: command '${command.path}' has no ${marker} marker" >&2
|
|
exit 1
|
|
fi
|
|
mv "$_mkskill_command.tmp" "$_mkskill_command"
|
|
chmod +x "$_mkskill_command"
|
|
'';
|
|
|
|
patchCommand = command:
|
|
let
|
|
env = command.env or { };
|
|
in
|
|
''
|
|
_mkskill_command="$out/${command.path}"
|
|
test -f "$_mkskill_command" \
|
|
|| { echo "mkSkill: command '${command.path}' does not exist" >&2; exit 1; }
|
|
test -x "$_mkskill_command" \
|
|
|| { echo "mkSkill: command '${command.path}' is not executable" >&2; exit 1; }
|
|
${lib.concatStringsSep "\n" (lib.mapAttrsToList (patchEnvDefault command) env)}
|
|
'';
|
|
|
|
patchCommands = lib.concatStringsSep "\n" (map patchCommand commands);
|
|
in
|
|
pkgs.stdenvNoCC.mkDerivation {
|
|
inherit name src;
|
|
|
|
# A skill is just files to copy, with nothing to unpack, configure, or build.
|
|
dontUnpack = true;
|
|
dontConfigure = true;
|
|
dontBuild = true;
|
|
|
|
installPhase = ''
|
|
runHook preInstall
|
|
mkdir -p "$out"
|
|
cp -R "$src"/. "$out/"
|
|
test -f "$out/SKILL.md" \
|
|
|| { echo "mkSkill: skill '${name}' has no SKILL.md at its root" >&2; exit 1; }
|
|
${patchCommands}
|
|
runHook postInstall
|
|
'';
|
|
|
|
# The name as an eval-time attribute, readable without building `$out`
|
|
# (no import-from-derivation).
|
|
passthru.skillName = name;
|
|
}
|