{ description = "Hello World flake templates for various languages and build systems"; outputs = { self, ... }: with builtins; let concatMapAttrs = func: attr: foldl' (x: y: x // y) {} (map func attr); # Display names of languages for template descriptions display-names = { bash = "Bash"; fish = "Fish"; c = "C"; python = "Python"; rust = "Rust"; }; # Template Aliases # Used to pick default template for each language aliases = { bash = "bash_script_nixpkgs"; fish = "fish_script_nixpkgs"; c = "c_make_nixpkgs"; python = "python_pyproject_nixpkgs_basic"; rust = "rust_cargo-nightly_crane+fenix"; }; # Files to filter out of the template template-ignore = [ "flake.lock" "Cargo.lock" ]; # Get all subdirectories of the given path # Returns [str] subdirs = dir: let subd = readDir dir; in filter (d: subd.${d} == "directory") (attrNames subd); # Get all proper recursive subdirectories with flakes in them # Returns [[str]] (list of subdirectory sequences, for processing) flakeSubdirs = dir: concatMap (subd: if pathExists /${dir}/${subd}/flake.nix then [ [ subd ] ] else map (l: [ subd ] ++ l) (flakeSubdirs /${dir}/${subd})) (subdirs dir); generateDesc = fields: let lang = head fields; in "${display-names.${lang} or lang} template (${concatStringsSep ", " (tail fields)})"; in { templates = concatMapAttrs (fields: { ${concatStringsSep "_" fields} = { description = generateDesc fields; path = filterSource (p: _: !(elem (baseNameOf p) template-ignore)) (foldl' (dir: subd: /${dir}/${subd}) ./. fields); }; }) (flakeSubdirs ./.) // mapAttrs (from: to: self.templates.${to}) aliases; }; }