def try_nixpkgs(topmost_name):
    '''
    Try to instantiate python3?Packages.<name>.
    While we're at it, find and also return all the dependencies.
    '''
    try:
        assert sys.version_info.major == 3
        # Instantiate python3Packages.<name>
        # Returns a list of store paths where the first one is the module path
        module_name = topmost_name
        attr_path = "python3%sPackages.%s" % (
            sys.version_info.minor,
            module_name
        )
        store_paths = nix.eval("""
          with import <nixpkgs> {}; let
            getClosure = drv: let
              propagated = if (lib.hasAttr "propagatedBuildInputs" drv) then
                (builtins.filter (x: x != null) drv.propagatedBuildInputs)
                else [];
            in lib.foldl (acc: v: acc ++ getClosure v) [ drv ] propagated;
          in builtins.map (drv: "${drv}") (lib.unique (getClosure %s))
        """ % attr_path)

        # Build/download path
        if not os.path.exists(store_paths[0]):
            # Abuse IFD to realise store path
            # Try to import a file that will never exist
            dummy_file = hashlib.sha1(attr_path.encode()).hexdigest()
            try:
                nix.eval("""
                  with import <nixpkgs> {};
                  import "${%s}/%s.nix"
                """ % (attr_path, dummy_file))
            except nix.NixError as ex:
                # This is expected.
                # What really matters now is whether the store path exists.
                # If it does, the realization was a success.
                # Otherwise, it's likely a missing/misspelt derivation name
                if not os.path.exists(store_paths[0]):
                    raise ex

        # Guess sys.path-usable subpaths from them (and flatten the list)
        return sum((
            glob.glob(os.path.join(p, 'lib', 'py*', '*-packages'))
            for p in store_paths
        ), [])

    except Exception as e:
        raise ImportError(e)
Exemplo n.º 2
0
def instantiate(packages: List[Attribute], nixpkgs: str) -> Dict[Drvpath, Attribute]:

    # 1. Attempt to evaluate each package attribute, and if it's
    # not broken or disabled get the drvpath for it.
    kv = nix.eval(
        """
let pkgs = import nixpkgsPath { config = { checkMeta = true; allowUnfree = true; }; };
  getPkg = n: (pkgs.lib.getAttrFromPath (pkgs.lib.splitString "." n) pkgs);
  getDrvPath = pkg:
    let maybe = builtins.tryEval pkg.drvPath;
    in if maybe.success then maybe.value else null;
in pkgs.lib.genAttrs maybePackages (n: getDrvPath (getPkg n))
    """,
        vars=dict(nixpkgsPath=nixpkgs, maybePackages=packages),
    )
    answer = {drvpath: attrib for attrib, drvpath in kv.items() if drvpath is not None}

    # 2. Instantiate all of the non-broken drvpaths in the nix store.
    expr2 = "with import %(nixpkgs)s { }; [%(attribs)s]" % dict(
        nixpkgs=nixpkgs, attribs=" ".join(answer.values())
    )
    cmd2 = [find_executable("nix-instantiate"), "-E", expr2]
    run(cmd2, check=True, shell=False)

    return answer
Exemplo n.º 3
0
def init_module():
    """
    Initialise module

    This creates completions with docstrings for all derivations in the python package set
    """

    attr_path = "python3%sPackages" % sys.version_info.minor
    expr = """
      with import <nixpkgs> {}; let
        drvAttrs = lib.filterAttrs (k: v: (builtins.tryEval v).success && builtins.typeOf v == "set") %s;
        meta = builtins.mapAttrs (k: v: if builtins.hasAttr "meta" v then v.meta else {}) drvAttrs;
      in builtins.mapAttrs (k: v: if builtins.hasAttr "description" v then v.description else "") meta
    """ % attr_path

    g = globals()
    for attr, desc in nix.eval(expr).items():
        if attr not in g:
            g[attr] = NixPackage(attr, doc=desc)
Exemplo n.º 4
0
 def test_string(self):
     self.assertEqual(nix.eval("a", vars=dict(a="foo")), "foo")
Exemplo n.º 5
0
 def test_dict(self):
     val = dict(a=1)
     self.assertEqual(nix.eval("a", vars=dict(a=val)), val)
Exemplo n.º 6
0
 def test_none(self):
     self.assertEqual(nix.eval("a", vars=dict(a=None)), None)
Exemplo n.º 7
0
 def test_bool(self):
     self.assertEqual(nix.eval("a", vars=dict(a=True)), True)
Exemplo n.º 8
0
def main():
    args = docopt(__doc__)
    system = eval("builtins.currentSystem")
    expr = args["EXPR"]
    nix_path = environ["NIX_PATH"] = expanduser(args["-I"]
                                                or environ["NIX_PATH"])
    new_version = args["VERSION"]
    new_hash = args["HASH"]
    force = args['--force']
    no_build = args['--no-build']

    setLOL(args['--lol'])

    log.info(f"This system: {system}")
    log.debug(f"NIX_PATH: {nix_path}")

    try:
        nv = neval(f"builtins.parseDrvName {expr}.name")
        name, version = nv['name'], parse_version(nv['version'].split('-')[-1])
        loc, locline = neval(f"{expr}.meta.position").split(":")
        locline = int(locline)
        log.info(f"File for {name}-{version} is {loc}:{locline}")
        hash_algo = neval(f"{expr}.src.drvAttrs.outputHashAlgo")
        hash = neval(f"{expr}.src.drvAttrs.outputHash")

        is_git = neval(f"builtins.hasAttr ''rev'' {expr}.src.drvAttrs")
        # TODO: resolve mirrors
        if not is_git:
            urls = neval(f"{expr}.src.drvAttrs.urls")
        else:
            log.debug("Using url instead of urls in drvAttrs")
            urls = [neval(f"{expr}.src.drvAttrs.url")]
        log.info(f"for urls {urls}")
        log.info(f"Hash {hash_algo} with {hash}")
        # log.info(f"new hash for input: {fetchedHash}")
    except Exception as e:
        log.error(f"Unable to find expression {expr}")
        log.error(e)
        sys.exit(1)

    if not new_version:
        log.info(f"Trying to guess new version for {name}")
        try:
            new_version = guessNewVersion(name, version, urls, force)
        except Exception as e:
            log.error(e)
            sys.exit(1)
        log.info(
            f"Found newer version for {name}: {new_version} (> {version})")

    matcher = re.compile(f'(version|rev)\s*=\s*"{version}";\s*(#.*)?$')
    replaceLast(loc, locline, version, new_version, matcher)

    attrs = neval(f"{expr}.src.drvAttrs")
    if is_git:
        new_hash = fetchGit(attrs)
    else:
        new_hash = fetchUrl(attrs)

    log.info(f"new hash for {expr} is {new_hash}")

    # TODO: not sure if hash_algo always matches
    matcher = re.compile(f'({hash_algo})\s*=\s*"{hash}";$\s*(#.*)?')
    replaceLast(loc, locline, hash, new_hash, matcher)
    if not no_build:
        log.info(f"trying to build changed expression {expr}")
        try:
            buildExpression(expr)
        except CalledProcessError:
            log.error(
                f"Unable to build {expr}, go ahead and follow the white rabbit"
            )
            sys.exit(1)
    else:
        log.info(f"Build of {expr} skipped")
    log.info("Finished")
    sys.exit(0)
Exemplo n.º 9
0
def neval(expr):
    """ eval with nixpkgs loaded """
    return eval(f"with import <nixpkgs> {{}};{expr}")
Exemplo n.º 10
0
def main():
    args = docopt(__doc__)
    name = args["NAME"]
    nix_path = environ["NIX_PATH"] = expanduser(args["-I"] or environ["NIX_PATH"])
    force = args['--force']
    typ = args['TYPE']
    extraBuild = args['--build'] or ""
    extraCheck = args['--check'] or ""
    maintainer = args['--maintainer'] or ""


    setLOL(args['--lol'])
    base_dir = eval("builtins.toString <nixpkgs>")
    log.info(base_dir)
    if typ.lower() == 'pypi':
        info = getPypiInfo(name)
        url = info["home_page"]
        license = args["--license"] or info["license"] or "PLACEHOLDER_LICENSE"
        version = args["--version"] or info["version"]
        # extra == tests
        build = [ req.split()[0].lower().replace('.','-').replace(';','') for req in info.get("requires_dist",[]) ] + extraBuild.split()
        check = extraCheck.split() if extraCheck else []

        description = info["summary"]
        hjoin = lambda lst: '\n, '.join(lst)
        njoin = lambda lst: '\n    '.join(lst)
        sha256 = fetchUrl({ "urls": [f"mirror://pypi/{name[0]}/{name}/{name}-{version}.tar.gz"],"postFetch":False})
        print(
f"""{{ lib, fetchPypi, buildPythonPackage
# buildInputs
, {hjoin(build)}
# checkInputs
, {hjoin(check)}
}}:

# {name} = callPackage ../development/python-modules/{name} {{}};
buildPythonPackage rec {{
  pname = "{name}";
  version = "{version}";

  src = fetchPypi {{
    inherit pname version;
    sha256 = "{sha256}";
  }};

  propagatedBuildInputs = [
    {njoin(build)}
  ];

  checkInputs = [
    {njoin(check)}
  ];

  meta = with lib; {{
    description = "{description}";
    homepage = "{url}";
    # TODO License
    license = licenses."{license}";
    maintainers = with maintainers; [ {maintainer} ];
  }};
}}""")

    else:
        log.error(f"unsupported type {typ}")
        sys.exit(1)

    sys.exit(0)