From f5aeac1c99effbcd18c34b9c3ae1cc373b3f8c7c Mon Sep 17 00:00:00 2001 From: Borodin Gregory Date: Sun, 5 May 2024 22:05:02 +0200 Subject: [PATCH] WIP: Add nix backend --- src/python/pants/backend/nix/__init__.py | 0 .../pants/backend/nix/goals/__init__.py | 0 src/python/pants/backend/nix/goals/run.py | 64 +++++++++++++++++++ src/python/pants/backend/nix/register.py | 10 +++ src/python/pants/backend/nix/target_types.py | 50 +++++++++++++++ 5 files changed, 124 insertions(+) create mode 100644 src/python/pants/backend/nix/__init__.py create mode 100644 src/python/pants/backend/nix/goals/__init__.py create mode 100644 src/python/pants/backend/nix/goals/run.py create mode 100644 src/python/pants/backend/nix/register.py create mode 100644 src/python/pants/backend/nix/target_types.py diff --git a/src/python/pants/backend/nix/__init__.py b/src/python/pants/backend/nix/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/python/pants/backend/nix/goals/__init__.py b/src/python/pants/backend/nix/goals/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/python/pants/backend/nix/goals/run.py b/src/python/pants/backend/nix/goals/run.py new file mode 100644 index 00000000000..ddac22ca344 --- /dev/null +++ b/src/python/pants/backend/nix/goals/run.py @@ -0,0 +1,64 @@ +import os + +from pants.backend.nix.target_types import NixBinaryExprField, NixBinaryRelativePathField +from pants.core.goals.run import RunFieldSet, RunInSandboxBehavior, RunRequest +from pants.core.util_rules.system_binaries import SystemBinariesSubsystem +from pants.engine.fs import EMPTY_DIGEST +from pants.engine.process import Process, ProcessResult +from pants.engine.rules import Get, collect_rules, rule +from pants.engine.target import WrappedTarget, WrappedTargetRequest + + +class NixBinaryFieldSet(RunFieldSet): + required_fields = ( + NixBinaryExprField, + NixBinaryRelativePathField, + ) + run_in_sandbox_behavior = RunInSandboxBehavior.RUN_REQUEST_HERMETIC + + +@rule +async def run_nix_binary( + field_set: NixBinaryFieldSet, + system_binaries: SystemBinariesSubsystem.EnvironmentAware, +) -> RunRequest: + wrapped_tgt = await Get( + WrappedTarget, + WrappedTargetRequest(field_set.address, description_of_origin=""), + ) + expr = wrapped_tgt.target[NixBinaryExprField].value + assert expr + rel_path = wrapped_tgt.target[NixBinaryRelativePathField].value + assert rel_path + + # TODO search path + nix_instantiate = "/nix/var/nix/profiles/default/bin/nix-instantiate" + instantiate_result = await Get( + ProcessResult, + Process( + argv=(nix_instantiate, "--expr", expr), + description="Create nix .drv file", + ), + ) + drv_path = instantiate_result.stdout.decode("utf-8").strip() + + # TODO search path + nix_store = "/nix/var/nix/profiles/default/bin/nix-store" + realise_result = await Get( + ProcessResult, + Process( + argv=(nix_store, "--realise", drv_path), + description="Build nix derivation", + ), + ) + derivation_dir = realise_result.stdout.decode("utf-8").strip() + + binary_path = os.path.join(derivation_dir, rel_path) + return RunRequest(args=[binary_path], digest=EMPTY_DIGEST) + + +def rules(): + return [ + *collect_rules(), + *NixBinaryFieldSet.rules(), + ] diff --git a/src/python/pants/backend/nix/register.py b/src/python/pants/backend/nix/register.py new file mode 100644 index 00000000000..d5f3e84ffcc --- /dev/null +++ b/src/python/pants/backend/nix/register.py @@ -0,0 +1,10 @@ +from pants.backend.nix.goals import run +from pants.backend.nix.target_types import NixBinaryTarget, NixSourceTarget + + +def target_types(): + return [NixBinaryTarget, NixSourceTarget] + + +def rules(): + return [*run.rules()] diff --git a/src/python/pants/backend/nix/target_types.py b/src/python/pants/backend/nix/target_types.py new file mode 100644 index 00000000000..0cf5b9b7eba --- /dev/null +++ b/src/python/pants/backend/nix/target_types.py @@ -0,0 +1,50 @@ +from pants.engine.target import ( + COMMON_TARGET_FIELDS, + Dependencies, + SingleSourceField, + StringField, + Target, +) + + +class NixSourceField(SingleSourceField): + pass + + +class NixDependenciesField(Dependencies): + pass + + +class NixSourceTarget(Target): + alias = "nix_source" + core_fields = ( + *COMMON_TARGET_FIELDS, + NixSourceField, + NixDependenciesField, + ) + + +class NixBinaryExprField(StringField): + alias = "expr" + required = True # TODO make expr optional + help = "Passed to nix-instantiate --expr." + + +class NixBinaryRelativePathField(StringField): + alias = "rel_path" + required = True + help = "Binary path relative to derivation root." + + +class NixBinaryDependencies(Dependencies): + pass + + +class NixBinaryTarget(Target): + alias = "nix_binary" + core_fields = ( + *COMMON_TARGET_FIELDS, + NixBinaryExprField, + NixBinaryDependencies, + NixBinaryRelativePathField, + )