Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dhall-to-nixpkgs #1826

Merged
merged 14 commits into from Jun 19, 2020
Merged

Add dhall-to-nixpkgs #1826

merged 14 commits into from Jun 19, 2020

Conversation

Gabriella439
Copy link
Collaborator

This adds a new dhall-nixpkgs project which builds a dhall-nixpkgs
executable. This executable is the Dhall analog of cabal2nix, which
takes a directory or GitHub project as input and generates a buildable
Nix package as its output.

Example output:

$ dhall-to-nixpkgs github https://github.com/Gabriel439/dhall-semver.git
{ buildDhallGitHubPackage, Prelude }:
  buildDhallGitHubPackage {
    name = "dhall-semver";
    githubBase = "github.com";
    owner = "Gabriel439";
    repo = "dhall-semver";
    rev = "7f5b7bf0e89664571522de9919edcc8469a55320";
    fetchSubmodules = false;
    sha256 = "00vi74npwbhwn2lnjpw4zv5y9kjqysc2f1wg1zncps6k5wljnwb7";
    directory = "";
    file = "package.dhall";
    source = false;
    dependencies = [ (Prelude.override { file = "package.dhall"; }) ];
    }
$ dhall-to-nixpkgs directory ~/proj/dhall-packages/
{ buildDhallDirectoryPackage, dhall-kubernetes, Prelude, dhall-packages }:
  buildDhallDirectoryPackage {
    name = "dhall-packages";
    src = /home/gabriel/proj/dhall-packages;
    file = "package.dhall";
    source = false;
    dependencies = [
      (dhall-kubernetes.override { file = "1.15/package.dhall"; })
      (Prelude.override { file = "JSON/Type"; })
      (Prelude.override { file = "JSON/package.dhall"; })
      (dhall-kubernetes.override { file = "1.16/package.dhall"; })
      (dhall-kubernetes.override { file = "1.17/package.dhall"; })
      (dhall-kubernetes.override {
        file = "types/io.k8s.api.core.v1.ServiceSpec.dhall";
        })
      (dhall-kubernetes.override {
        file = "types/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta.dhall";
        })
      (dhall-kubernetes.override {
        file = "types/io.k8s.apimachinery.pkg.apis.meta.v1.Time.dhall";
        })
      (dhall-kubernetes.override {
        file = "types/io.k8s.api.core.v1.PodTemplateSpec.dhall";
        })
      (dhall-kubernetes.override {
        file = "types/io.k8s.api.core.v1.SecretKeySelector.dhall";
        })
      (dhall-kubernetes.override {
        file = "types/io.k8s.apimachinery.pkg.apis.meta.v1.MicroTime.dhall";
        })
      (dhall-kubernetes.override {
        file = "types/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta.dhall";
        })
      (Prelude.override { file = "Map/Type"; })
      (dhall-packages.override { file = "kubernetes/k8s/1.15.dhall"; })
      (Prelude.override { file = "package.dhall"; })
      ];
    }

This requires the following matching changes to Nixpkgs in order to work:

  • Two new buildDhall{Directory,GitHub}Package utilities have to be
    added

    ... which are used by the generated output

  • The Dhall package set in Nixpkgs now needs to select default versions
    for packages

    In other words, pkgs.dhallPackages.Prelude should select a default
    version of the Prelude (ideally the latest version)

    This parallels how the Haskell package set works, by selecting a
    default version for each package, the latest version possible that
    produces a consistent package set.

This adds a new `dhall-nixpkgs` project which builds a `dhall-nixpkgs`
executable.  This executable is the Dhall analog of `cabal2nix`, which
takes a directory or GitHub project as input and generates a buildable
Nix package as its output.

Example output:

```bash
$ dhall-to-nixpkgs github https://github.com/Gabriel439/dhall-semver.git
```
```nix
{ buildDhallGitHubPackage, Prelude }:
  buildDhallGitHubPackage {
    name = "dhall-semver";
    githubBase = "github.com";
    owner = "Gabriel439";
    repo = "dhall-semver";
    rev = "7f5b7bf0e89664571522de9919edcc8469a55320";
    fetchSubmodules = false;
    sha256 = "00vi74npwbhwn2lnjpw4zv5y9kjqysc2f1wg1zncps6k5wljnwb7";
    directory = "";
    file = "package.dhall";
    source = false;
    dependencies = [ (Prelude.override { file = "package.dhall"; }) ];
    }
```

```bash
$ dhall-to-nixpkgs directory ~/proj/dhall-packages/
```
```nix
{ buildDhallDirectoryPackage, dhall-kubernetes, Prelude, dhall-packages }:
  buildDhallDirectoryPackage {
    name = "dhall-packages";
    src = /home/gabriel/proj/dhall-packages;
    file = "package.dhall";
    source = false;
    dependencies = [
      (dhall-kubernetes.override { file = "1.15/package.dhall"; })
      (Prelude.override { file = "JSON/Type"; })
      (Prelude.override { file = "JSON/package.dhall"; })
      (dhall-kubernetes.override { file = "1.16/package.dhall"; })
      (dhall-kubernetes.override { file = "1.17/package.dhall"; })
      (dhall-kubernetes.override {
        file = "types/io.k8s.api.core.v1.ServiceSpec.dhall";
        })
      (dhall-kubernetes.override {
        file = "types/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta.dhall";
        })
      (dhall-kubernetes.override {
        file = "types/io.k8s.apimachinery.pkg.apis.meta.v1.Time.dhall";
        })
      (dhall-kubernetes.override {
        file = "types/io.k8s.api.core.v1.PodTemplateSpec.dhall";
        })
      (dhall-kubernetes.override {
        file = "types/io.k8s.api.core.v1.SecretKeySelector.dhall";
        })
      (dhall-kubernetes.override {
        file = "types/io.k8s.apimachinery.pkg.apis.meta.v1.MicroTime.dhall";
        })
      (dhall-kubernetes.override {
        file = "types/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta.dhall";
        })
      (Prelude.override { file = "Map/Type"; })
      (dhall-packages.override { file = "kubernetes/k8s/1.15.dhall"; })
      (Prelude.override { file = "package.dhall"; })
      ];
    }
```

This requires the following matching changes to Nixpkgs in order to work:

* Two new `buildDhall{Directory,GitHub}Package` utilities have to be
  added

  ... which are used by the generated output

* The Dhall package set in Nixpkgs now needs to select default versions
  for packages

  In other words, `pkgs.dhallPackages.Prelude` should select a default
  version of the Prelude (ideally the latest version)

  This parallels how the Haskell package set works, by selecting a
  default version for each package, the latest version possible that
  produces a consistent package set.
@Gabriella439
Copy link
Collaborator Author

Here's the matching change to Nixpkgs: NixOS/nixpkgs#89237

Copy link
Collaborator

@sjakobi sjakobi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So is the main purpose of this tool to make it easy to integrate Dhall packages into Nix setups? Could you maybe say a bit about the background / context?

I've started reviewing the code a bit, but I haven't made it all the way through yet. I'm sure this is the most complex code I've seen in this repository so far! A good learning opportunity I guess! ;)

Of course, I'm also still way too unfamiliar with Nix…

Feel free to merge if you want to get this out quickly. Or keep it open a bit longer if you want a more in-depth review…

dhall-nixpkgs/Main.hs Outdated Show resolved Hide resolved
dhall-nixpkgs/Main.hs Show resolved Hide resolved
dhall-nixpkgs/Main.hs Outdated Show resolved Hide resolved
toListWith _ Nothing = [ ]

nub :: Ord a => [a] -> [a]
nub = Foldl.fold Foldl.nub
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also available from containers BTW: http://hackage.haskell.org/package/containers-0.6.2.1/docs/Data-Containers-ListUtils.html#v:nubOrd

But apparently only from v0.6.0.1 / GHC 8.6 on…

This function finds all remote imports that are transitive dependencies of
the given expression, failing if any of them are missing integrity checks.
-}
findExternalDependencies :: Expr Src Import -> StateT Status Shell URL
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of the Shell monad here? I don't quite understand how it's being used here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dhall-nixpkgs/Main.hs Outdated Show resolved Hide resolved
dhall-nixpkgs/Main.hs Outdated Show resolved Hide resolved
dhall-nixpkgs/Main.hs Show resolved Hide resolved
dhall-nixpkgs/Main.hs Outdated Show resolved Hide resolved
Copy link
Collaborator

@german1608 german1608 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know to much about Nix so I only reviewed code structure and LGTM!

I see that you used a lot of NeatInterpolations. Why don't we use them in other places of our project? Is it more efficient than concatenating Texts with (<>)?

I think that error messages construction in other modules could benefit from using NeatInterpolation since I see them way more readable, but that could go in another PR 😃

Gabriella439 and others added 7 commits May 31, 2020 20:12
It's no longer necessary
... as suggested by @sjakobi

Co-authored-by: Simon Jakobi <simon.jakobi@gmail.com>
... to clarify some questions that @sjakobi raised

Note that really the long-term place where this documentation will go
is in a new "Dhall" subsection of the Nixpkgs manual.  This module
header is just a temporary stopgap until the Nixpkgs manual entry can
be fully fleshed out.
@Gabriella439
Copy link
Collaborator Author

At this point I'm mainly waiting on NixOS/nixpkgs#89237 to be approved, too, before merging this

Copy link
Collaborator

@sjakobi sjakobi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing all my comments, @Gabriel439! :)

I still haven't properly grokked this though. I'll have to learn more about Nix first, I guess! ;)

Playing with it should also help…

@Gabriel439 Maybe also add this to the packages list in the main README?

dhall-nixpkgs/Main.hs Outdated Show resolved Hide resolved
dhall-nixpkgs/Main.hs Show resolved Hide resolved
@Anton-Latukha
Copy link

Anton-Latukha commented Jun 5, 2020

You can review this code later. HNix is 0.8.0, and it now uses GHC 8.8 by default: https://matrix.hackage.haskell.org/#/package/hnix and all its dependencies are up to the day, and we would look to keep it so and progress further.

Profpatsch pushed a commit to NixOS/nixpkgs that referenced this pull request Jun 17, 2020
The motivation for this change is to enable a new Dhall command-line
utility called `dhall-to-nixpkgs` which converts Dhall packages to
buildable Nix packages.  You can think of `dhall-to-nixpkgs` as the
Dhall analog of `cabal2nix`.

You can find the matching pull request for `dhall-to-nixpkgs` here:

dhall-lang/dhall-haskell#1826

The two main changes required to support `dhall-to-nixpkgs` are:

* Two new `buildDhall{Directory,GitHub}Package` utilities are added

  `dhall-to-nixpkgs` uses these in the generated output

* `pkgs.dhallPackages` now selects a default version for each package
  using the `prefer` utility

  All other versions are still buildable via a `passthru` attribute
@Gabriella439 Gabriella439 merged commit 50df284 into master Jun 19, 2020
@Gabriella439 Gabriella439 deleted the gabriel/dhall-to-nixpkgs_2 branch June 19, 2020 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants