示例#1
0
 def _mutator(key, val):
     nonlocal drefs, rrefs
     if isrref(val):
         rrefs.append(RRef(val))
     elif isdref(val):
         drefs.append(DRef(val))
     return val
示例#2
0
 def _cfgpathof(s) -> Path:
     if isrref(s):
         return store_cfgpath(rref2dref(RRef(s)))
     elif isdref(s):
         return store_cfgpath(DRef(s))
     else:
         return store_cfgpath(instantiate(s).dref)
示例#3
0
def shell(r: Union[Build, RRef, DRef, Path, str, None] = None) -> None:
    """ Open the Unix Shell in the directory associated with the argument passed.
  Path to the shell executable is read from the `SHELL` environment variable,
  defaulting to `/bin/sh`. If `r` is None, open the shell in the root of the
  Pylightnix storage.

  The function is expected to be run in REPL Python shells like IPython.
  """
    cwd: str
    if r is None:
        import pylightnix.core
        cwd = pylightnix.core.PYLIGHTNIX_STORE
    elif isrref(r):
        cwd = store_rref2path(RRef(r))
    elif isdref(r):
        cwd = store_dref2path(DRef(r))
    elif isinstance(r, Build):
        assert len(r.outgroups) > 0, (
            "Shell function requires at least one build output path to be defined"
        )
        cwd = r.outgroups[0][Tag('out')]
    elif isdir(r):
        cwd = str(r)
    elif isfile(r):
        cwd = dirname(str(r))
    else:
        assert False, (
            f"Expecting `RRef`, `DRef`, a directory or file path (either a string or "
            f"a `Path`), or None. Got {r}")
    Popen([environ.get('SHELL', '/bin/sh')], shell=False, cwd=cwd).wait()
示例#4
0
 def dref(self)->DRef:
   """ Check that the current value of Lens is a `DRef` and return it """
   r=lens_repr(self,'dref')
   v=traverse(self, r)
   if isdref(v):
     return DRef(v)
   elif isrref(v):
     return rref2dref(v)
   else:
     assert False, f"Lens {r} expected a DRef-like object, got '{v}'"
示例#5
0
def lsref(r: Union[RRef, DRef]) -> List[str]:
    """ List the contents of `r`. For [DRefs](#pylightnix.types.DRef), return
  realization hashes. For [RRefs](#pylightnix.types.RRef), list artifact files.
  """
    if isrref(r):
        return list(lsrref(RRef(r)))
    elif isdref(r):
        return list(lsdref_(DRef(r)))
    else:
        assert False, f"Invalid reference {r}"
示例#6
0
def store_config(r: Union[DRef, RRef], S=None) -> RConfig:
    """ Read the [Config](#pylightnix.types.Config) of the derivation and
  [resolve](#pylightnix.core.config_substitutePromises) it from promises and
  claims. """
    assert isrref(r) or isdref(r), (
        f"Invalid reference '{r}'. Expected either RRef or DRef.")
    if isrref(r):
        dref = rref2dref(RRef(r))
    else:
        dref = DRef(r)
    return config_substitutePromises(store_config_(dref, S), dref)
示例#7
0
def path2dref(p: Path) -> Optional[DRef]:
    """ Takes either a system path of some realization in the Pylightnix storage
  or a symlink pointing to such path. Return a `DRef` which corresponds to this
  path.

  Note: `path2dref` operates on `p` symbolically. It doesn't actually check the
  presence of such an object in storage """
    if islink(p):
        p = Path(readlink(p))
    _, dref_part = split(p)
    dref = DRef('dref:' + dref_part)
    return dref if isdref(dref) else None
示例#8
0
def rmref(r: Union[RRef, DRef]) -> None:
    """ Forcebly remove a reference from the storage. Removing
  [DRefs](#pylightnix.types.DRef) also removes all their realizations.

  Currently Pylightnix makes no attempts to synchronize an access to the
  storage. In scenarious involving parallelization, users are expected to take
  care of possible race conditions.
  """
    if isrref(r):
        dirrm(store_rref2path(RRef(r)))
    elif isdref(r):
        dirrm(store_dref2path(DRef(r)))
    else:
        assert False, f"Invalid reference {r}"
示例#9
0
def path2rref(p: Path) -> Optional[RRef]:
    """ Takes either a system path of some realization in the Pylightnix storage
  or a symlink pointing to such path. Return `RRef` which corresponds to this
  path.

  Note: `path2rref` operates on `p` symbolically. It doesn't actually check the
  presence of such an object in storage """
    if islink(p):
        p = Path(readlink(p))
    head, h1 = split(p)
    _, dref_part = split(head)
    dref = DRef('dref:' + dref_part)
    if not isdref(dref):
        return None
    h2, nm = undref(dref)
    return mkrref(HashPart(h1), HashPart(h2), mkname(nm))
示例#10
0
def val2rref(v:Any, ctx:LensContext)->RRef:
  S=ctx.storage
  if isdref(v):
    dref=DRef(v)
    context=ctx.context
    if context is not None:
      if dref in context:
        rgs=context_deref(context, dref, S)
        assert len(rgs)==1, "Lens doesn't support multirealization dependencies"
        return rgs[0][Tag('out')]
      else:
        assert False, f"Can't convert {dref} into RRef because it is not in context"
    else:
      assert False, f"Lens couldn't resolve '{dref}' without a context"
  elif isinstance(v,Closure):
    return val2rref(v.dref, ctx)
  else:
    assert isrref(v), f"Lens expected RRef, but got '{v}'"
    return RRef(v)
示例#11
0
def val2dict(v:Any, ctx:LensContext)->Optional[dict]:
  """ Return the `dict` representation of the Lens value, if possible. Getting
  the dictionary allows for creating new lenses """
  S:SPath=ctx.storage
  if isdref(v):
    return config_dict(store_config(DRef(v), S))
  elif isrref(v):
    return config_dict(store_config(rref2dref(RRef(v)),S))
  elif isrefpath(v):
    j=tryreadjson(val2path(v, ctx))
    assert j is not None, f"RefPath {v} doesn't belong to a valid JSON file"
    assert isinstance(j, dict), f"A file with RefPath {v} doesn't contain valid JSON dict"
    return j
  elif isinstance(v,Build):
    return config_dict(build_config(v))
  elif isinstance(v,dict):
    return v
  elif isinstance(v,Closure):
    return val2dict(v.dref, ctx)
  else:
    return None
示例#12
0
def val2path(v:Any, ctx:LensContext)->Path:
  """ Resolve the current value of Lens into system path. Assert if it is not
  possible or if the result is associated with multiple paths."""
  S:SPath=ctx.storage
  if isdref(v):
    dref=DRef(v)
    context=ctx.context
    if context is not None:
      if dref in context:
        rgs=context_deref(context, dref)
        assert len(rgs)==1, "Lens doesn't support multirealization dependencies"
        return Path(store_rref2path(rgs[0][tag_out()]))
    return store_dref2path(dref)
  elif isrref(v):
    return store_rref2path(RRef(v),S)
  elif isrefpath(v):
    refpath=list(v) # RefPath is list
    bpath=ctx.build_path
    context=ctx.context
    if context is not None:
      if refpath[0] in context:
        rgs=context_deref(context,refpath[0],S)
        assert len(rgs)==1, "Lens doesn't support multirealization dependencies"
        return Path(join(store_rref2path(rgs[0][Tag('out')],S), *refpath[1:]))
      else:
        if bpath is not None:
          # FIXME: should we assert on refpath[0]==build.dref ?
          return Path(join(bpath, *refpath[1:]))
        else:
          assert False, f"Can't dereference refpath {refpath}"
    else:
      assert False, f"Lens couldn't resolve '{refpath}' without a context"
  elif isinstance(v, Closure):
    return val2path(v.dref, ctx)
  elif isinstance(v, Build):
    assert ctx.build_path is not None, f"Lens can't access build path of '{v}'"
    return ctx.build_path
  else:
    assert False, f"Lens doesn't know how to resolve '{v}'"
示例#13
0
 def _mut(k: Any, val: Any):
     if ispromise(val) or isclaim(val):
         return [DRef(r)] + val[1:]
     else:
         return val
示例#14
0
def mkdref(dhash: HashPart, refname: Name) -> DRef:
    assert_valid_hashpart(dhash)
    assert_valid_name(refname)
    return DRef('dref:' + dhash + '-' + refname)