# mill-scale -- Another rust module for flakelight # Copyright (C) 2024 Robin Appelman # SPDX-License-Identifier: MIT { lib, src, config, flakelight, ... }: let inherit (builtins) elem readFile pathExists match fromJSON attrNames head; inherit (lib) getExe mkDefault mkIf mkMerge mkOption warnIf optionalAttrs types; inherit (lib.fileset) fileFilter toSource unions; inherit (flakelight.types) fileset function; phpVersions = { "5.6" = pkgs: pkgs.php56; "7.0" = pkgs: pkgs.php70; "7.1" = pkgs: pkgs.php71; "7.2" = pkgs: pkgs.php72; "7.3" = pkgs: pkgs.php73; "7.4" = pkgs: pkgs.php74; "8.0" = pkgs: pkgs.php80; "8.1" = pkgs: pkgs.php81; "8.2" = pkgs: pkgs.php82; "8.3" = pkgs: pkgs.php83; "8.4" = pkgs: pkgs.php84; }; filteredSrc = toSource { root = src; fileset = unions (config.extraPaths ++ [config.fileset]); }; composerJson = fromJSON (readFile config.composerJson); composerMeta = (import ./composer-meta.nix { inherit lib; allVersions = attrNames phpVersions; }) composerJson; hasPsalm = pathExists config.psalmConfig; hasPhpCsFixer = pathExists config.phpCsFixerConfig; buildPhp = pkgs: (phpVersions.${head composerMeta.phpVersions} pkgs).buildEnv { extensions = { enabled, all, }: enabled ++ (config.phpExtensions all); }; in warnIf (! builtins ? readFileType) "Unsupported Nix version in use." { options = { composerJson = mkOption { type = with types; path; default = src + /composer.json; }; composerLock = mkOption { type = with types; path; default = src + /composer.lock; }; psalmConfig = mkOption { type = with types; path; default = src + /psalm.xml; }; phpCsFixerConfig = mkOption { type = with types; path; default = src + /.php-cs-fixer.dist.php; }; extraPaths = mkOption { type = with types; listOf path; default = []; }; fileset = mkOption { type = fileset; default = fileFilter (file: file.hasExt "php" || file.hasExt "phpstub" || match "snapshot__.*\.snap" file.name != null || elem file.name [".php-cs-fixer.dist.php" "psalm.xml" "package.json" "package.lock"]) src; }; phpExtensions = mkOption { type = function; default = all: []; description = "extra php extensions to enable"; }; tools = mkOption { type = function; default = pkgs: []; description = "extra packages to make available in the dev shells"; }; vendorHash = mkOption { type = with types; str; }; }; config = mkMerge [ (mkIf (pathExists config.composerJson) { withOverlays = [ (final: prev: { minPhp = buildPhp final; vendor = final.callPackage ./pkgs/vendor.nix { php = final.minPhp; inherit (config) composerJson composerLock vendorHash; }; inherit composerMeta filteredSrc; inherit (final.minPhp.packages) php-cs-fixer composer psalm; }) ]; description = mkIf (composerMeta ? description) composerMeta.description; license = mkIf (composerMeta ? license) (mkDefault composerMeta.license); pname = composerMeta.name; outputs = { lib = { phpVersions = composerMeta.phpVersions; inherit hasPsalm hasPhpCsFixer; }; }; packages = { vendor = pkgs: pkgs.vendor; }; checks = {pkgs, ...}: (optionalAttrs hasPsalm { psalm = pkgs.callPackage ./checks/psalm.nix { src = filteredSrc; }; }); }) { devShells = { default = { packages = pkgs: (config.tools pkgs) ++ (with pkgs; [minPhp php-cs-fixer composer psalm]); }; }; formatters = pkgs: with pkgs; ({ "*.nix" = getExe alejandra; } // optionalAttrs hasPhpCsFixer { "*.php" = "${getExe php-cs-fixer} fix"; "*.phpstub" = "${getExe php-cs-fixer} fix"; }); } ]; }