diff --git a/ci.nix b/ci.nix index ea9f6004..9d1c043f 100644 --- a/ci.nix +++ b/ci.nix @@ -7,6 +7,7 @@ let dream2nix-repo = import ./examples/dream2nix-repo { dream2nixSource = ./.; + inherit pkgs; }; dream2nix-repo-flake = (import ./examples/dream2nix-repo-flake/flake.nix).outputs { diff --git a/examples/dream2nix-repo-flake/flake.nix b/examples/dream2nix-repo-flake/flake.nix index 7a7a03cb..f9d0a65c 100644 --- a/examples/dream2nix-repo-flake/flake.nix +++ b/examples/dream2nix-repo-flake/flake.nix @@ -19,7 +19,7 @@ projectRoot = ./.; # can be changed to ".git" or "flake.nix" to get rid of .project-root projectRootFile = "flake.nix"; - packagesDir = "/packages"; + packagesDir = ./packages; packageSets.nixpkgs = nixpkgs.legacyPackages.${system}; }; }; diff --git a/examples/dream2nix-repo/default.nix b/examples/dream2nix-repo/default.nix index 73e90d1c..1edac055 100644 --- a/examples/dream2nix-repo/default.nix +++ b/examples/dream2nix-repo/default.nix @@ -4,16 +4,16 @@ url = "https://github.com/nix-community/dream2nix/tarball/main"; # sha256 = ""; }, + pkgs ? import (import dream2nixSource).inputs.nixpkgs {}, }: let dream2nix = import dream2nixSource; - nixpkgs = import dream2nix.inputs.nixpkgs {}; # all packages defined inside ./packages/ packages = dream2nix.lib.importPackages { projectRoot = ./.; # can be changed to ".git" to get rid of .project-root projectRootFile = ".project-root"; - packagesDir = "/packages"; - packageSets.nixpkgs = nixpkgs; + packagesDir = ./packages; + packageSets.nixpkgs = pkgs; }; in # all packages defined inside ./packages/ diff --git a/modules/dream2nix/core/paths/interface.nix b/modules/dream2nix/core/paths/interface.nix index 4ad7f0bc..7e7bc01a 100644 --- a/modules/dream2nix/core/paths/interface.nix +++ b/modules/dream2nix/core/paths/interface.nix @@ -2,11 +2,13 @@ lib, config, ... -}: { +}: let + cfg = config.paths; +in { options.paths = lib.mapAttrs (_: lib.mkOption) { # mandatory fields projectRoot = { - type = lib.types.path; + type = lib.types.pathInStore; description = '' Path to the root of the project on which dream2nix operates. Must contain the marker file specified by 'paths.projectRootFile' @@ -16,13 +18,22 @@ example = lib.literalExpression "./."; }; package = { - type = lib.types.str; + type = lib.types.either lib.types.path lib.types.str; description = '' Path to the directory containing the definition of the current package. Relative to 'paths.projectRoot'. This helps locating package definitions for lock & update scripts. ''; + apply = path': let + projectRoot = toString cfg.projectRoot; + path = toString path'; + in + if path == projectRoot + then "./." + else if lib.hasPrefix projectRoot path + then lib.path.subpath.normalise "./${lib.removePrefix projectRoot path}" + else lib.path.subpath.normalise "./${path}"; }; # optional fields diff --git a/modules/dream2nix/php-granular/interface.nix b/modules/dream2nix/php-granular/interface.nix index 024c2680..d46ecd63 100644 --- a/modules/dream2nix/php-granular/interface.nix +++ b/modules/dream2nix/php-granular/interface.nix @@ -20,7 +20,7 @@ in { })); }; composerInstallFlags = { - type = t.listOf t.string; + type = t.listOf t.str; default = []; }; }; diff --git a/modules/flake-parts/examples.nix b/modules/flake-parts/examples.nix index aadd873e..5325606c 100644 --- a/modules/flake-parts/examples.nix +++ b/modules/flake-parts/examples.nix @@ -30,6 +30,15 @@ packagePath = "/examples/packages/${dirName}/${name}"; }); + importFlake = flakeFile: let + self' = (import flakeFile).outputs { + dream2nix = self; + nixpkgs = inputs.nixpkgs; + self = self'; + }; + in + self'; + # Type: [ {${name} = {module, packagePath} ] allExamples = mapAttrsToList (dirName: _: readExamples dirName) packageCategories; @@ -96,7 +105,16 @@ in { in { # map all modules in /examples to a package output in the flake. checks = - lib.mapAttrs (_: drvModules: makeDrv drvModules) - allModules; + (lib.mapAttrs (_: drvModules: makeDrv drvModules) allModules) + // { + example-repo = + (import (self + /examples/dream2nix-repo) { + dream2nixSource = self; + inherit pkgs; + }) + .hello; + example-repo-flake = + (importFlake (self + /examples/dream2nix-repo-flake/flake.nix)).packages.${system}.hello; + }; }; } diff --git a/modules/flake-parts/lib.nix b/modules/flake-parts/lib.nix index 83a4f0b4..cdcf3f78 100644 --- a/modules/flake-parts/lib.nix +++ b/modules/flake-parts/lib.nix @@ -13,9 +13,11 @@ packagesDir, ... }: let + projectRoot = toString args.projectRoot; + packagesDir = toString args.packagesDir; packagesDirPath = - if ! builtins.isString packagesDir - then throw "packagesDir must be a string" + if lib.hasPrefix projectRoot packagesDir + then packagesDir else projectRoot + "/${packagesDir}"; forwardedArgs = builtins.removeAttrs args [ "projectRoot" @@ -36,7 +38,7 @@ { paths.projectRoot = projectRoot; paths.projectRootFile = projectRootFile; - paths.package = "/${packagesDir}/${module}"; + paths.package = packagesDir + "/${module}"; } ]; }) diff --git a/tests/nix-unit/test_paths/default.nix b/tests/nix-unit/test_paths/default.nix new file mode 100644 index 00000000..6a2e374e --- /dev/null +++ b/tests/nix-unit/test_paths/default.nix @@ -0,0 +1,84 @@ +{ + pkgs ? import {}, + lib ? import , + dream2nix ? (import (../../../modules + "/flake.nix")).outputs {}, +}: let + eval = module: + (lib.evalModules { + modules = [ + dream2nix.modules.dream2nix.core + module + ]; + specialArgs = { + inherit dream2nix; + packageSets.nixpkgs = pkgs; + }; + }) + .config; +in { + test_package_in_root_1 = let + config = eval { + paths.projectRoot = "${./.}"; + paths.package = "${./.}"; + }; + in { + expr = {inherit (config.paths) projectRoot package;}; + expected = { + projectRoot = "${./.}"; + package = "./."; + }; + }; + + test_package_in_root_2 = let + config = eval { + paths.projectRoot = "${./.}"; + paths.package = "./."; + }; + in { + expr = {inherit (config.paths) projectRoot package;}; + expected = { + projectRoot = "${./.}"; + package = "./."; + }; + }; + + test_package_in_subdir_1 = let + config = eval { + paths.projectRoot = "${./.}"; + paths.package = "${./.}/package"; + }; + in { + expr = {inherit (config.paths) projectRoot package;}; + expected = { + projectRoot = "${./.}"; + package = "./package"; + }; + }; + + test_package_in_subdir_2 = let + config = eval { + paths.projectRoot = "${./.}"; + paths.package = "./package"; + }; + in { + expr = {inherit (config.paths) projectRoot package;}; + expected = { + projectRoot = "${./.}"; + package = "./package"; + }; + }; + + test_package_in_subdir_3 = let + self = /nix/store/some/path; + config = eval { + paths.projectRoot = self; + paths.package = self + /package; + }; + in { + expr = {inherit (config.paths) projectRoot package;}; + expected = { + projectRoot = self; + package = "./package"; + }; + }; +}