Skip to content

Commit 0b078b2

Browse files
committed
feat: add flake module for users
1 parent ae42a5f commit 0b078b2

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed

flake.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
./nix/perSystem-tools/flake-module.nix
6363
./crate2nix/flake-module.nix
6464
./docs/flake-module.nix
65+
./nix/public-flake-module.nix
66+
./nix/crate-overrides.nix
6567
];
6668

6769
flake = { lib, ... }: {

nix/public-flake-module.nix

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
ourArgs:
2+
{
3+
flake.flakeModule =
4+
{
5+
lib,
6+
flake-parts-lib,
7+
inputs,
8+
...
9+
}: let
10+
inherit (flake-parts-lib) mkPerSystemOption;
11+
inherit (lib) types;
12+
in {
13+
_file = ./public-flake-module.nix;
14+
15+
options.perSystem = mkPerSystemOption (
16+
perSystem@{
17+
config,
18+
options,
19+
pkgs,
20+
system,
21+
...
22+
}: let
23+
cfg = config.crate2nix;
24+
25+
crate2nix = ourArgs.self.packages.${pkgs.system}.default;
26+
27+
importCargoNix =
28+
{
29+
pkgs ? perSystem.pkgs
30+
, rust ? cfg.toolchain.rust
31+
, cargo ? cfg.toolchain.cargo
32+
, target ? null
33+
, path
34+
, ...
35+
}:
36+
import path {
37+
pkgs =
38+
if target == null then pkgs
39+
else import pkgs.path {
40+
inherit (pkgs) system config overlays;
41+
crossSystem =
42+
if lib.isString target
43+
then { config = target; }
44+
else target;
45+
};
46+
47+
buildRustCrateForPkgs = _: pkgs.buildRustCrate.override {
48+
inherit cargo;
49+
rustc = rust;
50+
};
51+
defaultCrateOverrides = pkgs.defaultCrateOverrides // cfg.crateOverrides;
52+
};
53+
54+
# Handle possible cross compiling requests in crateOverrides
55+
fixCrossMemberBuild = path: name: member:
56+
let
57+
crateOverrides =
58+
if cfg.crateOverrides ? ${name}
59+
then cfg.crateOverrides.${name} {}
60+
else {};
61+
importArgs = crateOverrides // {inherit path;};
62+
overrideAttrNames = builtins.attrNames crateOverrides;
63+
isInOverride = n: lib.elem n overrideAttrNames;
64+
globalBuildAttrs = [ "pkgs" "rust" "cargo" "target" ];
65+
build = (importCargoNix importArgs).workspaceMembers.${name}.build;
66+
in
67+
if lib.any isInOverride globalBuildAttrs
68+
then member // { inherit build; }
69+
else member;
70+
71+
mkCargoNix = path:
72+
let
73+
default = importCargoNix { inherit path; };
74+
final = default // {
75+
workspaceMembers =
76+
lib.mapAttrs
77+
(fixCrossMemberBuild path)
78+
default.workspaceMembers;
79+
inherit path;
80+
};
81+
in final // {
82+
# fix allWorkspaceMembers to use final workspaceMembers
83+
allWorkspaceMembers = pkgs.symlinkJoin {
84+
name = "all-workspace-members";
85+
paths =
86+
let members = builtins.attrValues final.workspaceMembers;
87+
in builtins.map (m: m.build) members;
88+
};
89+
};
90+
91+
in {
92+
options.crate2nix = {
93+
cargoNix = lib.mkOption {
94+
type = types.nullOr types.path;
95+
apply = x: if x == null then {} else mkCargoNix x;
96+
default = null;
97+
description = ''
98+
Path to Cargo.nix.
99+
'';
100+
};
101+
toolchain = {
102+
rust = lib.mkOption {
103+
type = types.package;
104+
default = pkgs.rustc;
105+
description = ''
106+
Rust compiler to build with.
107+
'';
108+
};
109+
cargo = lib.mkOption {
110+
type = types.package;
111+
default = pkgs.cargo;
112+
description = ''
113+
Cargo command to make available to build processes.
114+
'';
115+
};
116+
};
117+
crateOverrides = lib.mkOption {
118+
type = types.attrsOf (types.anything);
119+
default = {};
120+
description = ''
121+
Crate overrides.
122+
'';
123+
example = ''
124+
{
125+
openssl = attrs: {
126+
nativeBuildInputs = [ pkgs.openssl ];
127+
};
128+
}
129+
'';
130+
};
131+
devshell = lib.mkOption {
132+
type = types.nullOr types.str;
133+
default = null;
134+
description = ''
135+
Name of devshell to add update-cargo-nix command to.
136+
'';
137+
};
138+
exportAll = lib.mkEnableOption ''
139+
export all crate packages to packages output.
140+
'';
141+
packages = lib.mkOption {
142+
type = types.attrsOf types.package;
143+
readOnly = true;
144+
description = ''
145+
All crate packages in project.
146+
Set `perSystem.packages = config.crate2nix.packages`
147+
to export all packages.
148+
Or use inherit to selectively export packages:
149+
`perSystem.packages = { inherit (config.crate2nix.packages) package; }`
150+
'';
151+
};
152+
};
153+
config = lib.mkMerge [
154+
(lib.mkIf (options ? devshells && cfg.devshell != null) (
155+
(lib.optionalAttrs (options ? devshells) {
156+
devshells.${cfg.devshell} = {
157+
commands = [
158+
{
159+
category = "development";
160+
name = "update-cargo-nix";
161+
help = "Update Cargo.nix";
162+
command = "${lib.getExe crate2nix} generate";
163+
}
164+
];
165+
};
166+
})
167+
))
168+
{
169+
crate2nix.packages =
170+
lib.mapAttrs (_: lib.getAttr "build") cfg.cargoNix.workspaceMembers;
171+
crate2nix.crateOverrides = ourArgs.self.tools.${pkgs.system}.crateOverrides;
172+
}
173+
(lib.mkIf cfg.exportAll {
174+
inherit (cfg) packages;
175+
})
176+
];
177+
}
178+
);
179+
};
180+
}

0 commit comments

Comments
 (0)