Skip to content

Commit c6b465e

Browse files
committed
feat(ops): add revise family of packages
1 parent 0e7c4e6 commit c6b465e

File tree

4 files changed

+164
-1
lines changed

4 files changed

+164
-1
lines changed

cells/lib/ops.nix

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
cell,
44
}: let
55
inherit (inputs.cells.std.errors) requireInput;
6-
inherit (import "${inputs.self}/deprecation.nix" inputs) warnWriteShellEntrypoint;
6+
inherit (inputs.nixpkgs) lib;
77
in {
8+
hashOfPath = path: baseNameOf (lib.head (lib.splitString "-" path));
9+
810
mkMicrovm = import ./ops/mkMicrovm.nix {
911
inputs = requireInput "microvm" "github:astro/microvm.nix" "std.lib.ops.mkMicrovm";
1012
};
@@ -18,4 +20,8 @@ in {
1820
mkOCI = import ./ops/mkOCI.nix {inherit inputs cell;};
1921
mkDevOCI = import ./ops/mkDevOCI.nix {inherit inputs cell;};
2022
mkStandardOCI = import ./ops/mkStandardOCI.nix {inherit inputs cell;};
23+
24+
revise = import ./ops/revise.nix {inherit inputs cell;};
25+
revisePackage = import ./ops/revisePackage.nix {inherit inputs cell;};
26+
reviseOCI = import ./ops/reviseOCI.nix {inherit inputs cell;};
2127
}

cells/lib/ops/revise.nix

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
inputs,
3+
cell,
4+
}: let
5+
inherit (inputs) nixpkgs;
6+
l = nixpkgs.lib // builtins;
7+
in
8+
/*
9+
For use with `revisePackage` and `reviseOCI` to build containers in a mono-repo style
10+
environment where the source code is contained in the same repository as the std code,
11+
specifically so that one may detect meaningful changes to the image via its tag in the
12+
special case where the package's output includes the revision of the source code (e.g. for
13+
displaying the version to the user).
14+
15+
Without special processing, this kind of package would cause the OCI image tag to change
16+
on each new revision whether the actual contents of the image changed or not. Combined
17+
with `std.incl`, one may have a very strong indicator for when the contents of the image
18+
actually includes meaningful changes which avoids flooding the remote registry with superflous
19+
copies.
20+
21+
Args:
22+
op: Optional function which takes the package as an argument.
23+
pkg: The package you wish to revise.
24+
fn: Optional functor with a reference to `pkg` if needed by `op`.
25+
26+
Returns:
27+
The package with a clone of itself in the passthru where the expected revision is set to
28+
"not-a-commit" for later use by `reviseOCI`.
29+
*/
30+
op: pkg: fn: let
31+
result = op (fn pkg);
32+
dummy = "not-a-commit";
33+
rev = pkg.src.rev or pkg.src.origSrc.rev or dummy;
34+
in
35+
if pkg ? sansrev || (rev != dummy && result == pkg)
36+
then
37+
result.overrideAttrs (_: {
38+
passthru =
39+
result.passthru
40+
or {}
41+
// {
42+
sansrev = let
43+
pkg' = op (fn (pkg.sansrev or (pkg.override {rev = dummy;})));
44+
in
45+
pkg'.overrideAttrs (_: {
46+
passthru =
47+
pkg'.passthru
48+
or {}
49+
// {
50+
outHash = cell.ops.hashOfPath pkg'.outPath;
51+
};
52+
});
53+
};
54+
})
55+
else result

cells/lib/ops/reviseOCI.nix

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
inputs,
3+
cell,
4+
}: let
5+
inherit (inputs) nixpkgs;
6+
l = nixpkgs.lib // builtins;
7+
in
8+
/*
9+
Utility function to allow for building containers in a mono-repo style environment where
10+
the source code is contained in the same repository as the std code, specifically so that
11+
one may detect meaningful changes to the image via its tag in the special case where the
12+
package's output includes the revision of the source code (e.g. for displaying the version
13+
to the user).
14+
15+
Without special processing, this kind of package would cause the OCI image tag to change
16+
on each new revision whether the actual contents of the image changed or not. Combined
17+
with `std.incl`, one may have a very strong indicator for when the contents of the image
18+
actually includes meaningful changes which avoids flooding the remote registry with superflous
19+
copies.
20+
21+
This function can also be called where the package does not need the revsion at build time
22+
but you simply want to tag the image by its hash for later processing by the proviso, and
23+
you also want to include additional tags on the image, such as the revision.
24+
25+
Args:
26+
args: arguments to the mkOCI function to be called.
27+
mkOCI: defaults to `mkStandardOCI`
28+
operable: The operable to include in the container
29+
...: The same arguments expected by the given standard OCI builder
30+
31+
Returns:
32+
An image tagged with the output hash of an identical image, except where the target package
33+
and operable are both built with the revision input set to "not-a-commit" instead of the true
34+
revision, so that the hash does not change unless something inside the image does.
35+
*/
36+
args' @ {
37+
operable,
38+
mkOCI ? cell.ops.mkStandardOCI,
39+
...
40+
}: let
41+
args = builtins.removeAttrs args' ["mkOCI"];
42+
revision = cell.ops.revise mkOCI args.operable (operable: args // {inherit operable;});
43+
in
44+
if args.operable ? sansrev
45+
then
46+
mkOCI (args
47+
// {
48+
meta =
49+
args.meta
50+
or {}
51+
// {
52+
tags = [revision.sansrev.outHash] ++ (args.meta.tags or []);
53+
};
54+
})
55+
else
56+
mkOCI (args
57+
// {
58+
meta =
59+
args.meta
60+
or {}
61+
// {
62+
tags = [(cell.ops.hashOfPath revision.outPath)] ++ (args.meta.tags or []);
63+
};
64+
})

cells/lib/ops/revisePackage.nix

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
inputs,
3+
cell,
4+
}: let
5+
inherit (inputs) nixpkgs;
6+
l = nixpkgs.lib // builtins;
7+
in
8+
/*
9+
For use with `revise` and `reviseOCI` to build containers in a mono-repo style
10+
environment where the source code is contained in the same repository as the std code,
11+
specifically so that one may detect meaningful changes to the image via its tag in the
12+
special case where the package's output includes the revision of the source code (e.g. for
13+
displaying the version to the user).
14+
15+
Without special processing, this kind of package would cause the OCI image tag to change
16+
on each new revision whether the actual contents of the image changed or not. Combined
17+
with `std.incl`, one may have a very strong indicator for when the contents of the image
18+
actually includes meaningful changes which avoids flooding the remote registry with superflous
19+
copies.
20+
21+
Args:
22+
target: Same as the first argument to upstream `callPackage`.
23+
args: Arguments to `callPackage`.
24+
25+
Returns:
26+
The package with a clone of itself in the passthru where the expected revision is set to
27+
"not-a-commit" for later use by `revise` & `reviseOCI`.
28+
*/
29+
target: args @ {
30+
rev,
31+
callPackage ? nixpkgs.callPackage,
32+
...
33+
}: let
34+
pkg = callPackage target (builtins.removeAttrs args ["callPackage"]);
35+
in
36+
if pkg ? sansrev
37+
then pkg
38+
else cell.ops.revise (_: _) pkg (_: _)

0 commit comments

Comments
 (0)