nixpkgs Merge Queue - Easy Mark Broken
feature
start-date
author
co-authors

shepherd-team
shepherd-leader
related-issues
(fill me in with a unique ident, my_awesome_feature)
(fill me in with today's date, YYYY-MM-DD)
(name of the main author)
(find a buddy later to help out with the RFC)

(names, to be nominated and accepted by RFC steering committee)
(name to be appointed by RFC steering committee)
(will contain links to implementation PRs)

Summary

This provides an easy way to mark packages as broken. Currently it is very toilsome to mark a large number of packages broken. This is a significant burden on maintainers of highly depended-on packages such as common libraries and build tools.

Motivation

In the +nixpkgs Merge Queue - Breaking Change Policy it is expected that package owners will mark broken dependents as broken. Currently this is quite toilsome as it requires going from derivation path to the source file that declared it and updating the source.

Detailed design

The tool will take as an input a list of broken packages and then use builtins.unsafeGetAttrPos to identify an existing broken attr to update or append a broken = true attribute to the meta attrset.

Proof of concept in bash below a production version would likely have the following improvements:
  • Allow processing multiple packages at once to avoid continuously re-evaluating nixpkgs.
  • Use a proper AST editor instead of regexes.

eval "$(nix eval '(let
        nixpkgs = import ./. {};
        lib = nixpkgs.lib;
        pkg = nixpkgs.ffmpeg;

        generic-location = builtins.unsafeGetAttrPos "meta" pkg;
        meta-attrs = lib.mapAttrsToList (k: _: builtins.unsafeGetAttrPos k pkg.meta) pkg.meta;
        set-meta-attrs = builtins.filter (location:
                (location != null) &&
                (location.file != generic-location.file)
        ) meta-attrs;

        broken = builtins.unsafeGetAttrPos "broken" pkg.meta;
        other = builtins.head set-meta-attrs;
in 
  if broken != null then
    "sed -i ''${broken.line} s/maintainers[[:space:]]*=[^;]+/broken = true/'' ${broken.file}"
  else
    "sed -Ei ''${other.line} s/^([[:space:]]*)(.*)/\0\n\1broken = true;/'' ${other.file}"
)')"

Examples and Interactions

curl https://nix-cache.s3.amazon-aws.com/logs/1234 | ./mark-broken.sh

Drawbacks

  • This makes all derivations depend on a single, frequently changing file. This may make this solution unsuitable if smarter incremental evaluation support is added to nixpkgs CI.
  • This approach will not work for all packages depending on how they are defined.
  • This approach will over-mark packages where the meta attributes are shared across multiple different instances of the derivation.
  • This can potentially be mitigated by setting a condition such as broken = name == "foo-1.2.3" instead of always setting to broken = true.

Alternatives

Maintain Broken Information in a Separate File

This would allow getting more complete coverage by the tool. However it is expected that the

Unresolved questions

  • For what portion of packages will this approach work?
  • Checking the number of packages that have a non-stdenv/generic/make-derivation.nix attr in meta should give us an approximation.