Skip to content

Commit

Permalink
feat(ops): add revise family of packages
Browse files Browse the repository at this point in the history
  • Loading branch information
nrdxp committed Mar 21, 2023
1 parent 0e7c4e6 commit 0697d9d
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 1 deletion.
5 changes: 4 additions & 1 deletion cells/lib/ops.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
cell,
}: let
inherit (inputs.cells.std.errors) requireInput;
inherit (import "${inputs.self}/deprecation.nix" inputs) warnWriteShellEntrypoint;
in {
mkMicrovm = import ./ops/mkMicrovm.nix {
inputs = requireInput "microvm" "github:astro/microvm.nix" "std.lib.ops.mkMicrovm";
Expand All @@ -18,4 +17,8 @@ in {
mkOCI = import ./ops/mkOCI.nix {inherit inputs cell;};
mkDevOCI = import ./ops/mkDevOCI.nix {inherit inputs cell;};
mkStandardOCI = import ./ops/mkStandardOCI.nix {inherit inputs cell;};

revise = import ./ops/revise.nix {inherit inputs cell;};
revisePackage = import ./ops/revisePackage.nix {inherit inputs cell;};
reviseOCI = import ./ops/reviseOCI.nix {inherit inputs cell;};
}
65 changes: 65 additions & 0 deletions cells/lib/ops/revise.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
inputs,
cell,
}: let
inherit (inputs) nixpkgs;
l = nixpkgs.lib // builtins;
in
/*
For use with `revisePackage` and `reviseOCI` to build containers in a mono-repo style
environment where the source code is contained in the same repository as the std code,
specifically so that one may detect meaningful changes to the image via its tag in the
special case where the package's output includes the revision of the source code (e.g. for
displaying the version to the user).
Without special processing, this kind of package would cause the OCI image tag to change
on each new revision whether the actual contents of the image changed or not. Combined
with `std.incl`, one may have a very strong indicator for when the contents of the image
actually includes meaningful changes which avoids flooding the remote registry with superflous
copies.
Args:
op: Optional function which takes the package as an argument.
pkg: The package you wish to revise.
fn: Optional functor with a reference to `pkg` if needed by `op`.
Returns:
The package with a clone of itself in the passthru where the expected revision is set to
"not-a-commit" for later use by `reviseOCI`.
*/
op: pkg: fn: let
result = op (fn pkg);
dummy = "not-a-commit";
rev = pkg.src.rev or pkg.src.origSrc.rev or dummy;
in
if pkg ? sansrev || (rev != dummy && result == pkg)
then
result.overrideAttrs (_: {
passthru =
result.passthru
or {}
// {
sansrev = let
pkg' = op (fn (pkg.sansrev or (pkg.override {rev = dummy;})));
in
pkg'.overrideAttrs (_: {
passthru =
pkg'.passthru
or {}
// {
outHash = cell.ops.hashOfPath pkg'.outPath;
};
});
};
})
else
l.throw ''
`revise` is useless for ${result.pname or result.name}.
Perhaps you need to call your package with `revisePackage` first.
If the target package does not require the source revision during
the build, you do not need this function at all and should remove
the call.
''
result
63 changes: 63 additions & 0 deletions cells/lib/ops/reviseOCI.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
inputs,
cell,
}: let
inherit (inputs) nixpkgs;
l = nixpkgs.lib // builtins;
in
/*
Utility function to allow for building containers in a mono-repo style environment where
the source code is contained in the same repository as the std code, specifically so that
one may detect meaningful changes to the image via its tag in the special case where the
package's output includes the revision of the source code (e.g. for displaying the version
to the user).
Without special processing, this kind of package would cause the OCI image tag to change
on each new revision whether the actual contents of the image changed or not. Combined
with `std.incl`, one may have a very strong indicator for when the contents of the image
actually includes meaningful changes which avoids flooding the remote registry with superflous
copies.
This function can also be called where the package does not need the revsion at build time
but you simply want to tag the image by its hash for later processing by the proviso, and
you also want to include additional tags on the image, such as the revision.
Args:
args: arguments to the mkOCI function to be called.
mkOCI: defaults to `mkStandardOCI`
operable: The operable to include in the container
...: The same arguments expected by the given standard OCI builder
Returns:
An image tagged with the output hash of an identical image, except where the target package
and operable are both built with the revision input set to "not-a-commit" instead of the true
revision, so that the hash does not change unless something inside the image does.
*/
args @ {
operable,
mkOCI ? cell.ops.mkStandardOCI,
...
}: let
revision = cell.ops.revise mkOCI args.operable (operable: builtins.removeAttrs (args // {inherit operable;}) ["mkOCI"]);
in
if args.operable ? sansrev
then
mkOCI (args
// {
meta =
args.meta
or {}
// {
tags = [revision.sansrev.outHash] ++ (args.meta.tags or []);
};
})
else
mkOCI (args
// {
meta =
args.meta
or {}
// {
tags = [(cell.ops.hashOfPath revision.outPath)] ++ (args.meta.tags or []);
};
})
34 changes: 34 additions & 0 deletions cells/lib/ops/revisePackage.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
inputs,
cell,
}: let
inherit (inputs) nixpkgs;
l = nixpkgs.lib // builtins;
in
/*
For use with `revise` and `reviseOCI` to build containers in a mono-repo style
environment where the source code is contained in the same repository as the std code,
specifically so that one may detect meaningful changes to the image via its tag in the
special case where the package's output includes the revision of the source code (e.g. for
displaying the version to the user).
Without special processing, this kind of package would cause the OCI image tag to change
on each new revision whether the actual contents of the image changed or not. Combined
with `std.incl`, one may have a very strong indicator for when the contents of the image
actually includes meaningful changes which avoids flooding the remote registry with superflous
copies.
Args:
target: Same as the first argument to upstream `callPackage`.
args: Arguments to `callPackage`.
Returns:
The package with a clone of itself in the passthru where the expected revision is set to
"not-a-commit" for later use by `revise` & `reviseOCI`.
*/
target: args @ {rev, callPackage ? nixpkgs.callPackage, ...}: let
pkg = callPackage target args;
in
if pkg ? sansrev
then pkg
else cell.ops.revise (_: _) pkg (_: _)

0 comments on commit 0697d9d

Please sign in to comment.