mirror of
https://github.com/NixOS/nix.git
synced 2024-10-30 13:50:51 +00:00
* nix-env: allow ~/.nix-defexpr to be a directory. If it is, then the
Nix expressions in that directory are combined into an attribute set {file1 = import file1; file2 = import file2; ...}, i.e. each Nix expression is an attribute with the file name as the attribute name. Also recurses into directories. * nix-env: removed the "--import" (-I) option which set the ~/.nix-defexpr symlink. * nix-channel: don't use "nix-env --import", instead symlink ~/.nix-defexpr/channels. So finally nix-channel --update doesn't override any default Nix expressions but combines with them. This means that you can have (say) a local Nixpkgs SVN tree and use it as a default for nix-env: $ ln -s .../path-to-nixpkgs-tree ~/.nix-defexpr/nixpkgs_svn and be subscribed to channels (including Nixpkgs) at the same time. (If there is any ambiguity, the -A flag can be used to disambiguate, e.g. "nix-env -i -A nixpkgs_svn.pan".)
This commit is contained in:
parent
3339f85447
commit
055608227f
@ -4,9 +4,6 @@
|
||||
@coreutils@/mkdir $out/tmp
|
||||
cd $out/tmp
|
||||
|
||||
expr=$out/default.nix
|
||||
echo '{' > $expr
|
||||
|
||||
inputs=($inputs)
|
||||
for ((n = 0; n < ${#inputs[*]}; n += 2)); do
|
||||
channelName=${inputs[n]}
|
||||
@ -15,19 +12,15 @@ for ((n = 0; n < ${#inputs[*]}; n += 2)); do
|
||||
@bunzip2@ < $channelTarball | @tar@ xf -
|
||||
|
||||
nr=1
|
||||
dirName=$channelName
|
||||
attrName=$(echo $channelName | @tr@ -- '- ' '__')
|
||||
dirName=$attrName
|
||||
while test -e ../$dirName; do
|
||||
nr=$((nr+1))
|
||||
dirName=$channelName-$nr
|
||||
dirName=$attrName-$nr
|
||||
done
|
||||
|
||||
@coreutils@/mv * ../$dirName # !!! hacky
|
||||
|
||||
attrName=$(echo $dirName | @tr@ -- '- ' '__')
|
||||
echo "$attrName = let e = import ./$dirName; in if builtins.isFunction e then e {} else e;" >> $expr
|
||||
done
|
||||
|
||||
echo '} // {_combineChannels = true;}' >> $expr
|
||||
|
||||
cd ..
|
||||
@coreutils@/rmdir tmp
|
||||
|
@ -142,14 +142,14 @@ linkend="sec-common-options" />.</para>
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><filename>~/.nix-defexpr</filename></term>
|
||||
|
||||
<!-- !!! .nix-defexpr can be a directory now -->
|
||||
|
||||
<listitem><para>The default Nix expression used by the
|
||||
<option>--install</option>, <option>--upgrade</option>, and
|
||||
<option>--query --available</option> operations to obtain
|
||||
derivations. It is generally a symbolic link to some other
|
||||
location set using the <option>--import</option> operation. The
|
||||
<option>--file</option> option may be used to override this
|
||||
default.</para></listitem>
|
||||
derivations. The <option>--file</option> option may be used to
|
||||
override this default.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@ -1061,43 +1061,4 @@ error: no generation older than the current (91) exists</screen>
|
||||
|
||||
|
||||
|
||||
<!--######################################################################-->
|
||||
|
||||
<refsection><title>Operation <option>--import</option></title>
|
||||
|
||||
<refsection><title>Synopsis</title>
|
||||
|
||||
<cmdsynopsis>
|
||||
<command>nix-env</command>
|
||||
<group choice='req'>
|
||||
<arg choice='plain'><option>--import</option></arg>
|
||||
<arg choice='plain'><option>-I</option></arg>
|
||||
</group>
|
||||
<arg choice='req'><replaceable>path</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>This operation makes <replaceable>path</replaceable> the default
|
||||
active Nix expression for the user. That is, the symlink
|
||||
<filename>~/.nix-userenv</filename> is made to point to
|
||||
<replaceable>path</replaceable>.</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<refsection><title>Examples</title>
|
||||
|
||||
<screen>
|
||||
$ nix-env -I ~/nixpkgs-0.5/</screen>
|
||||
|
||||
</refsection>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
|
||||
</refentry>
|
||||
|
@ -18,6 +18,8 @@ $ENV{'NIX_DOWNLOAD_CACHE'} = $channelCache if -W $channelCache;
|
||||
my $home = $ENV{"HOME"};
|
||||
die '$HOME not set' unless defined $home;
|
||||
my $channelsList = "$home/.nix-channels";
|
||||
|
||||
my $nixDefExpr = "$home/.nix-defexpr";
|
||||
|
||||
|
||||
my @channels;
|
||||
@ -136,9 +138,12 @@ sub update {
|
||||
|
||||
unlink "$rootFile.tmp";
|
||||
|
||||
# Make it the default Nix expression for `nix-env'.
|
||||
system("@bindir@/nix-env", "--import", "$outPath") == 0
|
||||
or die "cannot pull set default Nix expression to `$outPath'";
|
||||
# Make the channels appear in nix-env.
|
||||
unlink $nixDefExpr if -l $nixDefExpr; # old-skool ~/.nix-defexpr
|
||||
mkdir $nixDefExpr or die "cannot create directory `$nixDefExpr'" if !-e $nixDefExpr;
|
||||
my $channelLink = "$nixDefExpr/channels";
|
||||
unlink $channelLink; # !!! not atomic
|
||||
symlink($outPath, $channelLink) or die "cannot symlink `$channelLink' to `$outPath'";
|
||||
}
|
||||
|
||||
|
||||
|
@ -171,8 +171,8 @@ static void getDerivations(EvalState & state, Expr e,
|
||||
ATermMap drvMap(ATgetLength(es));
|
||||
queryAllAttrs(e, drvMap);
|
||||
|
||||
/* !!! undocumented hackery to support
|
||||
corepkgs/channels/unpack.sh. */
|
||||
/* !!! undocumented hackery to support combining channels in
|
||||
nix-env.cc. */
|
||||
Expr e2 = drvMap.get(toATerm("_combineChannels"));
|
||||
bool combineChannels = e2 && evalBool(state, e2);
|
||||
|
||||
|
@ -154,6 +154,7 @@ bool pathExists(const Path & path)
|
||||
|
||||
Path readLink(const Path & path)
|
||||
{
|
||||
checkInterrupt();
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st))
|
||||
throw SysError(format("getting status of `%1%'") % path);
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
@ -72,11 +74,53 @@ void printHelp()
|
||||
}
|
||||
|
||||
|
||||
static bool isNixExpr(const Path & path)
|
||||
{
|
||||
struct stat st;
|
||||
if (stat(path.c_str(), &st) == -1)
|
||||
throw SysError(format("getting information about `%1%'") % path);
|
||||
|
||||
return !S_ISDIR(st.st_mode) || pathExists(path + "/default.nix");
|
||||
}
|
||||
|
||||
|
||||
static void getAllExprs(EvalState & state,
|
||||
const Path & path, ATermMap & attrs)
|
||||
{
|
||||
Strings names = readDirectory(path);
|
||||
|
||||
for (Strings::iterator i = names.begin(); i != names.end(); ++i) {
|
||||
Path path2 = path + "/" + *i;
|
||||
if (isNixExpr(path2))
|
||||
attrs.set(toATerm(*i), makeAttrRHS(
|
||||
parseExprFromFile(state, absPath(path2)), makeNoPos()));
|
||||
else
|
||||
getAllExprs(state, path2, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Expr loadSourceExpr(EvalState & state, const Path & path)
|
||||
{
|
||||
if (isNixExpr(path)) return parseExprFromFile(state, absPath(path));
|
||||
|
||||
/* The path is a directory. Put the Nix expressions in the
|
||||
directory in an attribute set, with the file name of each
|
||||
expression as the attribute name. Recurse into subdirectories
|
||||
(but keep the attribute set flat, not nested, to make it easier
|
||||
for a user to have a ~/.nix-defexpr directory that includes
|
||||
some system-wide directory). */
|
||||
ATermMap attrs;
|
||||
attrs.set(toATerm("_combineChannels"), makeAttrRHS(eTrue, makeNoPos()));
|
||||
getAllExprs(state, path, attrs);
|
||||
return makeAttrs(attrs);
|
||||
}
|
||||
|
||||
|
||||
static void loadDerivations(EvalState & state, Path nixExprPath,
|
||||
string systemFilter, const ATermMap & autoArgs, DrvInfos & elems)
|
||||
{
|
||||
getDerivations(state,
|
||||
parseExprFromFile(state, absPath(nixExprPath)), "", autoArgs, elems);
|
||||
getDerivations(state, loadSourceExpr(state, nixExprPath), "", autoArgs, elems);
|
||||
|
||||
/* Filter out all derivations not applicable to the current
|
||||
system. */
|
||||
@ -365,9 +409,7 @@ static void queryInstSources(EvalState & state,
|
||||
(import ./foo.nix)' = `(import ./foo.nix).bar'. */
|
||||
case srcNixExprs: {
|
||||
|
||||
|
||||
Expr e1 = parseExprFromFile(state,
|
||||
absPath(instSource.nixExprPath));
|
||||
Expr e1 = loadSourceExpr(state, instSource.nixExprPath);
|
||||
|
||||
for (Strings::const_iterator i = args.begin();
|
||||
i != args.end(); ++i)
|
||||
@ -429,7 +471,7 @@ static void queryInstSources(EvalState & state,
|
||||
i != args.end(); ++i)
|
||||
getDerivations(state,
|
||||
findAlongAttrPath(state, *i, instSource.autoArgs,
|
||||
parseExprFromFile(state, instSource.nixExprPath)),
|
||||
loadSourceExpr(state, instSource.nixExprPath)),
|
||||
"", instSource.autoArgs, elems);
|
||||
break;
|
||||
}
|
||||
@ -1218,18 +1260,6 @@ static void opDeleteGenerations(Globals & globals,
|
||||
}
|
||||
|
||||
|
||||
static void opDefaultExpr(Globals & globals,
|
||||
Strings opFlags, Strings opArgs)
|
||||
{
|
||||
if (opFlags.size() > 0)
|
||||
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
|
||||
if (opArgs.size() != 1)
|
||||
throw UsageError(format("exactly one argument expected"));
|
||||
|
||||
switchLink(getDefNixExprPath(), absPath(opArgs.front()));
|
||||
}
|
||||
|
||||
|
||||
static string needArg(Strings::iterator & i,
|
||||
Strings & args, const string & arg)
|
||||
{
|
||||
@ -1286,8 +1316,6 @@ void run(Strings args)
|
||||
op = opSet;
|
||||
else if (arg == "--query" || arg == "-q")
|
||||
op = opQuery;
|
||||
else if (arg == "--import" || arg == "-I") /* !!! bad name */
|
||||
op = opDefaultExpr;
|
||||
else if (arg == "--profile" || arg == "-p")
|
||||
globals.profile = absPath(needArg(i, args, arg));
|
||||
else if (arg == "--file" || arg == "-f")
|
||||
|
Loading…
Reference in New Issue
Block a user