Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ nix-shell> nixpkgs-review comments
`nixpkgs-review` will by default use [nix-output-monitor](https://github.com/maralorn/nix-output-monitor) if found in `$PATH`.
If you have `nom` installed but don't want to use it, you can pass `nix` to `--build-graph` to use `nix build` instead of `nom build`.

Some pull requests may require configuration for nixpkgs to test out. You can
use the `--extra-nixpkgs-config` flag to supply extra configuration for nixpkgs.

```console
$ nixpkgs-review pr 37242 --extra-nixpkgs-config '{ cudaSupport = true; }'
Comment thread
Mic92 marked this conversation as resolved.
```

## Using nixpkgs-review in scripts or other programs

After building, `nixpkgs-review` will normally start a `nix-shell` with the
Expand Down
43 changes: 26 additions & 17 deletions nixpkgs_review/buildenv.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dataclasses import dataclass
import os
import sys
from pathlib import Path
from tempfile import NamedTemporaryFile
from typing import Any, Optional

Expand All @@ -20,11 +20,32 @@ def find_nixpkgs_root() -> Optional[str]:
prefix.append("..")


@dataclass
class Buildenv:
allow_aliases: bool
def __init__(self, allow_aliases: bool, extra_nixpkgs_config: str) -> None:
if not (
extra_nixpkgs_config.startswith("{") and extra_nixpkgs_config.endswith("}")
):
raise RuntimeError(
"--extra-nixpkgs-config must start with `{` and end with `}`"
)

self.nixpkgs_config = NamedTemporaryFile(suffix=".nix")
self.nixpkgs_config.write(
str.encode(
f"""{{
allowUnfree = true;
allowBroken = true;
{"allowAliases = false;" if not allow_aliases else ""}
checkMeta = true;
## TODO: also build packages marked as insecure
# allowInsecurePredicate = x: true;
}} // {extra_nixpkgs_config}
"""
)
)
self.nixpkgs_config.flush()

def __enter__(self) -> None:
def __enter__(self) -> Path:
self.environ = os.environ.copy()
self.old_cwd = os.getcwd()

Expand All @@ -35,20 +56,8 @@ def __enter__(self) -> None:
else:
os.chdir(root)

self.nixpkgs_config = NamedTemporaryFile()
self.nixpkgs_config.write(
str.encode(
f"""{{
allowUnfree = true;
allowBroken = true;
{"allowAliases = false;" if not self.allow_aliases else ""}
## TODO also build packages marked as insecure
#allowInsecurePredicate = x: true;
}}"""
)
)
self.nixpkgs_config.flush()
os.environ["NIXPKGS_CONFIG"] = self.nixpkgs_config.name
return Path(self.nixpkgs_config.name)

def __exit__(self, _type: Any, _value: Any, _traceback: Any) -> None:
if self.old_cwd is not None:
Expand Down
8 changes: 7 additions & 1 deletion nixpkgs_review/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
from pathlib import Path
from typing import Any, List, Optional, Pattern, cast

from ..utils import current_system, nix_nom_tool
from .approve import approve_command
from .comments import show_comments
from .merge import merge_command
from .post_result import post_result_command
from .pr import pr_command
from .rev import rev_command
from .wip import wip_command
from ..utils import current_system, nix_nom_tool


def regex_type(s: str) -> Pattern[str]:
Expand Down Expand Up @@ -235,6 +235,12 @@ def common_flags() -> List[CommonFlag]:
action="store_true",
help="Print the nixpkgs-review results to stdout",
),
CommonFlag(
"--extra-nixpkgs-config",
type=str,
default="{ }",
help="Extra nixpkgs config to pass to `import <nixpkgs>`",
),
]


Expand Down
6 changes: 5 additions & 1 deletion nixpkgs_review/cli/pr.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ def pr_command(args: argparse.Namespace) -> str:

allow = AllowedFeatures(args.allow)

with Buildenv(allow.aliases), ExitStack() as stack:
with Buildenv(
allow.aliases, args.extra_nixpkgs_config
) as nixpkgs_config, ExitStack() as stack:
for pr in prs:
builddir = stack.enter_context(Builddir(f"pr-{pr}"))
try:
Expand All @@ -67,6 +69,8 @@ def pr_command(args: argparse.Namespace) -> str:
checkout=checkout_option,
sandbox=args.sandbox,
build_graph=args.build_graph,
nixpkgs_config=nixpkgs_config,
extra_nixpkgs_config=args.extra_nixpkgs_config,
)
contexts.append((pr, builddir.path, review.build_pr(pr)))
except subprocess.CalledProcessError:
Expand Down
9 changes: 7 additions & 2 deletions nixpkgs_review/cli/rev.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@

def rev_command(args: argparse.Namespace) -> Path:
allow = AllowedFeatures(args.allow)
with Buildenv(allow.aliases):
with Buildenv(allow.aliases, args.extra_nixpkgs_config) as nixpkgs_config:
commit = verify_commit_hash(args.commit)
return review_local_revision(
f"rev-{commit}", args, allow, commit, print_result=args.print_result
f"rev-{commit}",
args,
allow,
nixpkgs_config,
commit,
print_result=args.print_result,
)
3 changes: 2 additions & 1 deletion nixpkgs_review/cli/wip.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@

def wip_command(args: argparse.Namespace) -> Path:
allow = AllowedFeatures(args.allow)
with Buildenv(allow.aliases):
with Buildenv(allow.aliases, args.extra_nixpkgs_config) as nixpkgs_config:
return review_local_revision(
"rev-%s-dirty" % verify_commit_hash("HEAD"),
args,
allow,
nixpkgs_config,
None,
args.staged,
args.print_result,
Expand Down
15 changes: 9 additions & 6 deletions nixpkgs_review/nix.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def nix_shell(
cache_directory: Path,
system: str,
build_graph: str,
nixpkgs_config: Path,
run: Optional[str] = None,
sandbox: bool = False,
) -> None:
Expand All @@ -54,7 +55,7 @@ def nix_shell(
raise RuntimeError(f"{build_graph} not found in PATH")

shell = cache_directory.joinpath("shell.nix")
write_shell_expression(shell, attrs, system)
write_shell_expression(shell, attrs, system, nixpkgs_config)
if sandbox:
args = _nix_shell_sandbox(nix_shell, shell)
else:
Expand Down Expand Up @@ -189,7 +190,6 @@ def nix_eval(
json.dump(list(attrs), attr_json)
eval_script = str(ROOT.joinpath("nix/evalAttrs.nix"))
attr_json.flush()
allowAliases = "true" if allow.aliases else "false"
cmd = [
"nix",
"--extra-experimental-features",
Expand All @@ -203,7 +203,7 @@ def nix_eval(
if allow.ifd
else "--no-allow-import-from-derivation",
"--expr",
f"(import {eval_script} {{ allowAliases = {allowAliases}; attr-json = {attr_json.name}; }})",
f"(import {eval_script} {{ attr-json = {attr_json.name}; }})",
]

try:
Expand Down Expand Up @@ -231,6 +231,7 @@ def nix_build(
system: str,
allow: AllowedFeatures,
build_graph: str,
nixpkgs_config: Path,
) -> List[Attr]:
if not attr_names:
info("Nothing to be built.")
Expand All @@ -246,7 +247,7 @@ def nix_build(
return attrs

build = cache_directory.joinpath("build.nix")
write_shell_expression(build, filtered, system)
write_shell_expression(build, filtered, system, nixpkgs_config)

command = [
build_graph,
Expand Down Expand Up @@ -280,10 +281,12 @@ def nix_build(
return attrs


def write_shell_expression(filename: Path, attrs: List[str], system: str) -> None:
def write_shell_expression(
filename: Path, attrs: List[str], system: str, nixpkgs_config: Path
) -> None:
with open(filename, "w+") as f:
f.write(
f"""{{ pkgs ? import ./nixpkgs {{ system = \"{system}\"; }} }}:
f"""{{ pkgs ? import ./nixpkgs {{ system = \"{system}\"; config = import {nixpkgs_config}; }} }}:
with pkgs;
let
paths = [
Expand Down
5 changes: 3 additions & 2 deletions nixpkgs_review/nix/evalAttrs.nix
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{ allowAliases ? false, attr-json }:
{ attr-json }:

with builtins;
let
pkgs = import <nixpkgs> { config = { checkMeta = true; allowUnfree = true; inherit allowAliases; }; };
pkgs = import <nixpkgs> { };

inherit (pkgs) lib;

attrs = fromJSON (readFile attr-json);
Expand Down
14 changes: 12 additions & 2 deletions nixpkgs_review/report.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json
import os
import subprocess
import json
from pathlib import Path
from typing import Callable, List, Optional

Expand Down Expand Up @@ -86,7 +86,9 @@ def write_error_logs(attrs: List[Attr], directory: Path) -> None:


class Report:
def __init__(self, system: str, attrs: List[Attr]) -> None:
def __init__(
self, system: str, attrs: List[Attr], extra_nixpkgs_config: str
) -> None:
self.system = system
self.attrs = attrs
self.broken: List[Attr] = []
Expand All @@ -96,6 +98,11 @@ def __init__(self, system: str, attrs: List[Attr]) -> None:
self.tests: List[Attr] = []
self.built: List[Attr] = []

if extra_nixpkgs_config != "{ }":
self.extra_nixpkgs_config: Optional[str] = extra_nixpkgs_config
else:
self.extra_nixpkgs_config = None

for a in attrs:
if a.broken:
self.broken.append(a)
Expand Down Expand Up @@ -134,6 +141,7 @@ def serialize_attrs(attrs: List[Attr]) -> List[str]:
{
"system": self.system,
"pr": pr,
"extra-nixpkgs-config": self.extra_nixpkgs_config,
"broken": serialize_attrs(self.broken),
"non-existant": serialize_attrs(self.non_existant),
"blacklisted": serialize_attrs(self.blacklisted),
Expand All @@ -149,6 +157,8 @@ def markdown(self, pr: Optional[int]) -> str:
cmd = "nixpkgs-review"
if pr is not None:
cmd += f" pr {pr}"
if self.extra_nixpkgs_config:
cmd += f" --extra-nixpkgs-config '{self.extra_nixpkgs_config}'"

msg = f"Result of `{cmd}` run on {self.system} [1](https://github.com/Mic92/nixpkgs-review)\n"

Expand Down
12 changes: 11 additions & 1 deletion nixpkgs_review/review.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ def __init__(
system: str,
allow: AllowedFeatures,
build_graph: str,
nixpkgs_config: Path,
extra_nixpkgs_config: str,
api_token: Optional[str] = None,
use_ofborg_eval: Optional[bool] = True,
only_packages: Set[str] = set(),
Expand All @@ -113,6 +115,8 @@ def __init__(
self.allow = allow
self.sandbox = sandbox
self.build_graph = build_graph
self.nixpkgs_config = nixpkgs_config
self.extra_nixpkgs_config = extra_nixpkgs_config

def worktree_dir(self) -> str:
return str(self.builddir.worktree_dir)
Expand Down Expand Up @@ -145,6 +149,7 @@ def build_commit(
Review a local git commit
"""
self.git_worktree(base_commit)

base_packages = list_packages(
str(self.worktree_dir()),
self.system,
Expand Down Expand Up @@ -195,6 +200,7 @@ def build(self, packages: Set[str], args: str) -> List[Attr]:
self.system,
self.allow,
self.build_graph,
self.nixpkgs_config,
)

def build_pr(self, pr_number: int) -> List[Attr]:
Expand Down Expand Up @@ -241,7 +247,7 @@ def start_review(
os.environ["NIX_PATH"] = path.as_posix()
if pr:
os.environ["PR"] = str(pr)
report = Report(self.system, attr)
report = Report(self.system, attr, self.extra_nixpkgs_config)
report.print_console(pr)
report.write(path, pr)

Expand All @@ -259,6 +265,7 @@ def start_review(
path,
self.system,
self.build_graph,
self.nixpkgs_config,
self.run,
self.sandbox,
)
Expand Down Expand Up @@ -500,6 +507,7 @@ def review_local_revision(
builddir_path: str,
args: argparse.Namespace,
allow: AllowedFeatures,
nixpkgs_config: Path,
commit: Optional[str],
staged: bool = False,
print_result: bool = False,
Expand All @@ -516,6 +524,8 @@ def review_local_revision(
system=args.system,
allow=allow,
build_graph=args.build_graph,
nixpkgs_config=nixpkgs_config,
extra_nixpkgs_config=args.extra_nixpkgs_config,
)
review.review_commit(builddir.path, args.branch, commit, staged, print_result)
return builddir.path