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 flake-parts module #14

Merged
merged 14 commits into from
Dec 24, 2022
Merged

Conversation

srid
Copy link
Contributor

@srid srid commented Dec 21, 2022

I'm opening a draft PR (instead of waiting for full implementation) just to get something working, as well as to get any early feedback. The commits in this PR can be squash merged (or I can rebase them if necessary) once ready.

This PR adds a flake-parts module for working with treefmt in the most ergonomic way. It also adds a flake check to test in CI that the source tree is formatted. You can see a demo here: srid/haskell-template#75

Resolves #1

  • Can the types.raw be replaced with appropriate types? See also: API feedback #2
  • Add documentation

Copy link
Contributor

@roberth roberth left a comment

Choose a reason for hiding this comment

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

Maybe I should read more of the treefmt implementation, but I'm confused by the supposed submodule-ish options in this PR. Doesn't treefmt already do its things in modules, that just need to be imported?

flake-module.nix Outdated Show resolved Hide resolved
@srid
Copy link
Contributor Author

srid commented Dec 21, 2022

Maybe I should read more of the treefmt implementation, but I'm confused by the supposed submodule-ish options in this PR. Doesn't treefmt already do its things in modules, that just need to be imported?

The module options are spread across several files: there is one module called module-options and several program specific ones in the programs directory. They are passed to evalModules here:

treefmt-nix/default.nix

Lines 23 to 25 in 4230552

module-options
]
++ programs.modules

Is there a straightforward way to "merge" them to produce a single submodule for use in flake-parts options?

@roberth
Copy link
Contributor

roberth commented Dec 21, 2022

Is there a straightforward way to "merge" them to produce a single submodule for use in flake-parts options?

imports = [ ], or submoduleWith { modules = [ ... ]; } instead of submodule.

Another trick is you could use (<<treefmt>>.evalModule foo {}).type, which is a submodule type with all treefmt stuff in it. This doesn't show intent like it should, so perhaps it's better to refactor lib.nix a bit to extract the logic leading up to lib.evalModules into a function. Then you can do submoduleWith { modules = <<treefmt>>.prepareModule foo bar; }. It's the same thing, but less likely to be accidentally broken.

Copy link
Member

@zimbatm zimbatm left a comment

Choose a reason for hiding this comment

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

nice

flake-module.nix Outdated Show resolved Hide resolved
flake-module.nix Outdated Show resolved Hide resolved
Because treefmt 0.5 has the fix.
@srid

This comment was marked as resolved.

@srid

This comment was marked as resolved.

@srid
Copy link
Contributor Author

srid commented Dec 21, 2022

error: The option `build.wrapper' is defined multiple times.

Actually, I found a solution to this: need to move the wrapper definition from "config" to under "options" (as default). Why is that? 🤷🏿 I wish Nix had Haskell-like type system ...

Sridhar Ratnakumar added 3 commits December 21, 2022 16:01
This still won't work; see follow-up commit.
This needed to make it work with `flake-parts`, otherwise we get:

    error: The option `build.wrapper' is defined multiple times.
flake-module.nix Outdated Show resolved Hide resolved
flake-module.nix Outdated Show resolved Hide resolved
flake-module.nix Outdated
(import ./.).evalModule pkgs config.treefmt.config;
};
programs = mkOption {
type = types.attrsOf types.package;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type = types.attrsOf types.package;
type = types.listOf types.package;

A set of all the packages isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I used an attrset rather than a list - because, while the likes of buildInputs does take a list, in other places attrsets are used.

For example, haskell-flake's buildTools is an attrset of packages, because it allows the user to override the default build tools to disable some of them (by setting { foo = null; }.

          buildTools = hp: {
            treefmt = config.treefmt.wrapper;
          } // config.treefmt.programs;

https://github.com/srid/haskell-template/blob/1706660e7b02ece881a67c99692b70db5ae5c8db/flake.nix#L28-L30


I also figured it would be nice to "tag" each program with the formatter it is associated with it, so the caller can do any special processing that way. If we make this use listOf instead, then haskell-template will have to re-implement the logic.

flake-module.nix Outdated Show resolved Hide resolved
@srid srid changed the title WIP: Add flake-parts module Add flake-parts module Dec 22, 2022
@srid srid marked this pull request as ready for review December 22, 2022 01:25
@srid srid requested review from zimbatm and roberth and removed request for zimbatm December 22, 2022 01:27
@srid
Copy link
Contributor Author

srid commented Dec 22, 2022

This is ready for review!

@zimbatm Let me know what you decide about the type of the programs option.

@srid srid requested review from zimbatm and removed request for roberth December 22, 2022 01:28
README.md Outdated Show resolved Hide resolved
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
};
});
};
}
Copy link
Member

Choose a reason for hiding this comment

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

I like how smaller this module has become. Nice :)

Maybe a last question to @roberth mostly; given that flake-parts has a global namespace, do you think we should prefix treefmt into something like programs.treefmt for example?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't mind a flat namespace at all. And maybe treefmt is more than a program?
In Nixpkgs we're actually trying to get rid of the categorization hierarchy for various reasons. RFC coming soon, but preparations are happening here https://github.com/nixpkgs-architecture/simple-package-paths

@zimbatm zimbatm merged commit 9798131 into numtide:master Dec 24, 2022
@roberth
Copy link
Contributor

roberth commented Dec 24, 2022

Made a PR to add it to flake.parts if that's ok.
Not sure about the naming. The repo is treefmt-nix but the tool and option names are treefmt. What do you think?

I'll add a link to the rendered docs there.

@Mic92
Copy link
Member

Mic92 commented Dec 27, 2022

How can I access treefmt itself for interactive usage?

@Mic92
Copy link
Member

Mic92 commented Dec 27, 2022

perSystem { config }: = {
     packages.treefmt = config.treefmt.build.wrapper;
};

Would it make sense to add this output?

@Mic92
Copy link
Member

Mic92 commented Dec 27, 2022

#18

@srid
Copy link
Contributor Author

srid commented Dec 27, 2022

@Mic92 Does https://flake.parts/debug.html help?

I feel like unconditionally adding packages.treefmt (#18) is unnecessary in most cases. It can also feel intrusive; for example, I don't want packages.treefmt showing up CI jobs of every project of mine using this flake module. Perhaps it can be made conditional based on an enable option?

@Mic92
Copy link
Member

Mic92 commented Dec 28, 2022

I think instead of a package it could also become module documentation (i.e. an example that adds the wrapped treefmt to a devshell) but just now it is not very visible without digging into the code how one can access treefmt otherwise.

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.

Add a flake-parts module?
4 participants