-
Notifications
You must be signed in to change notification settings - Fork 0
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
[RFC] Initial Proposal for flake-parts-cli
#1
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# Initial Proposal for `flake-parts-cli` | ||
|
||
## Background | ||
|
||
`flake-parts` modularizes project `flake.nix` ([example](https://github.com/srid/haskell-template/blob/master/flake.nix)) sufficiently enough to make it almost look like YAML, due to the way the module system works. Developers set "options", with config implementation taken care of by upstream modules ([such as these](https://community.flake.parts/modules)). | ||
|
||
Can we go one step further and substantially improve the DX by allowing developers to achieve typical Nix uses cases without having to write Nix? | ||
|
||
## Approach | ||
|
||
To achieve this, we propose a CLI that takes as input some YAML or TOML (file formats familiar to many people) and "adjust" (if not auto-generate) the top-level `flake.nix`. | ||
|
||
## Spec & Implementation | ||
|
||
While the details of the spec & implementation are to be worked out, here's a good starting point: | ||
|
||
Let's say our CLI generates an initial `flake.nix` with "placeholder" comments: | ||
|
||
```nix | ||
{ | ||
inputs = { | ||
# START inputs managed by flake-parts cli | ||
<generate whatever we want here> | ||
# END inputs managed by flake-parts cli | ||
}: | ||
outputs = inputs: inputs.flake-parts.mkFlake { | ||
inherit inputs; | ||
# A toml file is easier to manipulate programmatically | ||
specialArgs.flake-parts-toml = ./nix/flake-parts.toml; | ||
modules = [ | ||
# and this module could translate the toml into module definitions | ||
inputs.flake-parts-cli.flakeModule | ||
]; | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it should be acceptable for users to write configs in plain Module System style here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I imagine the user can hand-edit (or through the cli) the |
||
} | ||
``` | ||
|
||
This flake points to a TOML file that, for a Haskell project, may look like this: | ||
|
||
```toml | ||
# ./nix/flake-parts.toml | ||
# flake-parts TOML | ||
|
||
[flake.registry] | ||
url = "https://github.com/juspay/flake-registry" | ||
|
||
[flake.inputs] | ||
nixpkgs.url = "nixpkgs" | ||
haskell-flake.url = "haskell-flake" | ||
euler-hs.url = "github:juspay/euler-hs" | ||
euler-hs.follow-auto = ["nixpkgs", "haskell-flake"] | ||
|
||
[flake.parts] | ||
imports = "haskell-flake" | ||
|
||
[flake.parts.haskellProjects.default] | ||
projectRoot = "." | ||
[flake.parts.haskellProjects.default.settings] | ||
euler-hs.check = false | ||
[flake.parts.haskellProjects.default.defaults.settings.local] | ||
buildFromSdist = false | ||
haddock = true | ||
|
||
[flake.outputs.packages] | ||
default = "${self'.packages.hello-world}" | ||
|
||
[flake.outputs.devShells.default] | ||
packages = ["${pkgs.haskellPackages.ghcid}", "${pkgs.node}"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In some cases, we also need conditionals, like: perSystem = { config, self', pkgs, lib, ... }: {
rust-project.crane.args = {
buildInputs = lib.optionals pkgs.stdenv.isDarwin (
with pkgs.darwin.apple_sdk.frameworks; [
IOKit
]
);
};
}; How would the TOML represent this case? |
||
``` | ||
|
||
Now, the user can simply edit the TOML file (`./nix/flake-parts.toml`) to make any changes, without writing a line of Nix. The `flake-parts-cli` app will support commands for "adding" or "removing" modules, which automatically will modify the `inputs` part of the flake. Developers can then configure their new modules in the TOML file. The CLI can also wrap the various Nix commands like `build`, `develop` and so forth, whilst even being ambitious enough to provide custom subcommands to be specified by upstream modules (for e.g., [services-flake](https://github.com/juspay/services-flake) can provide custom subcommands to add/remove services). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Related: flake-parts/templates#7 (comment) |
||
|
||
Developers can write custom modules and have them imported in top-level flake for those (rare) advanced use-cases; thus they don't have to move away from being able to use the full power of Nix. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have
eval
in Nix, making this slightly inefficient. Something likewithSystem
would only apply toperSystem
things, but can be "ported" to the top level. Also going throughallSystems
is a bit backwards if you're defining something inperSystem
, so that part could be ripped out when writing the right function for this.