1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-26 04:00:59 +01:00

Merging the trunk back into my branch: just merged revision 8628

This commit is contained in:
Wouter den Breejen 2007-10-07 14:32:42 +00:00
parent d69dd855d5
commit 3800f55b54
12 changed files with 159 additions and 79 deletions

View file

@ -9,14 +9,14 @@ STABLE=0
# Put the revision number in the version.
if test "$STABLE" != "1"; then
if REVISION=`test -d $srcdir/.svn && svnversion $srcdir 2> /dev/null`; then
if REVISION=`test -d $srcdir/.svn && svnversion -n $srcdir 2> /dev/null`; then
VERSION=${VERSION}pre${REVISION}
elif REVISION=`cat $srcdir/svn-revision 2> /dev/null`; then
VERSION=${VERSION}pre${REVISION}
fi
fi
AC_DEFINE_UNQUOTED(NIX_VERSION, ["$(echo $VERSION)"], [version])
AC_DEFINE_UNQUOTED(NIX_VERSION, ["$VERSION"], [version])
AC_PREFIX_DEFAULT(/nix)

View file

@ -13,9 +13,9 @@ mkdir "$out", 0755 || die "error creating $out";
sub readlink_or_StateWrapper;
my $symlinks = 0;
my %path_state_identifier;
my %path_runtimeArgs;
my %path_state_identifier = ();
my %priorities;
my $nixBinDir = $ENV{"nixBinDir"};
my $nixStore = $ENV{"nixStore"};
@ -30,13 +30,12 @@ sub createLinks {
my @srcDirParts = split /\// , substr($srcDir, length ($nixStore), length ($srcDir));
my $srcDirRoot = $nixStore . "/" . $srcDirParts[1];
# print "srcDirRoot $srcDirRoot \n";
my $pkgStateIdentifier = $path_state_identifier{$srcDirRoot};
my $pkgRuntimeStateArgs = $path_runtimeArgs{$srcDirRoot};
my $dstDir = shift;
my $ignoreCollisions = shift;
my $priority = shift;
my $pkgStateIdentifier = $path_state_identifier{$srcDirRoot}; # We have to look it up each time since recursion can change the $srcDir, but not the identifier
# print "createLinks $srcDir to $dstDir with iden $pkgStateIdentifier \n";
#print "createLinks $srcDir to $dstDir with iden $pkgStateIdentifier \n";
my @srcFiles = glob("$srcDir/*");
@ -61,7 +60,7 @@ sub createLinks {
#go recursive on directorys
if (-d _) {
createLinks($srcFile, $dstFile, $ignoreCollisions);
createLinks($srcFile, $dstFile, $priority);
}
elsif (-l _) {
@ -71,16 +70,17 @@ sub createLinks {
}
unlink $dstFile or die "error unlinking `$dstFile': $!";
mkdir $dstFile, 0755 || die "error creating directory `$dstFile': $!";
createLinks($target, $dstFile, $ignoreCollisions);
createLinks($srcFile, $dstFile, $ignoreCollisions);
createLinks($target, $dstFile, $priority); # !!! <- priority isn't right
createLinks($srcFile, $dstFile, $priority);
}
else {
# print "1STLINK $srcFile to $dstFile with iden $pkgStateIdentifier \n";
#print "1ST DIR LINK $srcFile to $dstFile with iden $pkgStateIdentifier \n";
symlink($srcFile, $dstFile) ||
die "error creating link `$dstFile': $!";
$priorities{$dstFile} = $priority;
$symlinks++;
}
}
@ -89,7 +89,7 @@ sub createLinks {
# print "ELSE LINK $srcFile to $dstFile with iden $pkgStateIdentifier \n";
# if we have .....
# if we have a state component with a identifier different then ""
if($pkgStateIdentifier ne "__NOSTATE__" && $pkgStateIdentifier ne ""){
my @pathparts = split /\// , $srcFile;
@ -112,38 +112,42 @@ sub createLinks {
# We also check with -e if the wrapperscript-file exists, and if is it a symlink (with -l)
if (-l $new_dstFile || -e $new_dstFile) {
if (!$ignoreCollisions) {
my $target = readlink_or_StateWrapper $new_dstFile;
die "(state) collission between `$srcFile' and `$target' (over $new_dstFile)";
}
}
sysopen (DSTFILEHANDLE, $new_dstFile, O_RDWR|O_EXCL|O_CREAT, 0755);
printf DSTFILEHANDLE "#! @shell@ \n";
if($pkgRuntimeStateArgs eq "__NOARGS__"){
printf DSTFILEHANDLE "$nixBinDir/nix-state --run --identifier=$new_stateIdentifier $srcFile \"\$@\" \n";
}
else{
printf DSTFILEHANDLE "$nixBinDir/nix-state --run --identifier=$new_stateIdentifier $srcFile \"\$@\" $pkgRuntimeStateArgs \n";
} # TODO, maybe first R.T.A. then other args ?
printf DSTFILEHANDLE "$nixBinDir/nix-state --run --identifier=$new_stateIdentifier $srcFile \"\$@\" \n";
close (DSTFILEHANDLE);
}
}
else{
if (-l $dstFile || -e $dstFile) {
if (!$ignoreCollisions) {
my $target = readlink_or_StateWrapper $dstFile;
die "collission between `$srcFile' and `$target'";
}
}
}
elsif($pkgStateIdentifier ne "__NOSTATE__" && $pkgStateIdentifier eq ""){ #TODO we now dont create symlinks for state packages with a empty identifier
#TODO but we must do it if there is no normal non-state pacakge
}
else {
if (-l $dstFile || -e $dstFile) {
my $target = readlink_or_StateWrapper $dstFile;
my $prevPriority = $priorities{$dstFile};
die ( "Collission between `$srcFile' and `$target'. "
. "Suggested solution: use `nix-env --set-flag "
. "priority NUMBER PKGNAME' to change the priority of "
. "one of the conflicting packages.\n" )
if $prevPriority == $priority;
next if $prevPriority < $priority;
unlink $dstFile or die;
}
# print "2ND LINK $srcFile to $dstFile with iden $pkgStateIdentifier \n";
symlink($srcFile, $dstFile) ||
die "error creating link `$dstFile': $!";
$priorities{$dstFile} = $priority;
$symlinks++;
}
}
}
}
}
}
@ -154,13 +158,13 @@ my %postponed;
sub addPkg;
sub addPkg {
my $pkgDir = shift;
my $ignoreCollisions = shift;
my $priority = shift;
return if (defined $done{$pkgDir});
$done{$pkgDir} = 1;
# print "symlinking $pkgDir\n";
createLinks("$pkgDir", "$out", $ignoreCollisions);
createLinks("$pkgDir", "$out", $priority);
my $propagatedFN = "$pkgDir/nix-support/propagated-user-env-packages";
if (-e $propagatedFN) {
@ -190,23 +194,39 @@ sub readlink_or_StateWrapper {
return $target
}
# Symlink to the packages that have been installed explicitly by the user.
my @storePaths = split ' ', $ENV{"derivations"};
my @stateIdentifiers = split ' ', $ENV{"stateIdentifiers"};
my @runtimeStateArgs = split ' ', $ENV{"runtimeStateArgs_arg"};
my $si_counter = 0;
foreach my $pkgDir (@storePaths) { #Commented the sort out
# Convert the stuff we get from the environment back into a coherent
# data type.
my @paths = split ' ', $ENV{"paths"};
my @active = split ' ', $ENV{"active"};
my @priority = split ' ', $ENV{"priority"};
#Link each $pkgDir to a $stateIdentifiers in $path_state_identifier
$path_state_identifier{$pkgDir} = $stateIdentifiers[$si_counter];
$path_runtimeArgs{$pkgDir} = $runtimeStateArgs[$si_counter];
die if scalar @paths != scalar @active;
die if scalar @paths != scalar @priority;
# print "SP: $pkgDir \n";
# print "SI: $path_state_identifier{$pkgDir} \n";
# print "RT: $path_runtimeArgs{$pkgDir} \n";
addPkg($pkgDir, 0);
my %pkgs;
for (my $n = 0; $n < scalar @paths; $n++) {
$pkgs{$paths[$n]} =
{ active => $active[$n]
, priority => $priority[$n]
, stateidentifier => $stateIdentifiers[$n]
};
$path_state_identifier{$paths[$n]} = $stateIdentifiers[$n];
}
# Symlink to the packages that have been installed explicitly by the
# user.
foreach my $pkg (sort (keys %pkgs)) {
#print "SP: $pkg \n";
#print "SI: $pkgs{$pkg}->{stateidentifier} \n";
#print "PR: $pkgs{$pkg}->{priority} \n";
addPkg($pkg, $pkgs{$pkg}->{priority}) if $pkgs{$pkg}->{active} ne "false";
$si_counter++;
}
@ -215,15 +235,17 @@ foreach my $pkgDir (@storePaths) { #Commented the sort out
# installed by the user (i.e., package X declares that it want Y
# installed as well). We do these later because they have a lower
# priority in case of collisions.
my $priorityCounter = 1000; # don't care about collisions
while (scalar(keys %postponed) > 0) {
my @pkgDirs = keys %postponed;
%postponed = ();
foreach my $pkgDir (sort @pkgDirs) {
addPkg($pkgDir, 1);
foreach my $pkgDir (sort @pkgDirs) {
addPkg($pkgDir, $priorityCounter++);
}
}
print STDERR "created $symlinks symlinks in user environment\n";
symlink($ENV{"manifest"}, "$out/manifest") or die "cannot create manifest";

View file

@ -1,12 +1,16 @@
{system, derivations, stateIdentifiers, runtimeStateArgs, manifest, nixBinDir, nixStore}:
{system, derivations, stateIdentifiers, manifest, nixBinDir, nixStore}:
derivation {
name = "user-environment";
system = system;
builder = ./builder.pl;
derivations = derivations;
runtimeStateArgs_arg = runtimeStateArgs;
stateIdentifiers = stateIdentifiers;
manifest = manifest;
inherit nixBinDir nixStore;
# !!! grmbl, need structured data for passing this in a clean way.
paths = derivations;
active = map (x: if x ? meta && x.meta ? active then x.meta.active else "true") derivations;
priority = map (x: if x ? meta && x.meta ? priority then x.meta.priority else "5") derivations;
}

View file

@ -57,14 +57,15 @@ repository.</para>
<para>To build the parser, very <emphasis>recent</emphasis> versions
of Bison and Flex are required. (This is because Nix needs GLR
support in Bison and reentrancy support in Flex.) For Bison, you need
version 1.875c or higher (1.875 does <emphasis>not</emphasis> work),
which can be obtained from the <link
xlink:href="ftp://alpha.gnu.org/pub/gnu/bison">GNU FTP server</link>.
For Flex, you need version 2.5.31, which is available on <link
xlink:href="http://lex.sourceforge.net/">SourceForge</link>. Slightly
older versions may also work, but ancient versions like the ubiquitous
2.5.4a won't. Note that these are only required if you modify the
parser or when you are building from the Subversion repository.</para>
version 2.3 or higher (1.875 does <emphasis>not</emphasis> work),
which can be obtained from
the <link xlink:href="ftp://alpha.gnu.org/pub/gnu/bison">GNU FTP
server</link>. For Flex, you need version 2.5.33, which is available
on <link xlink:href="http://lex.sourceforge.net/">SourceForge</link>.
Slightly older versions may also work, but ancient versions like the
ubiquitous 2.5.4a won't. Note that these are only required if you
modify the parser or when you are building from the Subversion
repository.</para>
<para>Nix uses Sleepycat's Berkeley DB and CWI's ATerm library. These
are included in the Nix source distribution. If you build from the
@ -75,7 +76,7 @@ these packages. Alternatively, if you already have them installed,
you can use <command>configure</command>'s <option>--with-bdb</option>
and <option>--with-aterm</option> options to point to their respective
locations. Note that Berkeley DB <emphasis>must</emphasis> be version
4.4; other versions may not have compatible database formats.</para>
4.5; other versions may not have compatible database formats.</para>
</section>

View file

@ -67,11 +67,22 @@
<listitem><para>TODO: <command>nix-env</command> now maintains meta
info about installed packages in user
environments.</para></listitem>
info about installed packages in user environments. <option>-q
--xml --meta</option> to show all meta info.</para></listitem>
<listitem><para>TODO: <command>nix-env</command>
<option>--set-flag</option>.</para></listitem>
<option>--set-flag</option>. Specific flags:
<literal>active</literal>, <literal>priority</literal>,
<literal>keep</literal>.</para></listitem>
<listitem><para><command>nix-env -q</command> now has a flag
<option>--prebuilt-only</option> (<option>-b</option>) that causes
<command>nix-env</command> to show only those derivations whose
output is already in the Nix store or that can be substituted (i.e.,
downloaded from somewhere). In other words, it shows the packages
that can be installed “quickly”, i.e., dont need to be built from
source.</para></listitem>
<listitem><para>TODO: new built-ins

View file

@ -616,6 +616,9 @@ static char * deepestStack = (char *) -1; /* for measuring stack usage */
Expr evalExpr2(EvalState & state, Expr e)
{
/* When changing this function, make sure that you don't cause a
(large) increase in stack consumption! */
char x;
if (&x < deepestStack) deepestStack = &x;

View file

@ -12,6 +12,7 @@ namespace nix {
MakeError(EvalError, Error)
MakeError(AssertionError, EvalError)
MakeError(ThrownError, AssertionError)
MakeError(Abort, EvalError)
MakeError(TypeError, EvalError)

View file

@ -271,6 +271,14 @@ static Expr prim_abort(EvalState & state, const ATermVector & args)
}
static Expr prim_throw(EvalState & state, const ATermVector & args)
{
PathSet context;
throw ThrownError(format("user-thrown exception: `%1%'") %
evalString(state, args[0], context));
}
/* Return an environment variable. Use with care. */
static Expr prim_getEnv(EvalState & state, const ATermVector & args)
{
@ -1026,6 +1034,7 @@ void EvalState::addPrimOps()
addPrimOp("isNull", 1, prim_isNull);
addPrimOp("dependencyClosure", 1, prim_dependencyClosure);
addPrimOp("abort", 1, prim_abort);
addPrimOp("throw", 1, prim_throw);
addPrimOp("__getEnv", 1, prim_getEnv);
addPrimOp("relativise", 2, prim_relativise);

View file

@ -1466,6 +1466,7 @@ void verifyStore(bool checkContents)
nixDB.enumTable(txn, dbValidPaths, paths);
for (Paths::iterator i = paths.begin(); i != paths.end(); ++i) {
checkInterrupt();
if (!pathExists(*i)) {
printMsg(lvlError, format("store path `%1%' disappeared") % *i);
invalidateStorePath(txn, *i);

View file

@ -45,8 +45,14 @@ Upgrade flags:
--eq: "upgrade" if the current version is equal
--always: upgrade regardless of current version
Query types:
Query sources:
--installed: use installed derivations (default)
--available / -a: use derivations available in Nix expression
Query flags:
--xml: show output in XML format
--status / -s: print installed/present status
--no-name: hide derivation names
--attr / -A: shows the unambiguous attribute name of the
@ -55,11 +61,10 @@ Query types:
--compare-versions / -c: compare version to available or installed
--drv-path: print path of derivation
--out-path: print path of derivation output
Query sources:
--installed: use installed derivations (default)
--available / -a: use derivations available in Nix expression
--description: print description
--meta: print all meta attributes (only with --xml)
--prebuilt-only: only show derivations whose prebuilt binaries are
available on this machine or are downloadable
Options:

View file

@ -163,7 +163,6 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems,
ATermList manifest = ATempty;
ATermList inputs = ATempty;
ATermList stateIdentifiers = ATempty;
ATermList runtimeStateArgs = ATempty;
for (DrvInfos::const_iterator i = elems.begin();
i != elems.end(); ++i)
{
@ -195,8 +194,6 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems,
//Insert the new stateIdentifier into the stateIdentifiers Atermlist
stateIdentifiers = ATinsert(stateIdentifiers, makeStr(i->queryStateIdentifier(state)));
//Insert the new runtime state args into the runtimeStateArgs Atermlist
runtimeStateArgs = ATinsert(runtimeStateArgs, makeStr(i->queryRuntimeStateArgs(state)));
inputs = ATinsert(inputs, makeStr(i->queryOutPath(state)));
@ -220,15 +217,13 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems,
Expr topLevel = makeCall(envBuilder, makeAttrs(
ATinsert(
ATmakeList6(
ATmakeList5(
makeBind(toATerm("system"),
makeStr(thisSystem), makeNoPos()),
makeBind(toATerm("derivations"),
makeList(ATreverse(manifest)), makeNoPos()),
makeBind(toATerm("stateIdentifiers"),
makeList(ATreverse(stateIdentifiers)), makeNoPos()),
makeBind(toATerm("runtimeStateArgs"),
makeList(ATreverse(runtimeStateArgs)), makeNoPos()),
makeBind(toATerm("manifest"),
makeStr(manifestFile, singleton<PathSet>(manifestFile)), makeNoPos()),
makeBind(toATerm("nixBinDir"),
@ -536,9 +531,13 @@ static void installDerivations(Globals & globals,
for (DrvInfos::iterator i = installedElems.begin(); i != installedElems.end(); ++i)
{
DrvName drvName(i->name);
MetaInfo meta = i->queryMetaInfo(globals.state);
//We may need to share state
if (!globals.preserveInstalled && newNames.find(drvName.name) != newNames.end()){
if (!globals.preserveInstalled &&
newNames.find(drvName.name) != newNames.end() &&
meta["keep"] != "true"
){
//******** We're gonna check if the component and state indentifiers are the same,
// since we may need to share state in that case.
@ -709,6 +708,9 @@ static void upgradeDerivations(Globals & globals,
{
DrvName drvName(i->name);
MetaInfo meta = i->queryMetaInfo(globals.state);
if (meta["keep"] == "true") continue;
/* Find the derivation in the input Nix expression with the
same name and satisfying the version constraints specified
by upgradeType. If there are multiple matches, take the
@ -997,6 +999,8 @@ static void opQuery(Globals & globals,
bool printDrvPath = false;
bool printOutPath = false;
bool printDescription = false;
bool printMeta = false;
bool prebuiltOnly = false;
bool compareVersions = false;
bool xmlOutput = false;
@ -1013,8 +1017,10 @@ static void opQuery(Globals & globals,
else if (*i == "--compare-versions" || *i == "-c") compareVersions = true;
else if (*i == "--drv-path") printDrvPath = true;
else if (*i == "--out-path") printOutPath = true;
else if (*i == "--meta") printMeta = true;
else if (*i == "--installed") source = sInstalled;
else if (*i == "--available" || *i == "-a") source = sAvailable;
else if (*i == "--prebuilt-only" || *i == "-b") prebuiltOnly = true;
else if (*i == "--xml") xmlOutput = true;
else throw UsageError(format("unknown flag `%1%'") % *i);
@ -1080,6 +1086,12 @@ static void opQuery(Globals & globals,
/* For XML output. */
XMLAttrs attrs;
if (prebuiltOnly) {
if (!store->isValidPath(i->queryOutPath(globals.state)) &&
!store->hasSubstitutes(i->queryOutPath(globals.state)))
continue;
}
if (printStatus) {
bool hasSubs = store->hasSubstitutes(i->queryOutPath(globals.state));
@ -1167,7 +1179,18 @@ static void opQuery(Globals & globals,
}
if (xmlOutput)
xml.writeEmptyElement("item", attrs);
if (printMeta) {
XMLOpenElement item(xml, "item", attrs);
MetaInfo meta = i->queryMetaInfo(globals.state);
for (MetaInfo::iterator j = meta.begin(); j != meta.end(); ++j) {
XMLAttrs attrs2;
attrs2["name"] = j->first;
attrs2["value"] = j->second;
xml.writeEmptyElement("meta", attrs2);
}
}
else
xml.writeEmptyElement("item", attrs);
else
table.push_back(columns);

View file

@ -36,7 +36,7 @@ static void secureChown(uid_t uidFrom, gid_t gidFrom,
to. */
throw Error(error);
if (uidFrom != -1) {
if (uidFrom != (uid_t) -1) {
assert(uidFrom != 0);
if (st.st_uid != uidFrom)
throw Error(error);