{
lib,
root,
}: let
fs = lib.fileset;
module = lib.removePrefix "module " (lib.head (lib.splitString "\n" (builtins.readFile (root + "/go.mod"))));
matches = regex: text: map lib.head (lib.filter lib.isList (builtins.split regex text));
# subpackages come in through their own imports, so a dir contributes only its own files
dirFiles = dir: let
entries = builtins.readDir (root + "/${dir}");
in
map (name: "${dir}/${name}")
(lib.filter (name: entries.${name} == "regular" && !(lib.hasSuffix "_test.go" name)) (lib.attrNames entries));
sources = dir: map (file: builtins.readFile (root + "/${file}")) (lib.filter (lib.hasSuffix ".go") (dirFiles dir));
imports = dir: lib.unique (lib.concatMap (matches "\"${lib.escapeRegex module}/([^\"]+)\"") (sources dir));
# a pattern's first segment is a file or dir under the package; globs there are covered by dirFiles
embeds = dir: let
patterns = lib.concatMap (lib.splitString " ") (lib.concatMap (matches "//go:embed ([^\n]+)") (sources dir));
first = pattern: lib.head (lib.splitString "/" (lib.removePrefix "all:" (lib.replaceStrings ["\""] [""] pattern)));
in
map (segment: "${dir}/${segment}")
(lib.filter (segment: segment != "" && builtins.match ".*[*?[].*" segment == null) (map first patterns));
closure = start: let
walk = seen: todo:
if todo == []
then seen
else let
next = lib.filter (dir: !(lib.elem dir seen)) (imports (lib.head todo));
in
walk (seen ++ next) (lib.tail todo ++ next);
in
walk [start] [start];
in
package: let
dirs = closure package;
in
fs.toSource {
inherit root;
fileset = fs.unions (map (file: root + "/${file}") (["go.mod" "go.sum"] ++ lib.concatMap (dir: dirFiles dir ++ embeds dir) dirs));
}