From 140dd34d49eea97618616b9a501644673b56519e Mon Sep 17 00:00:00 2001 From: Nicolas Mattia Date: Sat, 22 Feb 2020 17:38:00 +0100 Subject: [PATCH] Get rid of cabal2nix The `callCabal2nix` invocation caused `cabal2nix` to be downloaded on every install of `niv`. This introduces `foo`, a Nix function that does exactly the same. --- default.nix | 2 +- foo/default.nix | 83 ++++++++++++++++++++++++++++ package.yaml | 140 +++++++++++++++++++++++++----------------------- 3 files changed, 157 insertions(+), 68 deletions(-) create mode 100644 foo/default.nix diff --git a/default.nix b/default.nix index 0af48b6..53d5bff 100644 --- a/default.nix +++ b/default.nix @@ -51,7 +51,7 @@ with rec pkgs.haskell.lib.disableExecutableProfiling ( pkgs.haskell.lib.disableLibraryProfiling ( pkgs.haskell.lib.generateOptparseApplicativeCompletion "niv" ( - haskellPackages.callCabal2nix "niv" niv-source {} + (pkgs.callPackage ./foo {}).buildPackage { root = ./.; src = niv-source; } ) ) ) diff --git a/foo/default.nix b/foo/default.nix new file mode 100644 index 0000000..fc58c68 --- /dev/null +++ b/foo/default.nix @@ -0,0 +1,83 @@ +{ haskellPackages +, stdenv +, lib +}: + +{ + buildPackage = + attrs: + let + src = if !lib.isDerivation attrs && lib.isAttrs attrs then attrs.src else attrs; + root = if !lib.isDerivation attrs && lib.isAttrs attrs then attrs.root else attrs; + nubdeps = ds: lib.lists.sort (x: y: x < y) ( + lib.unique ( + map (d: lib.head (lib.splitString " " d)) ds + ) + ); + spec = builtins.fromJSON (builtins.readFile (root + "/package.yaml")); + commonDeps = spec.dependencies; + + libraryExtraDeps = + lib.optionals + (spec ? library && spec.library ? dependencies) + spec.library.dependencies; + libraryDeps = nubdeps (commonDeps ++ libraryExtraDeps); + + exeExtraDeps = lib.optionals (spec ? executables) ( + lib.concatMap + ( + exe: lib.optionals + (exe ? dependencies) exe.dependencies + ) + (builtins.attrValues spec.executables) + ); + exeDeps = + nubdeps + ( + builtins.filter (x: x != spec.name) + (commonDeps ++ exeExtraDeps) + ); + + testExtraDeps = lib.optionals (spec ? tests) ( + lib.concatMap + ( + test: lib.optionals + (test ? dependencies) test.dependencies + ) + (builtins.attrValues spec.tests) + ); + testDeps = nubdeps (builtins.filter (x: x != spec.name) (commonDeps ++ testExtraDeps)); + + depsFor = depType: + map ( + d: + if ! builtins.hasAttr d haskellPackages + then throw "haskellPackages does not contain dependency '${d}' needed for '${depType}'" + else + haskellPackages.${d} + ); + + in + haskellPackages.callPackage ( + { mkDerivation }: + haskellPackages.mkDerivation { + pname = spec.name; + version = spec.version; + inherit src; + isLibrary = builtins.hasAttr "library" spec; + isExecutable = builtins.hasAttr "executables" spec; + enableSeparateDataOutput = true; + libraryHaskellDepends = depsFor "libraryHaskellDepends" libraryDeps; + libraryToolDepends = [ haskellPackages.hpack ]; + executableHaskellDepends = depsFor "executableHaskellDepends" exeDeps; + testHaskellDepends = depsFor "testHaskellDepends" testDeps; + prePatch = "hpack"; + homepage = "https://github.com/${spec.github}#readme"; + description = spec.synopsis; + license = + if builtins.hasAttr "license" spec && spec.license == "MIT" + then stdenv.lib.licenses.mit + else throw "Don't know how to handle license: ${builtins.toJSON spec.license}"; + } + ) {}; +} diff --git a/package.yaml b/package.yaml index 5dee879..11ebbd3 100644 --- a/package.yaml +++ b/package.yaml @@ -1,67 +1,73 @@ -name: niv -version: 0.2.13 -license: MIT -author: Nicolas Mattia -maintainer: Nicolas Mattia -copyright: (c) 2019 Nicolas Mattia -category: Development -github: nmattia/niv -synopsis: Easy dependency management for Nix projects -description: Easy dependency management for Nix projects. - -ghc-options: - - -Wall - - # For macOS: https://github.com/gibiansky/IHaskell/issues/942 - - -optP-Wno-nonportable-include-path - -data-files: - - nix/sources.nix - -extra-source-files: - - README.md - -dependencies: - - aeson - - aeson-pretty - - ansi-terminal - - base < 5 - - bytestring - - directory - - file-embed - - filepath - - hashable - - http-conduit - - mtl - - optparse-applicative - - process - - profunctors - - pureMD5 - - string-qq - - text - - unliftio - - unordered-containers - -library: - source-dirs: - - src - dependencies: - - aeson - - tasty - - tasty-hunit - - unordered-containers - -executables: - niv: - main: Niv.main - source-dirs: app - dependencies: - - niv - -tests: - unit: - main: NivTest.main - source-dirs: app - dependencies: - - tasty - - niv +{ + "name": "niv", + "version": "0.2.13", + "license": "MIT", + "author": "Nicolas Mattia ", + "maintainer": "Nicolas Mattia ", + "copyright": "(c) 2019 Nicolas Mattia", + "category": "Development", + "github": "nmattia/niv", + "synopsis": "Easy dependency management for Nix projects", + "description": "Easy dependency management for Nix projects.", + "ghc-options": [ + "-Wall", + "-optP-Wno-nonportable-include-path" + ], + "data-files": [ + "nix/sources.nix" + ], + "extra-source-files": [ + "README.md" + ], + "dependencies": [ + "aeson", + "aeson-pretty", + "ansi-terminal", + "base < 5", + "bytestring", + "directory", + "file-embed", + "filepath", + "hashable", + "http-conduit", + "mtl", + "optparse-applicative", + "process", + "profunctors", + "pureMD5", + "string-qq", + "text", + "unliftio", + "unordered-containers" + ], + "library": { + "source-dirs": [ + "src" + ], + "dependencies": [ + "aeson", + "tasty", + "tasty-hunit", + "unordered-containers" + ] + }, + "executables": { + "niv": { + "main": "Niv.main", + "source-dirs": "app", + "dependencies": [ + "niv" + ] + } + }, + "tests": { + "unit": { + "main": "NivTest.main", + "source-dirs": "app", + "dependencies": [ + "tasty", + "niv" + ] + } + } +}