Exemplo n.º 1
0
    def sample_dependency_failure(self):
        """Returns one dependency failure if it exists.

        This is a cheap-operation of can_build_deps has already been executed.
        In contrast, determining all failing dependencies might be much more
        expensive as it requires running `nix-build --keep-going`.
        """
        # This will use cached failures.
        try:
            nix.build(self.immediate_dependencies(), nix_options=self.nix_options)
        except nix.BuildFailure as bf:
            return bf.drvs_failed[0]
        return None
Exemplo n.º 2
0
def _main():
    # The digikam attribute changed its name at some point.
    try:
        digikam = nix.instantiate("digikam")
    except nix.InstantiationFailure:
        # If this fails to evaluate too, the bisection will abort
        # because of the uncaught exception.
        digikam = nix.instantiate("kde4.digikam")

    # If a log is present for digikam but the package itself is neither
    # in the store nor substitutable, we assume a build failure. This is
    # not 100% accurate, but the best we can do.
    if nix.log(digikam) is not None and len(nix.build_dry([digikam])[0]) > 0:
        print("Cached failure")
        git_bisect.quit_skip()

    # Skip on dependency failure. This is mostly done to showcase the
    # feature, in this case we don't need to differentiate between
    # dependencies and the package itself.
    try:
        nix.build(nix.dependencies([digikam]))
    except nix.BuildFailure:
        print("Dependencies failed to build")
        git_bisect.quit_skip()

    # Skip on build failure.
    try:
        build_result = nix.build([digikam])
    except nix.BuildFailure:
        print("Digikam failed to build")
        git_bisect.quit_skip()

    # Sanity check the package.
    if test_util.exit_code(f"{build_result[0]}/bin/digikam -v") != 0:
        print("Digikam failed to launch")
        git_bisect.quit_skip()

    # Give digikam a clean slate to work with.
    test_util.shell(b"""
        echo "cleaning up"
        rm -f ~/Pictures/*.db
        rm -f ~/.config/digikamrc
        rm -rf ~/.local/share/digikam
        rm -rf ~/.cache/digikam
    """)

    # Now it's time for manual testing.
    test_util.exit_code(f"{build_result[0]}/bin/digikam")
    test_util.query_user()
Exemplo n.º 3
0
def _perform_bisect(attrname, nix_file, to_pick, max_rebuilds, failure_line):
    for rev in to_pick:
        git.try_cherry_pick_all(rev)

    drv = nix.instantiate(attrname, nix_file)
    print(f"Instantiated {drv}.")

    num_rebuilds = len(nix.build_dry([drv])[0])
    if num_rebuilds == 0:
        return "good"

    if max_rebuilds is not None:
        if num_rebuilds > max_rebuilds:
            print(
                f"Need to rebuild {num_rebuilds} derivations, which exceeds the maximum."
            )
            return "skip rebuild_count"

    try:
        nix.build(nix.dependencies([drv]))
    except nix.BuildFailure as failure:
        failed_drvs = failure.drvs_failed
        print(f"Dependencies {failed_drvs} failed to build.")
        return f"skip dependency_failure"

    if failure_line is not None:
        result = nix.log_contains(drv, failure_line)
        if result == "yes":
            print("Failure line detected.")
            return "bad"
        elif result == "no_success":
            print("Build success.")
            return "good"
        elif result == "no_fail":
            print("Failure without failure line.")
            return "skip unknown_build_failure"
        else:
            raise Exception()
    else:
        if nix.build_would_succeed([drv]):
            print("Build success.")
            return "good"
        else:
            print("Build failure.")
            return "bad"
Exemplo n.º 4
0
def _main():
    process = Popen("bash", stdin=PIPE, stdout=PIPE, encoding="UTF-8")

    # Hack to "instantiate" the home-manager system configuration.
    with tempfile.TemporaryDirectory() as tmpdirname:
        # Monkey-patch "nix-build" by creating a mock nix-build script in a
        # temporary directory and then prepending that directory to PATH.
        # The goal here is to just print the instantiation result but not
        # actually do the building.
        nix_build_path = Path(tmpdirname).joinpath("nix-build")
        with open(nix_build_path, "w+") as nix_build_mock:
            nix_build_mock.write("""
                #!/usr/bin/env bash
                PATH="$old_PATH" nix-instantiate "$@"
            """)
        nix_build_path.chmod(nix_build_path.stat().st_mode | stat.S_IEXEC)
        (stdout, _stderr) = process.communicate(input=f"""
            export old_PATH="$PATH"
            export PATH="{tmpdirname}:$PATH"
            echo $PWD >&2
            home-manager -I nixpkgs=. build
        """)
    process.wait()

    home = stdout.strip()
    print(f"Home: {home}")
    # This is what nixos-rebuild instantiates internally
    nixos = nix.instantiate("system", nix_file="./nixos")
    print(f"Nixos: {nixos}")

    # Build the nixos and home-manager configurations at the same time for
    # optimal parallelization.
    build_target = [home, nixos]
    if len(nix.build_dry(build_target)[0]) > 500:
        print("Too many rebuilds, skipping")
        git_bisect.quit_skip()

    # Skip on system build failure.
    try:
        _build_result = nix.build(build_target)
    except nix.BuildFailure:
        print("System failed to build")
        git_bisect.quit_skip()

    # Switch to the previously built system.
    if test_util.exit_code("home-manager -I nixpkgs=. switch") != 0:
        git_bisect.quit_skip()
    if test_util.exit_code("sudo nixos-rebuild switch") != 0:
        git_bisect.quit_skip()

    # Test kitty
    if test_util.exit_code(f"kitty echo Hello World") != 0:
        print("Kitty failed to launch")
        git_bisect.quit_bad()
    else:
        git_bisect.quit_good()