forked from lix-project/lix
Revert "Get rid of unicode quotes (#1140)"
This reverts commit f78126bfd6
. There
really is no need for such a massive change...
This commit is contained in:
parent
f78126bfd6
commit
215b70f51e
|
@ -1,5 +1,5 @@
|
||||||
/* This is the implementation of the 'derivation' builtin function.
|
/* This is the implementation of the ‘derivation’ builtin function.
|
||||||
It's actually a wrapper around the 'derivationStrict' primop. */
|
It's actually a wrapper around the ‘derivationStrict’ primop. */
|
||||||
|
|
||||||
drvAttrs @ { outputs ? [ "out" ], ... }:
|
drvAttrs @ { outputs ? [ "out" ], ... }:
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
# Utility function for recursively finding files, e.g.
|
# Utility function for recursively finding files, e.g.
|
||||||
# '$(call rwildcard, path/to/dir, *.c *.h)'.
|
# ‘$(call rwildcard, path/to/dir, *.c *.h)’.
|
||||||
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
|
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
|
||||||
|
|
||||||
# Given a file name, produce the corresponding dependency file
|
# Given a file name, produce the corresponding dependency file
|
||||||
# (e.g. 'foo/bar.o' becomes 'foo/.bar.o.dep').
|
# (e.g. ‘foo/bar.o’ becomes ‘foo/.bar.o.dep’).
|
||||||
filename-to-dep = $(dir $1).$(notdir $1).dep
|
filename-to-dep = $(dir $1).$(notdir $1).dep
|
||||||
|
|
||||||
# Return the full path to a program by looking it up in $PATH, or the
|
# Return the full path to a program by looking it up in $PATH, or the
|
||||||
|
|
|
@ -11,9 +11,9 @@ else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Build a library with symbolic name $(1). The library is defined by
|
# Build a library with symbolic name $(1). The library is defined by
|
||||||
# various variables prefixed by '$(1)_':
|
# various variables prefixed by ‘$(1)_’:
|
||||||
#
|
#
|
||||||
# - $(1)_NAME: the name of the library (e.g. 'libfoo'); defaults to
|
# - $(1)_NAME: the name of the library (e.g. ‘libfoo’); defaults to
|
||||||
# $(1).
|
# $(1).
|
||||||
#
|
#
|
||||||
# - $(1)_DIR: the directory where the (non-installed) library will be
|
# - $(1)_DIR: the directory where the (non-installed) library will be
|
||||||
|
@ -45,7 +45,7 @@ endif
|
||||||
# - $(1)_INSTALL_DIR: the directory where the library will be
|
# - $(1)_INSTALL_DIR: the directory where the library will be
|
||||||
# installed. Defaults to $(libdir).
|
# installed. Defaults to $(libdir).
|
||||||
#
|
#
|
||||||
# - BUILD_SHARED_LIBS: if equal to '1', a dynamic library will be
|
# - BUILD_SHARED_LIBS: if equal to ‘1’, a dynamic library will be
|
||||||
# built, otherwise a static library.
|
# built, otherwise a static library.
|
||||||
define build-library
|
define build-library
|
||||||
$(1)_NAME ?= $(1)
|
$(1)_NAME ?= $(1)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
programs-list :=
|
programs-list :=
|
||||||
|
|
||||||
# Build a program with symbolic name $(1). The program is defined by
|
# Build a program with symbolic name $(1). The program is defined by
|
||||||
# various variables prefixed by '$(1)_':
|
# various variables prefixed by ‘$(1)_’:
|
||||||
#
|
#
|
||||||
# - $(1)_DIR: the directory where the (non-installed) program will be
|
# - $(1)_DIR: the directory where the (non-installed) program will be
|
||||||
# placed.
|
# placed.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
template-files :=
|
template-files :=
|
||||||
|
|
||||||
# Create the file $(1) from $(1).in by running config.status (which
|
# Create the file $(1) from $(1).in by running config.status (which
|
||||||
# substitutes all '@var@' variables set by the configure script).
|
# substitutes all ‘@var@’ variables set by the configure script).
|
||||||
define instantiate-template
|
define instantiate-template
|
||||||
|
|
||||||
clean-files += $(1)
|
clean-files += $(1)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Run program $1 as part of 'make installcheck'.
|
# Run program $1 as part of ‘make installcheck’.
|
||||||
define run-install-test
|
define run-install-test
|
||||||
|
|
||||||
installcheck: $1
|
installcheck: $1
|
||||||
|
|
|
@ -33,7 +33,7 @@ sub readConfig {
|
||||||
my $config = "$confDir/nix.conf";
|
my $config = "$confDir/nix.conf";
|
||||||
return unless -f $config;
|
return unless -f $config;
|
||||||
|
|
||||||
open CONFIG, "<$config" or die "cannot open '$config'";
|
open CONFIG, "<$config" or die "cannot open ‘$config’";
|
||||||
while (<CONFIG>) {
|
while (<CONFIG>) {
|
||||||
/^\s*([\w\-\.]+)\s*=\s*(.*)$/ or next;
|
/^\s*([\w\-\.]+)\s*=\s*(.*)$/ or next;
|
||||||
$config{$1} = $2;
|
$config{$1} = $2;
|
||||||
|
|
|
@ -35,14 +35,14 @@ sub copyToOpen {
|
||||||
my $missingSize = 0;
|
my $missingSize = 0;
|
||||||
$missingSize += (queryPathInfo($_, 1))[3] foreach @missing;
|
$missingSize += (queryPathInfo($_, 1))[3] foreach @missing;
|
||||||
|
|
||||||
printf STDERR "copying %d missing paths (%.2f MiB) to '$sshHost'...\n",
|
printf STDERR "copying %d missing paths (%.2f MiB) to ‘$sshHost’...\n",
|
||||||
scalar(@missing), $missingSize / (1024**2);
|
scalar(@missing), $missingSize / (1024**2);
|
||||||
return if $dryRun;
|
return if $dryRun;
|
||||||
|
|
||||||
# Send the "import paths" command.
|
# Send the "import paths" command.
|
||||||
syswrite($to, pack("L<x4", 4)) or die;
|
syswrite($to, pack("L<x4", 4)) or die;
|
||||||
exportPaths(fileno($to), @missing);
|
exportPaths(fileno($to), @missing);
|
||||||
readInt($from) == 1 or die "remote machine '$sshHost' failed to import closure\n";
|
readInt($from) == 1 or die "remote machine ‘$sshHost’ failed to import closure\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -60,10 +60,10 @@ sub readManifest_ {
|
||||||
# Decompress the manifest if necessary.
|
# Decompress the manifest if necessary.
|
||||||
if ($manifest =~ /\.bz2$/) {
|
if ($manifest =~ /\.bz2$/) {
|
||||||
open MANIFEST, "$Nix::Config::bzip2 -d < $manifest |"
|
open MANIFEST, "$Nix::Config::bzip2 -d < $manifest |"
|
||||||
or die "cannot decompress '$manifest': $!";
|
or die "cannot decompress ‘$manifest’: $!";
|
||||||
} else {
|
} else {
|
||||||
open MANIFEST, "<$manifest"
|
open MANIFEST, "<$manifest"
|
||||||
or die "cannot open '$manifest': $!";
|
or die "cannot open ‘$manifest’: $!";
|
||||||
}
|
}
|
||||||
|
|
||||||
my $inside = 0;
|
my $inside = 0;
|
||||||
|
@ -287,7 +287,7 @@ sub parseNARInfo {
|
||||||
# FIXME: might be useful to support multiple signatures per .narinfo.
|
# FIXME: might be useful to support multiple signatures per .narinfo.
|
||||||
|
|
||||||
if (!defined $sig) {
|
if (!defined $sig) {
|
||||||
warn "NAR info file '$location' lacks a signature; ignoring\n";
|
warn "NAR info file ‘$location’ lacks a signature; ignoring\n";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
my ($keyName, $sig64) = split ":", $sig;
|
my ($keyName, $sig64) = split ":", $sig;
|
||||||
|
@ -295,7 +295,7 @@ sub parseNARInfo {
|
||||||
|
|
||||||
my $publicKey = $Nix::Config::binaryCachePublicKeys{$keyName};
|
my $publicKey = $Nix::Config::binaryCachePublicKeys{$keyName};
|
||||||
if (!defined $publicKey) {
|
if (!defined $publicKey) {
|
||||||
warn "NAR info file '$location' is signed by unknown key '$keyName'; ignoring\n";
|
warn "NAR info file ‘$location’ is signed by unknown key ‘$keyName’; ignoring\n";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,12 +306,12 @@ sub parseNARInfo {
|
||||||
[ map { "$Nix::Config::storeDir/$_" } @refs ]);
|
[ map { "$Nix::Config::storeDir/$_" } @refs ]);
|
||||||
};
|
};
|
||||||
if ($@) {
|
if ($@) {
|
||||||
warn "cannot compute fingerprint of '$location'; ignoring\n";
|
warn "cannot compute fingerprint of ‘$location’; ignoring\n";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checkSignature($publicKey, decode_base64($sig64), $fingerprint)) {
|
if (!checkSignature($publicKey, decode_base64($sig64), $fingerprint)) {
|
||||||
warn "NAR info file '$location' has an incorrect signature; ignoring\n";
|
warn "NAR info file ‘$location’ has an incorrect signature; ignoring\n";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ sub connectToRemoteNix {
|
||||||
|
|
||||||
$extraFlags ||= "";
|
$extraFlags ||= "";
|
||||||
|
|
||||||
# Start 'nix-store --serve' on the remote host.
|
# Start ‘nix-store --serve’ on the remote host.
|
||||||
my ($from, $to);
|
my ($from, $to);
|
||||||
# FIXME: don't start a shell, start ssh directly.
|
# FIXME: don't start a shell, start ssh directly.
|
||||||
my $pid = open2($from, $to, "exec ssh -x -a $sshHost @globalSshOpts @{$sshOpts} nix-store --serve --write $extraFlags");
|
my $pid = open2($from, $to, "exec ssh -x -a $sshHost @globalSshOpts @{$sshOpts} nix-store --serve --write $extraFlags");
|
||||||
|
@ -97,7 +97,7 @@ sub connectToRemoteNix {
|
||||||
syswrite($to, pack("L<x4L<x4", $SERVE_MAGIC_1, $clientVersion)) or die;
|
syswrite($to, pack("L<x4L<x4", $SERVE_MAGIC_1, $clientVersion)) or die;
|
||||||
$magic = readInt($from);
|
$magic = readInt($from);
|
||||||
};
|
};
|
||||||
die "unable to connect to '$sshHost'\n" if $@;
|
die "unable to connect to ‘$sshHost’\n" if $@;
|
||||||
die "did not get valid handshake from remote host\n" if $magic != 0x5452eecb;
|
die "did not get valid handshake from remote host\n" if $magic != 0x5452eecb;
|
||||||
|
|
||||||
my $serverVersion = readInt($from);
|
my $serverVersion = readInt($from);
|
||||||
|
|
|
@ -10,7 +10,7 @@ $urlRE = "(?: [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!
|
||||||
|
|
||||||
sub checkURL {
|
sub checkURL {
|
||||||
my ($url) = @_;
|
my ($url) = @_;
|
||||||
die "invalid URL '$url'\n" unless $url =~ /^ $urlRE $ /x;
|
die "invalid URL ‘$url’\n" unless $url =~ /^ $urlRE $ /x;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub uniq {
|
sub uniq {
|
||||||
|
@ -26,7 +26,7 @@ sub uniq {
|
||||||
|
|
||||||
sub writeFile {
|
sub writeFile {
|
||||||
my ($fn, $s) = @_;
|
my ($fn, $s) = @_;
|
||||||
open TMP, ">$fn" or die "cannot create file '$fn': $!";
|
open TMP, ">$fn" or die "cannot create file ‘$fn’: $!";
|
||||||
print TMP "$s" or die;
|
print TMP "$s" or die;
|
||||||
close TMP or die;
|
close TMP or die;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ sub writeFile {
|
||||||
sub readFile {
|
sub readFile {
|
||||||
local $/ = undef;
|
local $/ = undef;
|
||||||
my ($fn) = @_;
|
my ($fn) = @_;
|
||||||
open TMP, "<$fn" or die "cannot open file '$fn': $!";
|
open TMP, "<$fn" or die "cannot open file ‘$fn’: $!";
|
||||||
my $s = <TMP>;
|
my $s = <TMP>;
|
||||||
close TMP or die;
|
close TMP or die;
|
||||||
return $s;
|
return $s;
|
||||||
|
|
|
@ -209,7 +209,7 @@ REQ: while (1) {
|
||||||
};
|
};
|
||||||
last REQ unless $@;
|
last REQ unless $@;
|
||||||
print STDERR "$@";
|
print STDERR "$@";
|
||||||
warn "unable to open SSH connection to '$hostName', trying other available machines...\n";
|
warn "unable to open SSH connection to ‘$hostName’, trying other available machines...\n";
|
||||||
$from = undef;
|
$from = undef;
|
||||||
$to = undef;
|
$to = undef;
|
||||||
$machine->{enabled} = 0;
|
$machine->{enabled} = 0;
|
||||||
|
@ -251,7 +251,7 @@ close UPLOADLOCK;
|
||||||
|
|
||||||
|
|
||||||
# Perform the build.
|
# Perform the build.
|
||||||
print STDERR "building '$drvPath' on '$hostName'\n";
|
print STDERR "building ‘$drvPath’ on ‘$hostName’\n";
|
||||||
writeInt(6, $to) or die; # == cmdBuildPaths
|
writeInt(6, $to) or die; # == cmdBuildPaths
|
||||||
writeStrings([$drvPath], $to);
|
writeStrings([$drvPath], $to);
|
||||||
writeInt($maxSilentTime, $to);
|
writeInt($maxSilentTime, $to);
|
||||||
|
@ -259,7 +259,7 @@ writeInt($buildTimeout, $to);
|
||||||
my $res = readInt($from);
|
my $res = readInt($from);
|
||||||
if ($res != 0) {
|
if ($res != 0) {
|
||||||
my $msg = decode("utf-8", readString($from));
|
my $msg = decode("utf-8", readString($from));
|
||||||
print STDERR "error: $msg on '$hostName'\n";
|
print STDERR "error: $msg on ‘$hostName’\n";
|
||||||
exit $res;
|
exit $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,13 @@ if ! [ -e $dest ]; then
|
||||||
cmd="mkdir -m 0755 $dest && chown $USER $dest"
|
cmd="mkdir -m 0755 $dest && chown $USER $dest"
|
||||||
echo "directory $dest does not exist; creating it by running '$cmd' using sudo" >&2
|
echo "directory $dest does not exist; creating it by running '$cmd' using sudo" >&2
|
||||||
if ! sudo sh -c "$cmd"; then
|
if ! sudo sh -c "$cmd"; then
|
||||||
echo "$0: please manually run '$cmd' as root to create $dest" >&2
|
echo "$0: please manually run ‘$cmd’ as root to create $dest" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! [ -w $dest ]; then
|
if ! [ -w $dest ]; then
|
||||||
echo "$0: directory $dest exists, but is not writable by you. This could indicate that another user has already performed a single-user installation of Nix on this system. If you wish to enable multi-user support see http://nixos.org/nix/manual/#ssec-multi-user. If you wish to continue with a single-user install for $USER please run 'chown -R $USER $dest' as root." >&2
|
echo "$0: directory $dest exists, but is not writable by you. This could indicate that another user has already performed a single-user installation of Nix on this system. If you wish to enable multi-user support see http://nixos.org/nix/manual/#ssec-multi-user. If you wish to continue with a single-user install for $USER please run ‘chown -R $USER $dest’ as root." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ while (@ARGV) {
|
||||||
exec "man nix-copy-closure" or die;
|
exec "man nix-copy-closure" or die;
|
||||||
}
|
}
|
||||||
elsif ($arg eq "--gzip" || $arg eq "--bzip2" || $arg eq "--xz") {
|
elsif ($arg eq "--gzip" || $arg eq "--bzip2" || $arg eq "--xz") {
|
||||||
warn "$0: '$arg' is not implemented\n" if $arg ne "--gzip";
|
warn "$0: ‘$arg’ is not implemented\n" if $arg ne "--gzip";
|
||||||
push @globalSshOpts, "-C";
|
push @globalSshOpts, "-C";
|
||||||
}
|
}
|
||||||
elsif ($arg eq "--from") {
|
elsif ($arg eq "--from") {
|
||||||
|
@ -51,7 +51,7 @@ while (@ARGV) {
|
||||||
$includeOutputs = 1;
|
$includeOutputs = 1;
|
||||||
}
|
}
|
||||||
elsif ($arg eq "--show-progress") {
|
elsif ($arg eq "--show-progress") {
|
||||||
warn "$0: '$arg' is not implemented\n";
|
warn "$0: ‘$arg’ is not implemented\n";
|
||||||
}
|
}
|
||||||
elsif ($arg eq "--dry-run") {
|
elsif ($arg eq "--dry-run") {
|
||||||
$dryRun = 1;
|
$dryRun = 1;
|
||||||
|
@ -93,7 +93,7 @@ else { # Copy FROM the remote machine.
|
||||||
|
|
||||||
# Export the store paths on the remote machine and import them locally.
|
# Export the store paths on the remote machine and import them locally.
|
||||||
if (scalar @missing > 0) {
|
if (scalar @missing > 0) {
|
||||||
print STDERR "copying ", scalar @missing, " missing paths from '$sshHost'...\n";
|
print STDERR "copying ", scalar @missing, " missing paths from ‘$sshHost’...\n";
|
||||||
writeInt(5, $to); # == cmdExportPaths
|
writeInt(5, $to); # == cmdExportPaths
|
||||||
writeInt(0, $to); # obsolete
|
writeInt(0, $to); # obsolete
|
||||||
writeStrings(\@missing, $to);
|
writeStrings(\@missing, $to);
|
||||||
|
|
|
@ -12,7 +12,7 @@ static bool isDirectory (const Path & path)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(path.c_str(), &st) == -1)
|
if (stat(path.c_str(), &st) == -1)
|
||||||
throw SysError(format("getting status of '%1%'") % path);
|
throw SysError(format("getting status of ‘%1%’") % path);
|
||||||
return S_ISDIR(st.st_mode);
|
return S_ISDIR(st.st_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,18 +53,18 @@ static void createLinks(const Path & srcDir, const Path & dstDir, int priority)
|
||||||
} else if (S_ISLNK(dstSt.st_mode)) {
|
} else if (S_ISLNK(dstSt.st_mode)) {
|
||||||
auto target = readLink(dstFile);
|
auto target = readLink(dstFile);
|
||||||
if (!isDirectory(target))
|
if (!isDirectory(target))
|
||||||
throw Error(format("collision between '%1%' and non-directory '%2%'")
|
throw Error(format("collision between ‘%1%’ and non-directory ‘%2%’")
|
||||||
% srcFile % target);
|
% srcFile % target);
|
||||||
if (unlink(dstFile.c_str()) == -1)
|
if (unlink(dstFile.c_str()) == -1)
|
||||||
throw SysError(format("unlinking '%1%'") % dstFile);
|
throw SysError(format("unlinking ‘%1%’") % dstFile);
|
||||||
if (mkdir(dstFile.c_str(), 0755) == -1)
|
if (mkdir(dstFile.c_str(), 0755) == -1)
|
||||||
throw SysError(format("creating directory '%1%'"));
|
throw SysError(format("creating directory ‘%1%’"));
|
||||||
createLinks(target, dstFile, priorities[dstFile]);
|
createLinks(target, dstFile, priorities[dstFile]);
|
||||||
createLinks(srcFile, dstFile, priority);
|
createLinks(srcFile, dstFile, priority);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (errno != ENOENT)
|
} else if (errno != ENOENT)
|
||||||
throw SysError(format("getting status of '%1%'") % dstFile);
|
throw SysError(format("getting status of ‘%1%’") % dstFile);
|
||||||
} else {
|
} else {
|
||||||
struct stat dstSt;
|
struct stat dstSt;
|
||||||
auto res = lstat(dstFile.c_str(), &dstSt);
|
auto res = lstat(dstFile.c_str(), &dstSt);
|
||||||
|
@ -74,17 +74,17 @@ static void createLinks(const Path & srcDir, const Path & dstDir, int priority)
|
||||||
auto prevPriority = priorities[dstFile];
|
auto prevPriority = priorities[dstFile];
|
||||||
if (prevPriority == priority)
|
if (prevPriority == priority)
|
||||||
throw Error(format(
|
throw Error(format(
|
||||||
"collision between '%1%' and '%2%'; "
|
"collision between ‘%1%’ and ‘%2%’; "
|
||||||
"use 'nix-env --set-flag priority NUMBER PKGNAME' "
|
"use ‘nix-env --set-flag priority NUMBER PKGNAME’ "
|
||||||
"to change the priority of one of the conflicting packages"
|
"to change the priority of one of the conflicting packages"
|
||||||
) % srcFile % target);
|
) % srcFile % target);
|
||||||
if (prevPriority < priority)
|
if (prevPriority < priority)
|
||||||
continue;
|
continue;
|
||||||
if (unlink(dstFile.c_str()) == -1)
|
if (unlink(dstFile.c_str()) == -1)
|
||||||
throw SysError(format("unlinking '%1%'") % dstFile);
|
throw SysError(format("unlinking ‘%1%’") % dstFile);
|
||||||
}
|
}
|
||||||
} else if (errno != ENOENT)
|
} else if (errno != ENOENT)
|
||||||
throw SysError(format("getting status of '%1%'") % dstFile);
|
throw SysError(format("getting status of ‘%1%’") % dstFile);
|
||||||
}
|
}
|
||||||
createSymlink(srcFile, dstFile);
|
createSymlink(srcFile, dstFile);
|
||||||
priorities[dstFile] = priority;
|
priorities[dstFile] = priority;
|
||||||
|
@ -112,7 +112,7 @@ static void addPkg(const Path & pkgDir, int priority)
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
return;
|
return;
|
||||||
throw SysError(format("opening '%1%'") % propagatedFN);
|
throw SysError(format("opening ‘%1%’") % propagatedFN);
|
||||||
}
|
}
|
||||||
propagated = readLine(fd.get());
|
propagated = readLine(fd.get());
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ static void query(std::pair<FdSink, FdSource> & pipes)
|
||||||
std::cout << readLongLong(pipes.second) << std::endl;
|
std::cout << readLongLong(pipes.second) << std::endl;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
throw Error(format("unknown substituter query '%1%'") % cmd);
|
throw Error(format("unknown substituter query ‘%1%’") % cmd);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,10 +132,10 @@ int main(int argc, char * * argv)
|
||||||
throw UsageError("download-via-ssh: --substitute takes exactly two arguments");
|
throw UsageError("download-via-ssh: --substitute takes exactly two arguments");
|
||||||
Path storePath = argv[2];
|
Path storePath = argv[2];
|
||||||
Path destPath = argv[3];
|
Path destPath = argv[3];
|
||||||
printError(format("downloading '%1%' via SSH from '%2%'...") % storePath % host);
|
printError(format("downloading ‘%1%’ via SSH from ‘%2%’...") % storePath % host);
|
||||||
substitute(pipes, storePath, destPath);
|
substitute(pipes, storePath, destPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw UsageError(format("download-via-ssh: unknown command '%1%'") % arg);
|
throw UsageError(format("download-via-ssh: unknown command ‘%1%’") % arg);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ static Strings parseAttrPath(const string & s)
|
||||||
++i;
|
++i;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (i == s.end())
|
if (i == s.end())
|
||||||
throw Error(format("missing closing quote in selection path '%1%'") % s);
|
throw Error(format("missing closing quote in selection path ‘%1%’") % s);
|
||||||
if (*i == '"') break;
|
if (*i == '"') break;
|
||||||
cur.push_back(*i++);
|
cur.push_back(*i++);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ Value * findAlongAttrPath(EvalState & state, const string & attrPath,
|
||||||
Strings tokens = parseAttrPath(attrPath);
|
Strings tokens = parseAttrPath(attrPath);
|
||||||
|
|
||||||
Error attrError =
|
Error attrError =
|
||||||
Error(format("attribute selection path '%1%' does not match expression") % attrPath);
|
Error(format("attribute selection path ‘%1%’ does not match expression") % attrPath);
|
||||||
|
|
||||||
Value * v = &vIn;
|
Value * v = &vIn;
|
||||||
|
|
||||||
|
@ -62,15 +62,15 @@ Value * findAlongAttrPath(EvalState & state, const string & attrPath,
|
||||||
|
|
||||||
if (v->type != tAttrs)
|
if (v->type != tAttrs)
|
||||||
throw TypeError(
|
throw TypeError(
|
||||||
format("the expression selected by the selection path '%1%' should be a set but is %2%")
|
format("the expression selected by the selection path ‘%1%’ should be a set but is %2%")
|
||||||
% attrPath % showType(*v));
|
% attrPath % showType(*v));
|
||||||
|
|
||||||
if (attr.empty())
|
if (attr.empty())
|
||||||
throw Error(format("empty attribute name in selection path '%1%'") % attrPath);
|
throw Error(format("empty attribute name in selection path ‘%1%’") % attrPath);
|
||||||
|
|
||||||
Bindings::iterator a = v->attrs->find(state.symbols.create(attr));
|
Bindings::iterator a = v->attrs->find(state.symbols.create(attr));
|
||||||
if (a == v->attrs->end())
|
if (a == v->attrs->end())
|
||||||
throw Error(format("attribute '%1%' in selection path '%2%' not found") % attr % attrPath);
|
throw Error(format("attribute ‘%1%’ in selection path ‘%2%’ not found") % attr % attrPath);
|
||||||
v = &*a->value;
|
v = &*a->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,11 +78,11 @@ Value * findAlongAttrPath(EvalState & state, const string & attrPath,
|
||||||
|
|
||||||
if (!v->isList())
|
if (!v->isList())
|
||||||
throw TypeError(
|
throw TypeError(
|
||||||
format("the expression selected by the selection path '%1%' should be a list but is %2%")
|
format("the expression selected by the selection path ‘%1%’ should be a list but is %2%")
|
||||||
% attrPath % showType(*v));
|
% attrPath % showType(*v));
|
||||||
|
|
||||||
if (attrIndex >= v->listSize())
|
if (attrIndex >= v->listSize())
|
||||||
throw Error(format("list index %1% in selection path '%2%' is out of range") % attrIndex % attrPath);
|
throw Error(format("list index %1% in selection path ‘%2%’ is out of range") % attrIndex % attrPath);
|
||||||
|
|
||||||
v = v->listElems()[attrIndex];
|
v = v->listElems()[attrIndex];
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ bool parseAutoArgs(Strings::iterator & i,
|
||||||
string arg = *i;
|
string arg = *i;
|
||||||
if (arg != "--arg" && arg != "--argstr") return false;
|
if (arg != "--arg" && arg != "--argstr") return false;
|
||||||
|
|
||||||
UsageError error(format("'%1%' requires two arguments") % arg);
|
UsageError error(format("‘%1%’ requires two arguments") % arg);
|
||||||
|
|
||||||
if (++i == argsEnd) throw error;
|
if (++i == argsEnd) throw error;
|
||||||
string name = *i;
|
string name = *i;
|
||||||
|
@ -46,7 +46,7 @@ bool parseSearchPathArg(Strings::iterator & i,
|
||||||
const Strings::iterator & argsEnd, Strings & searchPath)
|
const Strings::iterator & argsEnd, Strings & searchPath)
|
||||||
{
|
{
|
||||||
if (*i != "-I") return false;
|
if (*i != "-I") return false;
|
||||||
if (++i == argsEnd) throw UsageError("'-I' requires an argument");
|
if (++i == argsEnd) throw UsageError("‘-I’ requires an argument");
|
||||||
searchPath.push_back(*i);
|
searchPath.push_back(*i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -330,7 +330,7 @@ Path EvalState::checkSourcePath(const Path & path_)
|
||||||
if (!restricted) return path_;
|
if (!restricted) return path_;
|
||||||
|
|
||||||
/* Resolve symlinks. */
|
/* Resolve symlinks. */
|
||||||
debug(format("checking access to '%s'") % path_);
|
debug(format("checking access to ‘%s’") % path_);
|
||||||
Path path = canonPath(path_, true);
|
Path path = canonPath(path_, true);
|
||||||
|
|
||||||
for (auto & i : searchPath) {
|
for (auto & i : searchPath) {
|
||||||
|
@ -352,7 +352,7 @@ Path EvalState::checkSourcePath(const Path & path_)
|
||||||
return path;
|
return path;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
throw RestrictedPathError(format("access to path '%1%' is forbidden in restricted mode") % path_);
|
throw RestrictedPathError(format("access to path ‘%1%’ is forbidden in restricted mode") % path_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -505,7 +505,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
|
||||||
return j->value;
|
return j->value;
|
||||||
}
|
}
|
||||||
if (!env->prevWith)
|
if (!env->prevWith)
|
||||||
throwUndefinedVarError("undefined variable '%1%' at %2%", var.name, var.pos);
|
throwUndefinedVarError("undefined variable ‘%1%’ at %2%", var.name, var.pos);
|
||||||
for (unsigned int l = env->prevWith; l; --l, env = env->up) ;
|
for (unsigned int l = env->prevWith; l; --l, env = env->up) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -644,12 +644,12 @@ void EvalState::evalFile(const Path & path, Value & v)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Activity act(*logger, lvlTalkative, format("evaluating file '%1%'") % path2);
|
Activity act(*logger, lvlTalkative, format("evaluating file ‘%1%’") % path2);
|
||||||
Expr * e = parseExprFromFile(checkSourcePath(path2));
|
Expr * e = parseExprFromFile(checkSourcePath(path2));
|
||||||
try {
|
try {
|
||||||
eval(e, v);
|
eval(e, v);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
addErrorPrefix(e, "while evaluating the file '%1%':\n", path2);
|
addErrorPrefix(e, "while evaluating the file ‘%1%’:\n", path2);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -799,7 +799,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
Symbol nameSym = state.symbols.create(nameVal.string.s);
|
Symbol nameSym = state.symbols.create(nameVal.string.s);
|
||||||
Bindings::iterator j = v.attrs->find(nameSym);
|
Bindings::iterator j = v.attrs->find(nameSym);
|
||||||
if (j != v.attrs->end())
|
if (j != v.attrs->end())
|
||||||
throwEvalError("dynamic attribute '%1%' at %2% already defined at %3%", nameSym, i.pos, *j->pos);
|
throwEvalError("dynamic attribute ‘%1%’ at %2% already defined at %3%", nameSym, i.pos, *j->pos);
|
||||||
|
|
||||||
i.valueExpr->setName(nameSym);
|
i.valueExpr->setName(nameSym);
|
||||||
/* Keep sorted order so find can catch duplicates */
|
/* Keep sorted order so find can catch duplicates */
|
||||||
|
@ -887,7 +887,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
} else {
|
} else {
|
||||||
state.forceAttrs(*vAttrs, pos);
|
state.forceAttrs(*vAttrs, pos);
|
||||||
if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
|
if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
|
||||||
throwEvalError("attribute '%1%' missing, at %2%", name, pos);
|
throwEvalError("attribute ‘%1%’ missing, at %2%", name, pos);
|
||||||
}
|
}
|
||||||
vAttrs = j->value;
|
vAttrs = j->value;
|
||||||
pos2 = j->pos;
|
pos2 = j->pos;
|
||||||
|
@ -898,7 +898,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
if (pos2 && pos2->file != state.sDerivationNix)
|
if (pos2 && pos2->file != state.sDerivationNix)
|
||||||
addErrorPrefix(e, "while evaluating the attribute '%1%' at %2%:\n",
|
addErrorPrefix(e, "while evaluating the attribute ‘%1%’ at %2%:\n",
|
||||||
showAttrPath(state, env, attrPath), *pos2);
|
showAttrPath(state, env, attrPath), *pos2);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@ -1040,7 +1040,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
|
||||||
for (auto & i : lambda.formals->formals) {
|
for (auto & i : lambda.formals->formals) {
|
||||||
Bindings::iterator j = arg.attrs->find(i.name);
|
Bindings::iterator j = arg.attrs->find(i.name);
|
||||||
if (j == arg.attrs->end()) {
|
if (j == arg.attrs->end()) {
|
||||||
if (!i.def) throwTypeError("%1% called without required argument '%2%', at %3%",
|
if (!i.def) throwTypeError("%1% called without required argument ‘%2%’, at %3%",
|
||||||
lambda, i.name, pos);
|
lambda, i.name, pos);
|
||||||
env2.values[displ++] = i.def->maybeThunk(*this, env2);
|
env2.values[displ++] = i.def->maybeThunk(*this, env2);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1056,7 +1056,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
|
||||||
user. */
|
user. */
|
||||||
for (auto & i : *arg.attrs)
|
for (auto & i : *arg.attrs)
|
||||||
if (lambda.formals->argNames.find(i.name) == lambda.formals->argNames.end())
|
if (lambda.formals->argNames.find(i.name) == lambda.formals->argNames.end())
|
||||||
throwTypeError("%1% called with unexpected argument '%2%', at %3%", lambda, i.name, pos);
|
throwTypeError("%1% called with unexpected argument ‘%2%’, at %3%", lambda, i.name, pos);
|
||||||
abort(); // can't happen
|
abort(); // can't happen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1114,7 +1114,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
|
||||||
if (j != args.end())
|
if (j != args.end())
|
||||||
actualArgs->attrs->push_back(*j);
|
actualArgs->attrs->push_back(*j);
|
||||||
else if (!i.def)
|
else if (!i.def)
|
||||||
throwTypeError("cannot auto-call a function that has an argument without a default value ('%1%')", i.name);
|
throwTypeError("cannot auto-call a function that has an argument without a default value (‘%1%’)", i.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
actualArgs->attrs->sort();
|
actualArgs->attrs->sort();
|
||||||
|
@ -1343,7 +1343,7 @@ void EvalState::forceValueDeep(Value & v)
|
||||||
try {
|
try {
|
||||||
recurse(*i.value);
|
recurse(*i.value);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
addErrorPrefix(e, "while evaluating the attribute '%1%' at %2%:\n", i.name, *i.pos);
|
addErrorPrefix(e, "while evaluating the attribute ‘%1%’ at %2%:\n", i.name, *i.pos);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1435,10 +1435,10 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos)
|
||||||
string s = forceString(v, pos);
|
string s = forceString(v, pos);
|
||||||
if (v.string.context) {
|
if (v.string.context) {
|
||||||
if (pos)
|
if (pos)
|
||||||
throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%'), at %3%",
|
throwEvalError("the string ‘%1%’ is not allowed to refer to a store path (such as ‘%2%’), at %3%",
|
||||||
v.string.s, v.string.context[0], pos);
|
v.string.s, v.string.context[0], pos);
|
||||||
else
|
else
|
||||||
throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')",
|
throwEvalError("the string ‘%1%’ is not allowed to refer to a store path (such as ‘%2%’)",
|
||||||
v.string.s, v.string.context[0]);
|
v.string.s, v.string.context[0]);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
|
@ -1520,7 +1520,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
|
||||||
string EvalState::copyPathToStore(PathSet & context, const Path & path)
|
string EvalState::copyPathToStore(PathSet & context, const Path & path)
|
||||||
{
|
{
|
||||||
if (nix::isDerivation(path))
|
if (nix::isDerivation(path))
|
||||||
throwEvalError("file names are not allowed to end in '%1%'", drvExtension);
|
throwEvalError("file names are not allowed to end in ‘%1%’", drvExtension);
|
||||||
|
|
||||||
Path dstPath;
|
Path dstPath;
|
||||||
if (srcToStore[path] != "")
|
if (srcToStore[path] != "")
|
||||||
|
@ -1530,7 +1530,7 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path)
|
||||||
? store->computeStorePathForPath(checkSourcePath(path)).first
|
? store->computeStorePathForPath(checkSourcePath(path)).first
|
||||||
: store->addToStore(baseNameOf(path), checkSourcePath(path), true, htSHA256, defaultPathFilter, repair);
|
: store->addToStore(baseNameOf(path), checkSourcePath(path), true, htSHA256, defaultPathFilter, repair);
|
||||||
srcToStore[path] = dstPath;
|
srcToStore[path] = dstPath;
|
||||||
printMsg(lvlChatty, format("copied source '%1%' -> '%2%'")
|
printMsg(lvlChatty, format("copied source ‘%1%’ -> ‘%2%’")
|
||||||
% path % dstPath);
|
% path % dstPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1543,7 +1543,7 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context)
|
||||||
{
|
{
|
||||||
string path = coerceToString(pos, v, context, false, false);
|
string path = coerceToString(pos, v, context, false, false);
|
||||||
if (path == "" || path[0] != '/')
|
if (path == "" || path[0] != '/')
|
||||||
throwEvalError("string '%1%' doesn't represent an absolute path, at %2%", path, pos);
|
throwEvalError("string ‘%1%’ doesn't represent an absolute path, at %2%", path, pos);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ struct PrimOp
|
||||||
struct Env
|
struct Env
|
||||||
{
|
{
|
||||||
Env * up;
|
Env * up;
|
||||||
unsigned short size; // used by 'valueSize'
|
unsigned short size; // used by ‘valueSize’
|
||||||
unsigned short prevWith:15; // nr of levels up to next `with' environment
|
unsigned short prevWith:15; // nr of levels up to next `with' environment
|
||||||
unsigned short haveWithAttrs:1;
|
unsigned short haveWithAttrs:1;
|
||||||
Value * values[0];
|
Value * values[0];
|
||||||
|
|
|
@ -33,7 +33,7 @@ string DrvInfo::queryOutPath()
|
||||||
DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
|
DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
|
||||||
{
|
{
|
||||||
if (outputs.empty()) {
|
if (outputs.empty()) {
|
||||||
/* Get the 'outputs' list. */
|
/* Get the ‘outputs’ list. */
|
||||||
Bindings::iterator i;
|
Bindings::iterator i;
|
||||||
if (attrs && (i = attrs->find(state->sOutputs)) != attrs->end()) {
|
if (attrs && (i = attrs->find(state->sOutputs)) != attrs->end()) {
|
||||||
state->forceList(*i->value, *i->pos);
|
state->forceList(*i->value, *i->pos);
|
||||||
|
@ -46,7 +46,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
|
||||||
if (out == attrs->end()) continue; // FIXME: throw error?
|
if (out == attrs->end()) continue; // FIXME: throw error?
|
||||||
state->forceAttrs(*out->value);
|
state->forceAttrs(*out->value);
|
||||||
|
|
||||||
/* And evaluate its 'outPath' attribute. */
|
/* And evaluate its ‘outPath’ attribute. */
|
||||||
Bindings::iterator outPath = out->value->attrs->find(state->sOutPath);
|
Bindings::iterator outPath = out->value->attrs->find(state->sOutPath);
|
||||||
if (outPath == out->value->attrs->end()) continue; // FIXME: throw error?
|
if (outPath == out->value->attrs->end()) continue; // FIXME: throw error?
|
||||||
PathSet context;
|
PathSet context;
|
||||||
|
@ -61,7 +61,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
|
||||||
/* Check for `meta.outputsToInstall` and return `outputs` reduced to that. */
|
/* Check for `meta.outputsToInstall` and return `outputs` reduced to that. */
|
||||||
const Value * outTI = queryMeta("outputsToInstall");
|
const Value * outTI = queryMeta("outputsToInstall");
|
||||||
if (!outTI) return outputs;
|
if (!outTI) return outputs;
|
||||||
const auto errMsg = Error("this derivation has bad 'meta.outputsToInstall'");
|
const auto errMsg = Error("this derivation has bad ‘meta.outputsToInstall’");
|
||||||
/* ^ this shows during `nix-env -i` right under the bad derivation */
|
/* ^ this shows during `nix-env -i` right under the bad derivation */
|
||||||
if (!outTI->isList()) throw errMsg;
|
if (!outTI->isList()) throw errMsg;
|
||||||
Outputs result;
|
Outputs result;
|
||||||
|
@ -290,7 +290,7 @@ static void getDerivations(EvalState & state, Value & vIn,
|
||||||
attrs.insert(std::pair<string, Symbol>(i.name, i.name));
|
attrs.insert(std::pair<string, Symbol>(i.name, i.name));
|
||||||
|
|
||||||
for (auto & i : attrs) {
|
for (auto & i : attrs) {
|
||||||
Activity act(*logger, lvlDebug, format("evaluating attribute '%1%'") % i.first);
|
Activity act(*logger, lvlDebug, format("evaluating attribute ‘%1%’") % i.first);
|
||||||
string pathPrefix2 = addToPath(pathPrefix, i.first);
|
string pathPrefix2 = addToPath(pathPrefix, i.first);
|
||||||
Value & v2(*v.attrs->find(i.second)->value);
|
Value & v2(*v.attrs->find(i.second)->value);
|
||||||
if (combineChannels)
|
if (combineChannels)
|
||||||
|
|
|
@ -58,7 +58,7 @@ static void parseJSON(EvalState & state, const char * & s, Value & v)
|
||||||
values.push_back(v2);
|
values.push_back(v2);
|
||||||
skipWhitespace(s);
|
skipWhitespace(s);
|
||||||
if (*s == ']') break;
|
if (*s == ']') break;
|
||||||
if (*s != ',') throw JSONParseError("expected ',' or ']' after JSON array element");
|
if (*s != ',') throw JSONParseError("expected ‘,’ or ‘]’ after JSON array element");
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
s++;
|
s++;
|
||||||
|
@ -75,14 +75,14 @@ static void parseJSON(EvalState & state, const char * & s, Value & v)
|
||||||
if (attrs.empty() && *s == '}') break;
|
if (attrs.empty() && *s == '}') break;
|
||||||
string name = parseJSONString(s);
|
string name = parseJSONString(s);
|
||||||
skipWhitespace(s);
|
skipWhitespace(s);
|
||||||
if (*s != ':') throw JSONParseError("expected ':' in JSON object");
|
if (*s != ':') throw JSONParseError("expected ‘:’ in JSON object");
|
||||||
s++;
|
s++;
|
||||||
Value * v2 = state.allocValue();
|
Value * v2 = state.allocValue();
|
||||||
parseJSON(state, s, *v2);
|
parseJSON(state, s, *v2);
|
||||||
attrs[state.symbols.create(name)] = v2;
|
attrs[state.symbols.create(name)] = v2;
|
||||||
skipWhitespace(s);
|
skipWhitespace(s);
|
||||||
if (*s == '}') break;
|
if (*s == '}') break;
|
||||||
if (*s != ',') throw JSONParseError("expected ',' or '}' after JSON member");
|
if (*s != ',') throw JSONParseError("expected ‘,’ or ‘}’ after JSON member");
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
state.mkAttrs(v, attrs.size());
|
state.mkAttrs(v, attrs.size());
|
||||||
|
|
|
@ -124,13 +124,13 @@ or { return OR_KW; }
|
||||||
{INT} { errno = 0;
|
{INT} { errno = 0;
|
||||||
yylval->n = strtol(yytext, 0, 10);
|
yylval->n = strtol(yytext, 0, 10);
|
||||||
if (errno != 0)
|
if (errno != 0)
|
||||||
throw ParseError(format("invalid integer '%1%'") % yytext);
|
throw ParseError(format("invalid integer ‘%1%’") % yytext);
|
||||||
return INT;
|
return INT;
|
||||||
}
|
}
|
||||||
{FLOAT} { errno = 0;
|
{FLOAT} { errno = 0;
|
||||||
yylval->nf = strtod(yytext, 0);
|
yylval->nf = strtod(yytext, 0);
|
||||||
if (errno != 0)
|
if (errno != 0)
|
||||||
throw ParseError(format("invalid float '%1%'") % yytext);
|
throw ParseError(format("invalid float ‘%1%’") % yytext);
|
||||||
return FLOAT;
|
return FLOAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -267,7 +267,7 @@ void ExprVar::bindVars(const StaticEnv & env)
|
||||||
/* Otherwise, the variable must be obtained from the nearest
|
/* Otherwise, the variable must be obtained from the nearest
|
||||||
enclosing `with'. If there is no `with', then we can issue an
|
enclosing `with'. If there is no `with', then we can issue an
|
||||||
"undefined variable" error now. */
|
"undefined variable" error now. */
|
||||||
if (withLevel == -1) throw UndefinedVarError(format("undefined variable '%1%' at %2%") % name % pos);
|
if (withLevel == -1) throw UndefinedVarError(format("undefined variable ‘%1%’ at %2%") % name % pos);
|
||||||
|
|
||||||
fromWith = true;
|
fromWith = true;
|
||||||
this->level = withLevel;
|
this->level = withLevel;
|
||||||
|
@ -419,7 +419,7 @@ void ExprLambda::setName(Symbol & name)
|
||||||
|
|
||||||
string ExprLambda::showNamePos() const
|
string ExprLambda::showNamePos() const
|
||||||
{
|
{
|
||||||
return (format("%1% at %2%") % (name.set() ? "'" + (string) name + "'" : "anonymous function") % pos).str();
|
return (format("%1% at %2%") % (name.set() ? "‘" + (string) name + "’" : "anonymous function") % pos).str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -235,7 +235,7 @@ struct ExprLambda : Expr
|
||||||
: pos(pos), arg(arg), matchAttrs(matchAttrs), formals(formals), body(body)
|
: pos(pos), arg(arg), matchAttrs(matchAttrs), formals(formals), body(body)
|
||||||
{
|
{
|
||||||
if (!arg.empty() && formals && formals->argNames.find(arg) != formals->argNames.end())
|
if (!arg.empty() && formals && formals->argNames.find(arg) != formals->argNames.end())
|
||||||
throw ParseError(format("duplicate formal function argument '%1%' at %2%")
|
throw ParseError(format("duplicate formal function argument ‘%1%’ at %2%")
|
||||||
% arg % pos);
|
% arg % pos);
|
||||||
};
|
};
|
||||||
void setName(Symbol & name);
|
void setName(Symbol & name);
|
||||||
|
|
|
@ -65,14 +65,14 @@ namespace nix {
|
||||||
|
|
||||||
static void dupAttr(const AttrPath & attrPath, const Pos & pos, const Pos & prevPos)
|
static void dupAttr(const AttrPath & attrPath, const Pos & pos, const Pos & prevPos)
|
||||||
{
|
{
|
||||||
throw ParseError(format("attribute '%1%' at %2% already defined at %3%")
|
throw ParseError(format("attribute ‘%1%’ at %2% already defined at %3%")
|
||||||
% showAttrPath(attrPath) % pos % prevPos);
|
% showAttrPath(attrPath) % pos % prevPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dupAttr(Symbol attr, const Pos & pos, const Pos & prevPos)
|
static void dupAttr(Symbol attr, const Pos & pos, const Pos & prevPos)
|
||||||
{
|
{
|
||||||
throw ParseError(format("attribute '%1%' at %2% already defined at %3%")
|
throw ParseError(format("attribute ‘%1%’ at %2% already defined at %3%")
|
||||||
% attr % pos % prevPos);
|
% attr % pos % prevPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ static void addAttr(ExprAttrs * attrs, AttrPath & attrPath,
|
||||||
static void addFormal(const Pos & pos, Formals * formals, const Formal & formal)
|
static void addFormal(const Pos & pos, Formals * formals, const Formal & formal)
|
||||||
{
|
{
|
||||||
if (formals->argNames.find(formal.name) != formals->argNames.end())
|
if (formals->argNames.find(formal.name) != formals->argNames.end())
|
||||||
throw ParseError(format("duplicate formal function argument '%1%' at %2%")
|
throw ParseError(format("duplicate formal function argument ‘%1%’ at %2%")
|
||||||
% formal.name % pos);
|
% formal.name % pos);
|
||||||
formals->formals.push_front(formal);
|
formals->formals.push_front(formal);
|
||||||
formals->argNames.insert(formal.name);
|
formals->argNames.insert(formal.name);
|
||||||
|
@ -356,7 +356,7 @@ expr_select
|
||||||
| expr_simple '.' attrpath OR_KW expr_select
|
| expr_simple '.' attrpath OR_KW expr_select
|
||||||
{ $$ = new ExprSelect(CUR_POS, $1, *$3, $5); }
|
{ $$ = new ExprSelect(CUR_POS, $1, *$3, $5); }
|
||||||
| /* Backwards compatibility: because Nixpkgs has a rarely used
|
| /* Backwards compatibility: because Nixpkgs has a rarely used
|
||||||
function named 'or', allow stuff like 'map or [...]'. */
|
function named ‘or’, allow stuff like ‘map or [...]’. */
|
||||||
expr_simple OR_KW
|
expr_simple OR_KW
|
||||||
{ $$ = new ExprApp(CUR_POS, $1, new ExprVar(CUR_POS, data->symbols.create("or"))); }
|
{ $$ = new ExprApp(CUR_POS, $1, new ExprVar(CUR_POS, data->symbols.create("or"))); }
|
||||||
| expr_simple { $$ = $1; }
|
| expr_simple { $$ = $1; }
|
||||||
|
@ -564,7 +564,7 @@ Path resolveExprPath(Path path)
|
||||||
struct stat st;
|
struct stat st;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting status of '%1%'") % path);
|
throw SysError(format("getting status of ‘%1%’") % path);
|
||||||
if (!S_ISLNK(st.st_mode)) break;
|
if (!S_ISLNK(st.st_mode)) break;
|
||||||
path = absPath(readLink(path), dirOf(path));
|
path = absPath(readLink(path), dirOf(path));
|
||||||
}
|
}
|
||||||
|
@ -642,7 +642,7 @@ Path EvalState::findFile(SearchPath & searchPath, const string & path, const Pos
|
||||||
if (pathExists(res)) return canonPath(res);
|
if (pathExists(res)) return canonPath(res);
|
||||||
}
|
}
|
||||||
format f = format(
|
format f = format(
|
||||||
"file '%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)"
|
"file ‘%1%’ was not found in the Nix search path (add it using $NIX_PATH or -I)"
|
||||||
+ string(pos ? ", at %2%" : ""));
|
+ string(pos ? ", at %2%" : ""));
|
||||||
f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
|
f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
|
||||||
throw ThrownError(f % path % pos);
|
throw ThrownError(f % path % pos);
|
||||||
|
@ -664,7 +664,7 @@ std::pair<bool, std::string> EvalState::resolveSearchPathElem(const SearchPathEl
|
||||||
else
|
else
|
||||||
res = { true, getDownloader()->downloadCached(store, elem.second, true) };
|
res = { true, getDownloader()->downloadCached(store, elem.second, true) };
|
||||||
} catch (DownloadError & e) {
|
} catch (DownloadError & e) {
|
||||||
printError(format("warning: Nix search path entry '%1%' cannot be downloaded, ignoring") % elem.second);
|
printError(format("warning: Nix search path entry ‘%1%’ cannot be downloaded, ignoring") % elem.second);
|
||||||
res = { false, "" };
|
res = { false, "" };
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -672,12 +672,12 @@ std::pair<bool, std::string> EvalState::resolveSearchPathElem(const SearchPathEl
|
||||||
if (pathExists(path))
|
if (pathExists(path))
|
||||||
res = { true, path };
|
res = { true, path };
|
||||||
else {
|
else {
|
||||||
printError(format("warning: Nix search path entry '%1%' does not exist, ignoring") % elem.second);
|
printError(format("warning: Nix search path entry ‘%1%’ does not exist, ignoring") % elem.second);
|
||||||
res = { false, "" };
|
res = { false, "" };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(format("resolved search path element '%s' to '%s'") % elem.second % res.second);
|
debug(format("resolved search path element ‘%s’ to ‘%s’") % elem.second % res.second);
|
||||||
|
|
||||||
searchPathResolved[elem.second] = res;
|
searchPathResolved[elem.second] = res;
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace nix {
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/* Decode a context string '!<name>!<path>' into a pair <path,
|
/* Decode a context string ‘!<name>!<path>’ into a pair <path,
|
||||||
name>. */
|
name>. */
|
||||||
std::pair<string, string> decodeContext(const string & s)
|
std::pair<string, string> decodeContext(const string & s)
|
||||||
{
|
{
|
||||||
|
@ -43,7 +43,7 @@ std::pair<string, string> decodeContext(const string & s)
|
||||||
|
|
||||||
|
|
||||||
InvalidPathError::InvalidPathError(const Path & path) :
|
InvalidPathError::InvalidPathError(const Path & path) :
|
||||||
EvalError(format("path '%1%' is not valid") % path), path(path) {}
|
EvalError(format("path ‘%1%’ is not valid") % path), path(path) {}
|
||||||
|
|
||||||
void EvalState::realiseContext(const PathSet & context)
|
void EvalState::realiseContext(const PathSet & context)
|
||||||
{
|
{
|
||||||
|
@ -77,7 +77,7 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
|
||||||
try {
|
try {
|
||||||
state.realiseContext(context);
|
state.realiseContext(context);
|
||||||
} catch (InvalidPathError & e) {
|
} catch (InvalidPathError & e) {
|
||||||
throw EvalError(format("cannot import '%1%', since path '%2%' is not valid, at %3%")
|
throw EvalError(format("cannot import ‘%1%’, since path ‘%2%’ is not valid, at %3%")
|
||||||
% path % e.path % pos);
|
% path % e.path % pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
|
||||||
env->values[displ++] = attr.value;
|
env->values[displ++] = attr.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Activity act(*logger, lvlTalkative, format("evaluating file '%1%'") % path);
|
Activity act(*logger, lvlTalkative, format("evaluating file ‘%1%’") % path);
|
||||||
Expr * e = state.parseExprFromFile(resolveExprPath(path), staticEnv);
|
Expr * e = state.parseExprFromFile(resolveExprPath(path), staticEnv);
|
||||||
|
|
||||||
e->eval(state, *env, v);
|
e->eval(state, *env, v);
|
||||||
|
@ -146,7 +146,7 @@ static void prim_importNative(EvalState & state, const Pos & pos, Value * * args
|
||||||
try {
|
try {
|
||||||
state.realiseContext(context);
|
state.realiseContext(context);
|
||||||
} catch (InvalidPathError & e) {
|
} catch (InvalidPathError & e) {
|
||||||
throw EvalError(format("cannot import '%1%', since path '%2%' is not valid, at %3%")
|
throw EvalError(format("cannot import ‘%1%’, since path ‘%2%’ is not valid, at %3%")
|
||||||
% path % e.path % pos);
|
% path % e.path % pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,16 +156,16 @@ static void prim_importNative(EvalState & state, const Pos & pos, Value * * args
|
||||||
|
|
||||||
void *handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
void *handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
||||||
if (!handle)
|
if (!handle)
|
||||||
throw EvalError(format("could not open '%1%': %2%") % path % dlerror());
|
throw EvalError(format("could not open ‘%1%’: %2%") % path % dlerror());
|
||||||
|
|
||||||
dlerror();
|
dlerror();
|
||||||
ValueInitializer func = (ValueInitializer) dlsym(handle, sym.c_str());
|
ValueInitializer func = (ValueInitializer) dlsym(handle, sym.c_str());
|
||||||
if(!func) {
|
if(!func) {
|
||||||
char *message = dlerror();
|
char *message = dlerror();
|
||||||
if (message)
|
if (message)
|
||||||
throw EvalError(format("could not load symbol '%1%' from '%2%': %3%") % sym % path % message);
|
throw EvalError(format("could not load symbol ‘%1%’ from ‘%2%’: %3%") % sym % path % message);
|
||||||
else
|
else
|
||||||
throw EvalError(format("symbol '%1%' from '%2%' resolved to NULL when a function pointer was expected")
|
throw EvalError(format("symbol ‘%1%’ from ‘%2%’ resolved to NULL when a function pointer was expected")
|
||||||
% sym % path);
|
% sym % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
|
||||||
Bindings::iterator startSet =
|
Bindings::iterator startSet =
|
||||||
args[0]->attrs->find(state.symbols.create("startSet"));
|
args[0]->attrs->find(state.symbols.create("startSet"));
|
||||||
if (startSet == args[0]->attrs->end())
|
if (startSet == args[0]->attrs->end())
|
||||||
throw EvalError(format("attribute 'startSet' required, at %1%") % pos);
|
throw EvalError(format("attribute ‘startSet’ required, at %1%") % pos);
|
||||||
state.forceList(*startSet->value, pos);
|
state.forceList(*startSet->value, pos);
|
||||||
|
|
||||||
ValueList workSet;
|
ValueList workSet;
|
||||||
|
@ -303,7 +303,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
|
||||||
Bindings::iterator op =
|
Bindings::iterator op =
|
||||||
args[0]->attrs->find(state.symbols.create("operator"));
|
args[0]->attrs->find(state.symbols.create("operator"));
|
||||||
if (op == args[0]->attrs->end())
|
if (op == args[0]->attrs->end())
|
||||||
throw EvalError(format("attribute 'operator' required, at %1%") % pos);
|
throw EvalError(format("attribute ‘operator’ required, at %1%") % pos);
|
||||||
state.forceValue(*op->value);
|
state.forceValue(*op->value);
|
||||||
|
|
||||||
/* Construct the closure by applying the operator to element of
|
/* Construct the closure by applying the operator to element of
|
||||||
|
@ -322,7 +322,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
|
||||||
Bindings::iterator key =
|
Bindings::iterator key =
|
||||||
e->attrs->find(state.symbols.create("key"));
|
e->attrs->find(state.symbols.create("key"));
|
||||||
if (key == e->attrs->end())
|
if (key == e->attrs->end())
|
||||||
throw EvalError(format("attribute 'key' required, at %1%") % pos);
|
throw EvalError(format("attribute ‘key’ required, at %1%") % pos);
|
||||||
state.forceValue(*key->value);
|
state.forceValue(*key->value);
|
||||||
|
|
||||||
if (doneKeys.find(key->value) != doneKeys.end()) continue;
|
if (doneKeys.find(key->value) != doneKeys.end()) continue;
|
||||||
|
@ -353,7 +353,7 @@ static void prim_abort(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string s = state.coerceToString(pos, *args[0], context);
|
string s = state.coerceToString(pos, *args[0], context);
|
||||||
throw Abort(format("evaluation aborted with the following error message: '%1%'") % s);
|
throw Abort(format("evaluation aborted with the following error message: ‘%1%’") % s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -464,13 +464,13 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
/* Figure out the name first (for stack backtraces). */
|
/* Figure out the name first (for stack backtraces). */
|
||||||
Bindings::iterator attr = args[0]->attrs->find(state.sName);
|
Bindings::iterator attr = args[0]->attrs->find(state.sName);
|
||||||
if (attr == args[0]->attrs->end())
|
if (attr == args[0]->attrs->end())
|
||||||
throw EvalError(format("required attribute 'name' missing, at %1%") % pos);
|
throw EvalError(format("required attribute ‘name’ missing, at %1%") % pos);
|
||||||
string drvName;
|
string drvName;
|
||||||
Pos & posDrvName(*attr->pos);
|
Pos & posDrvName(*attr->pos);
|
||||||
try {
|
try {
|
||||||
drvName = state.forceStringNoCtx(*attr->value, pos);
|
drvName = state.forceStringNoCtx(*attr->value, pos);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addPrefix(format("while evaluating the derivation attribute 'name' at %1%:\n") % posDrvName);
|
e.addPrefix(format("while evaluating the derivation attribute ‘name’ at %1%:\n") % posDrvName);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
for (auto & i : *args[0]->attrs) {
|
for (auto & i : *args[0]->attrs) {
|
||||||
if (i.name == state.sIgnoreNulls) continue;
|
if (i.name == state.sIgnoreNulls) continue;
|
||||||
string key = i.name;
|
string key = i.name;
|
||||||
Activity act(*logger, lvlVomit, format("processing attribute '%1%'") % key);
|
Activity act(*logger, lvlVomit, format("processing attribute ‘%1%’") % key);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
@ -522,28 +522,28 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
else if (i.name == state.sSystem) drv.platform = s;
|
else if (i.name == state.sSystem) drv.platform = s;
|
||||||
else if (i.name == state.sName) {
|
else if (i.name == state.sName) {
|
||||||
drvName = s;
|
drvName = s;
|
||||||
printMsg(lvlVomit, format("derivation name is '%1%'") % drvName);
|
printMsg(lvlVomit, format("derivation name is ‘%1%’") % drvName);
|
||||||
}
|
}
|
||||||
else if (key == "outputHash") outputHash = s;
|
else if (key == "outputHash") outputHash = s;
|
||||||
else if (key == "outputHashAlgo") outputHashAlgo = s;
|
else if (key == "outputHashAlgo") outputHashAlgo = s;
|
||||||
else if (key == "outputHashMode") {
|
else if (key == "outputHashMode") {
|
||||||
if (s == "recursive") outputHashRecursive = true;
|
if (s == "recursive") outputHashRecursive = true;
|
||||||
else if (s == "flat") outputHashRecursive = false;
|
else if (s == "flat") outputHashRecursive = false;
|
||||||
else throw EvalError(format("invalid value '%1%' for 'outputHashMode' attribute, at %2%") % s % posDrvName);
|
else throw EvalError(format("invalid value ‘%1%’ for ‘outputHashMode’ attribute, at %2%") % s % posDrvName);
|
||||||
}
|
}
|
||||||
else if (key == "outputs") {
|
else if (key == "outputs") {
|
||||||
Strings tmp = tokenizeString<Strings>(s);
|
Strings tmp = tokenizeString<Strings>(s);
|
||||||
outputs.clear();
|
outputs.clear();
|
||||||
for (auto & j : tmp) {
|
for (auto & j : tmp) {
|
||||||
if (outputs.find(j) != outputs.end())
|
if (outputs.find(j) != outputs.end())
|
||||||
throw EvalError(format("duplicate derivation output '%1%', at %2%") % j % posDrvName);
|
throw EvalError(format("duplicate derivation output ‘%1%’, at %2%") % j % posDrvName);
|
||||||
/* !!! Check whether j is a valid attribute
|
/* !!! Check whether j is a valid attribute
|
||||||
name. */
|
name. */
|
||||||
/* Derivations cannot be named 'drv', because
|
/* Derivations cannot be named ‘drv’, because
|
||||||
then we'd have an attribute 'drvPath' in
|
then we'd have an attribute ‘drvPath’ in
|
||||||
the resulting set. */
|
the resulting set. */
|
||||||
if (j == "drv")
|
if (j == "drv")
|
||||||
throw EvalError(format("invalid derivation output name 'drv', at %1%") % posDrvName);
|
throw EvalError(format("invalid derivation output name ‘drv’, at %1%") % posDrvName);
|
||||||
outputs.insert(j);
|
outputs.insert(j);
|
||||||
}
|
}
|
||||||
if (outputs.empty())
|
if (outputs.empty())
|
||||||
|
@ -552,7 +552,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addPrefix(format("while evaluating the attribute '%1%' of the derivation '%2%' at %3%:\n")
|
e.addPrefix(format("while evaluating the attribute ‘%1%’ of the derivation ‘%2%’ at %3%:\n")
|
||||||
% key % drvName % posDrvName);
|
% key % drvName % posDrvName);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@ -585,14 +585,14 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
else if (path.at(0) == '~')
|
else if (path.at(0) == '~')
|
||||||
drv.inputSrcs.insert(string(path, 1));
|
drv.inputSrcs.insert(string(path, 1));
|
||||||
|
|
||||||
/* Handle derivation outputs of the form '!<name>!<path>'. */
|
/* Handle derivation outputs of the form ‘!<name>!<path>’. */
|
||||||
else if (path.at(0) == '!') {
|
else if (path.at(0) == '!') {
|
||||||
std::pair<string, string> ctx = decodeContext(path);
|
std::pair<string, string> ctx = decodeContext(path);
|
||||||
drv.inputDrvs[ctx.first].insert(ctx.second);
|
drv.inputDrvs[ctx.first].insert(ctx.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle derivation contexts returned by
|
/* Handle derivation contexts returned by
|
||||||
'builtins.storePath'. */
|
‘builtins.storePath’. */
|
||||||
else if (isDerivation(path))
|
else if (isDerivation(path))
|
||||||
drv.inputDrvs[path] = state.store->queryDerivationOutputNames(path);
|
drv.inputDrvs[path] = state.store->queryDerivationOutputNames(path);
|
||||||
|
|
||||||
|
@ -603,14 +603,14 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
|
|
||||||
/* Do we have all required attributes? */
|
/* Do we have all required attributes? */
|
||||||
if (drv.builder == "")
|
if (drv.builder == "")
|
||||||
throw EvalError(format("required attribute 'builder' missing, at %1%") % posDrvName);
|
throw EvalError(format("required attribute ‘builder’ missing, at %1%") % posDrvName);
|
||||||
if (drv.platform == "")
|
if (drv.platform == "")
|
||||||
throw EvalError(format("required attribute 'system' missing, at %1%") % posDrvName);
|
throw EvalError(format("required attribute ‘system’ missing, at %1%") % posDrvName);
|
||||||
|
|
||||||
/* Check whether the derivation name is valid. */
|
/* Check whether the derivation name is valid. */
|
||||||
checkStoreName(drvName);
|
checkStoreName(drvName);
|
||||||
if (isDerivation(drvName))
|
if (isDerivation(drvName))
|
||||||
throw EvalError(format("derivation names are not allowed to end in '%1%', at %2%")
|
throw EvalError(format("derivation names are not allowed to end in ‘%1%’, at %2%")
|
||||||
% drvExtension % posDrvName);
|
% drvExtension % posDrvName);
|
||||||
|
|
||||||
if (outputHash != "") {
|
if (outputHash != "") {
|
||||||
|
@ -620,7 +620,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
|
|
||||||
HashType ht = parseHashType(outputHashAlgo);
|
HashType ht = parseHashType(outputHashAlgo);
|
||||||
if (ht == htUnknown)
|
if (ht == htUnknown)
|
||||||
throw EvalError(format("unknown hash algorithm '%1%', at %2%") % outputHashAlgo % posDrvName);
|
throw EvalError(format("unknown hash algorithm ‘%1%’, at %2%") % outputHashAlgo % posDrvName);
|
||||||
Hash h = parseHash16or32(ht, outputHash);
|
Hash h = parseHash16or32(ht, outputHash);
|
||||||
outputHash = printHash(h);
|
outputHash = printHash(h);
|
||||||
if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo;
|
if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo;
|
||||||
|
@ -656,7 +656,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
/* Write the resulting term into the Nix store directory. */
|
/* Write the resulting term into the Nix store directory. */
|
||||||
Path drvPath = writeDerivation(state.store, drv, drvName, state.repair);
|
Path drvPath = writeDerivation(state.store, drv, drvName, state.repair);
|
||||||
|
|
||||||
printMsg(lvlChatty, format("instantiated '%1%' -> '%2%'")
|
printMsg(lvlChatty, format("instantiated ‘%1%’ -> ‘%2%’")
|
||||||
% drvName % drvPath);
|
% drvName % drvPath);
|
||||||
|
|
||||||
/* Optimisation, but required in read-only mode! because in that
|
/* Optimisation, but required in read-only mode! because in that
|
||||||
|
@ -676,11 +676,11 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
|
|
||||||
/* Return a placeholder string for the specified output that will be
|
/* Return a placeholder string for the specified output that will be
|
||||||
substituted by the corresponding output path at build time. For
|
substituted by the corresponding output path at build time. For
|
||||||
example, 'placeholder "out"' returns the string
|
example, ‘placeholder "out"’ returns the string
|
||||||
/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9. At build
|
/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9. At build
|
||||||
time, any occurence of this string in an derivation attribute will
|
time, any occurence of this string in an derivation attribute will
|
||||||
be replaced with the concrete path in the Nix store of the output
|
be replaced with the concrete path in the Nix store of the output
|
||||||
'out'. */
|
‘out’. */
|
||||||
static void prim_placeholder(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_placeholder(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
mkString(v, hashPlaceholder(state.forceStringNoCtx(*args[0], pos)));
|
mkString(v, hashPlaceholder(state.forceStringNoCtx(*args[0], pos)));
|
||||||
|
@ -713,12 +713,12 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = state.checkSourcePath(state.coerceToPath(pos, *args[0], context));
|
Path path = state.checkSourcePath(state.coerceToPath(pos, *args[0], context));
|
||||||
/* Resolve symlinks in 'path', unless 'path' itself is a symlink
|
/* Resolve symlinks in ‘path’, unless ‘path’ itself is a symlink
|
||||||
directly in the store. The latter condition is necessary so
|
directly in the store. The latter condition is necessary so
|
||||||
e.g. nix-push does the right thing. */
|
e.g. nix-push does the right thing. */
|
||||||
if (!state.store->isStorePath(path)) path = canonPath(path, true);
|
if (!state.store->isStorePath(path)) path = canonPath(path, true);
|
||||||
if (!state.store->isInStore(path))
|
if (!state.store->isInStore(path))
|
||||||
throw EvalError(format("path '%1%' is not in the Nix store, at %2%") % path % pos);
|
throw EvalError(format("path ‘%1%’ is not in the Nix store, at %2%") % path % pos);
|
||||||
Path path2 = state.store->toStorePath(path);
|
Path path2 = state.store->toStorePath(path);
|
||||||
if (!settings.readOnlyMode)
|
if (!settings.readOnlyMode)
|
||||||
state.store->ensurePath(path2);
|
state.store->ensurePath(path2);
|
||||||
|
@ -732,12 +732,12 @@ static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args,
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = state.coerceToPath(pos, *args[0], context);
|
Path path = state.coerceToPath(pos, *args[0], context);
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
throw EvalError(format("string '%1%' cannot refer to other paths, at %2%") % path % pos);
|
throw EvalError(format("string ‘%1%’ cannot refer to other paths, at %2%") % path % pos);
|
||||||
try {
|
try {
|
||||||
mkBool(v, pathExists(state.checkSourcePath(path)));
|
mkBool(v, pathExists(state.checkSourcePath(path)));
|
||||||
} catch (SysError & e) {
|
} catch (SysError & e) {
|
||||||
/* Don't give away info from errors while canonicalising
|
/* Don't give away info from errors while canonicalising
|
||||||
'path' in restricted mode. */
|
‘path’ in restricted mode. */
|
||||||
mkBool(v, false);
|
mkBool(v, false);
|
||||||
} catch (RestrictedPathError & e) {
|
} catch (RestrictedPathError & e) {
|
||||||
mkBool(v, false);
|
mkBool(v, false);
|
||||||
|
@ -773,18 +773,18 @@ static void prim_readFile(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
try {
|
try {
|
||||||
state.realiseContext(context);
|
state.realiseContext(context);
|
||||||
} catch (InvalidPathError & e) {
|
} catch (InvalidPathError & e) {
|
||||||
throw EvalError(format("cannot read '%1%', since path '%2%' is not valid, at %3%")
|
throw EvalError(format("cannot read ‘%1%’, since path ‘%2%’ is not valid, at %3%")
|
||||||
% path % e.path % pos);
|
% path % e.path % pos);
|
||||||
}
|
}
|
||||||
string s = readFile(state.checkSourcePath(path));
|
string s = readFile(state.checkSourcePath(path));
|
||||||
if (s.find((char) 0) != string::npos)
|
if (s.find((char) 0) != string::npos)
|
||||||
throw Error(format("the contents of the file '%1%' cannot be represented as a Nix string") % path);
|
throw Error(format("the contents of the file ‘%1%’ cannot be represented as a Nix string") % path);
|
||||||
mkString(v, s.c_str(), context);
|
mkString(v, s.c_str(), context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Find a file in the Nix search path. Used to implement <x> paths,
|
/* Find a file in the Nix search path. Used to implement <x> paths,
|
||||||
which are desugared to 'findFile __nixPath "x"'. */
|
which are desugared to ‘findFile __nixPath "x"’. */
|
||||||
static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceList(*args[0], pos);
|
state.forceList(*args[0], pos);
|
||||||
|
@ -802,7 +802,7 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
|
|
||||||
i = v2.attrs->find(state.symbols.create("path"));
|
i = v2.attrs->find(state.symbols.create("path"));
|
||||||
if (i == v2.attrs->end())
|
if (i == v2.attrs->end())
|
||||||
throw EvalError(format("attribute 'path' missing, at %1%") % pos);
|
throw EvalError(format("attribute ‘path’ missing, at %1%") % pos);
|
||||||
|
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string path = state.coerceToString(pos, *i->value, context, false, false);
|
string path = state.coerceToString(pos, *i->value, context, false, false);
|
||||||
|
@ -810,7 +810,7 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
try {
|
try {
|
||||||
state.realiseContext(context);
|
state.realiseContext(context);
|
||||||
} catch (InvalidPathError & e) {
|
} catch (InvalidPathError & e) {
|
||||||
throw EvalError(format("cannot find '%1%', since path '%2%' is not valid, at %3%")
|
throw EvalError(format("cannot find ‘%1%’, since path ‘%2%’ is not valid, at %3%")
|
||||||
% path % e.path % pos);
|
% path % e.path % pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,7 +830,7 @@ static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Val
|
||||||
try {
|
try {
|
||||||
state.realiseContext(ctx);
|
state.realiseContext(ctx);
|
||||||
} catch (InvalidPathError & e) {
|
} catch (InvalidPathError & e) {
|
||||||
throw EvalError(format("cannot read '%1%', since path '%2%' is not valid, at %3%")
|
throw EvalError(format("cannot read ‘%1%’, since path ‘%2%’ is not valid, at %3%")
|
||||||
% path % e.path % pos);
|
% path % e.path % pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -904,7 +904,7 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu
|
||||||
if (isDerivation(path)) {
|
if (isDerivation(path)) {
|
||||||
/* See prim_unsafeDiscardOutputDependency. */
|
/* See prim_unsafeDiscardOutputDependency. */
|
||||||
if (path.at(0) != '~')
|
if (path.at(0) != '~')
|
||||||
throw EvalError(format("in 'toFile': the file '%1%' cannot refer to derivation outputs, at %2%") % name % pos);
|
throw EvalError(format("in ‘toFile’: the file ‘%1%’ cannot refer to derivation outputs, at %2%") % name % pos);
|
||||||
path = string(path, 1);
|
path = string(path, 1);
|
||||||
}
|
}
|
||||||
refs.insert(path);
|
refs.insert(path);
|
||||||
|
@ -937,7 +937,7 @@ struct FilterFromExpr : PathFilter
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError(format("getting attributes of path ‘%1%’") % path);
|
||||||
|
|
||||||
/* Call the filter function. The first argument is the path,
|
/* Call the filter function. The first argument is the path,
|
||||||
the second is a string indicating the type of the file. */
|
the second is a string indicating the type of the file. */
|
||||||
|
@ -967,11 +967,11 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = state.coerceToPath(pos, *args[1], context);
|
Path path = state.coerceToPath(pos, *args[1], context);
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
throw EvalError(format("string '%1%' cannot refer to other paths, at %2%") % path % pos);
|
throw EvalError(format("string ‘%1%’ cannot refer to other paths, at %2%") % path % pos);
|
||||||
|
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0]);
|
||||||
if (args[0]->type != tLambda)
|
if (args[0]->type != tLambda)
|
||||||
throw TypeError(format("first argument in call to 'filterSource' is not a function but %1%, at %2%") % showType(*args[0]) % pos);
|
throw TypeError(format("first argument in call to ‘filterSource’ is not a function but %1%, at %2%") % showType(*args[0]) % pos);
|
||||||
|
|
||||||
FilterFromExpr filter(state, *args[0], pos);
|
FilterFromExpr filter(state, *args[0], pos);
|
||||||
|
|
||||||
|
@ -1035,7 +1035,7 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
// !!! Should we create a symbol here or just do a lookup?
|
// !!! Should we create a symbol here or just do a lookup?
|
||||||
Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
|
Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
|
||||||
if (i == args[1]->attrs->end())
|
if (i == args[1]->attrs->end())
|
||||||
throw EvalError(format("attribute '%1%' missing, at %2%") % attr % pos);
|
throw EvalError(format("attribute ‘%1%’ missing, at %2%") % attr % pos);
|
||||||
// !!! add to stack trace?
|
// !!! add to stack trace?
|
||||||
if (state.countCalls && i->pos) state.attrSelects[*i->pos]++;
|
if (state.countCalls && i->pos) state.attrSelects[*i->pos]++;
|
||||||
state.forceValue(*i->value);
|
state.forceValue(*i->value);
|
||||||
|
@ -1115,14 +1115,14 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args,
|
||||||
|
|
||||||
Bindings::iterator j = v2.attrs->find(state.sName);
|
Bindings::iterator j = v2.attrs->find(state.sName);
|
||||||
if (j == v2.attrs->end())
|
if (j == v2.attrs->end())
|
||||||
throw TypeError(format("'name' attribute missing in a call to 'listToAttrs', at %1%") % pos);
|
throw TypeError(format("‘name’ attribute missing in a call to ‘listToAttrs’, at %1%") % pos);
|
||||||
string name = state.forceStringNoCtx(*j->value, pos);
|
string name = state.forceStringNoCtx(*j->value, pos);
|
||||||
|
|
||||||
Symbol sym = state.symbols.create(name);
|
Symbol sym = state.symbols.create(name);
|
||||||
if (seen.find(sym) == seen.end()) {
|
if (seen.find(sym) == seen.end()) {
|
||||||
Bindings::iterator j2 = v2.attrs->find(state.symbols.create(state.sValue));
|
Bindings::iterator j2 = v2.attrs->find(state.symbols.create(state.sValue));
|
||||||
if (j2 == v2.attrs->end())
|
if (j2 == v2.attrs->end())
|
||||||
throw TypeError(format("'value' attribute missing in a call to 'listToAttrs', at %1%") % pos);
|
throw TypeError(format("‘value’ attribute missing in a call to ‘listToAttrs’, at %1%") % pos);
|
||||||
|
|
||||||
v.attrs->push_back(Attr(sym, j2->value, j2->pos));
|
v.attrs->push_back(Attr(sym, j2->value, j2->pos));
|
||||||
seen.insert(sym);
|
seen.insert(sym);
|
||||||
|
@ -1197,7 +1197,7 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0]);
|
||||||
if (args[0]->type != tLambda)
|
if (args[0]->type != tLambda)
|
||||||
throw TypeError(format("'functionArgs' requires a function, at %1%") % pos);
|
throw TypeError(format("‘functionArgs’ requires a function, at %1%") % pos);
|
||||||
|
|
||||||
if (!args[0]->lambda.fun->matchAttrs) {
|
if (!args[0]->lambda.fun->matchAttrs) {
|
||||||
state.mkAttrs(v, 0);
|
state.mkAttrs(v, 0);
|
||||||
|
@ -1256,7 +1256,7 @@ static void prim_tail(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
{
|
{
|
||||||
state.forceList(*args[0], pos);
|
state.forceList(*args[0], pos);
|
||||||
if (args[0]->listSize() == 0)
|
if (args[0]->listSize() == 0)
|
||||||
throw Error(format("'tail' called on an empty list, at %1%") % pos);
|
throw Error(format("‘tail’ called on an empty list, at %1%") % pos);
|
||||||
state.mkList(v, args[0]->listSize() - 1);
|
state.mkList(v, args[0]->listSize() - 1);
|
||||||
for (unsigned int n = 0; n < v.listSize(); ++n)
|
for (unsigned int n = 0; n < v.listSize(); ++n)
|
||||||
v.listElems()[n] = args[0]->listElems()[n + 1];
|
v.listElems()[n] = args[0]->listElems()[n + 1];
|
||||||
|
@ -1565,7 +1565,7 @@ static void prim_substring(EvalState & state, const Pos & pos, Value * * args, V
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string s = state.coerceToString(pos, *args[2], context);
|
string s = state.coerceToString(pos, *args[2], context);
|
||||||
|
|
||||||
if (start < 0) throw EvalError(format("negative start position in 'substring', at %1%") % pos);
|
if (start < 0) throw EvalError(format("negative start position in ‘substring’, at %1%") % pos);
|
||||||
|
|
||||||
mkString(v, (unsigned int) start >= s.size() ? "" : string(s, start, len), context);
|
mkString(v, (unsigned int) start >= s.size() ? "" : string(s, start, len), context);
|
||||||
}
|
}
|
||||||
|
@ -1612,7 +1612,7 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args,
|
||||||
string type = state.forceStringNoCtx(*args[0], pos);
|
string type = state.forceStringNoCtx(*args[0], pos);
|
||||||
HashType ht = parseHashType(type);
|
HashType ht = parseHashType(type);
|
||||||
if (ht == htUnknown)
|
if (ht == htUnknown)
|
||||||
throw Error(format("unknown hash type '%1%', at %2%") % type % pos);
|
throw Error(format("unknown hash type ‘%1%’, at %2%") % type % pos);
|
||||||
|
|
||||||
PathSet context; // discarded
|
PathSet context; // discarded
|
||||||
string s = state.forceString(*args[1], context, pos);
|
string s = state.forceString(*args[1], context, pos);
|
||||||
|
@ -1622,7 +1622,7 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args,
|
||||||
|
|
||||||
|
|
||||||
/* Match a regular expression against a string and return either
|
/* Match a regular expression against a string and return either
|
||||||
'null' or a list containing substring matches. */
|
‘null’ or a list containing substring matches. */
|
||||||
static void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
std::regex regex(state.forceStringNoCtx(*args[0], pos), std::regex::extended);
|
std::regex regex(state.forceStringNoCtx(*args[0], pos), std::regex::extended);
|
||||||
|
@ -1674,7 +1674,7 @@ static void prim_replaceStrings(EvalState & state, const Pos & pos, Value * * ar
|
||||||
state.forceList(*args[0], pos);
|
state.forceList(*args[0], pos);
|
||||||
state.forceList(*args[1], pos);
|
state.forceList(*args[1], pos);
|
||||||
if (args[0]->listSize() != args[1]->listSize())
|
if (args[0]->listSize() != args[1]->listSize())
|
||||||
throw EvalError(format("'from' and 'to' arguments to 'replaceStrings' have different lengths, at %1%") % pos);
|
throw EvalError(format("‘from’ and ‘to’ arguments to ‘replaceStrings’ have different lengths, at %1%") % pos);
|
||||||
|
|
||||||
vector<string> from;
|
vector<string> from;
|
||||||
from.reserve(args[0]->listSize());
|
from.reserve(args[0]->listSize());
|
||||||
|
@ -1765,17 +1765,17 @@ void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
|
||||||
else if (n == "name")
|
else if (n == "name")
|
||||||
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||||
else
|
else
|
||||||
throw EvalError(format("unsupported argument '%1%' to '%2%', at %3%") % attr.name % who % attr.pos);
|
throw EvalError(format("unsupported argument ‘%1%’ to ‘%2%’, at %3%") % attr.name % who % attr.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.empty())
|
if (url.empty())
|
||||||
throw EvalError(format("'url' argument required, at %1%") % pos);
|
throw EvalError(format("‘url’ argument required, at %1%") % pos);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
url = state.forceStringNoCtx(*args[0], pos);
|
url = state.forceStringNoCtx(*args[0], pos);
|
||||||
|
|
||||||
if (state.restricted && !expectedHash)
|
if (state.restricted && !expectedHash)
|
||||||
throw Error(format("'%1%' is not allowed in restricted mode") % who);
|
throw Error(format("‘%1%’ is not allowed in restricted mode") % who);
|
||||||
|
|
||||||
Path res = getDownloader()->downloadCached(state.store, url, unpack, name, expectedHash);
|
Path res = getDownloader()->downloadCached(state.store, url, unpack, name, expectedHash);
|
||||||
mkString(v, res, PathSet({res}));
|
mkString(v, res, PathSet({res}));
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace nix {
|
||||||
Path exportGit(ref<Store> store, const std::string & uri, const std::string & rev)
|
Path exportGit(ref<Store> store, const std::string & uri, const std::string & rev)
|
||||||
{
|
{
|
||||||
if (!isUri(uri))
|
if (!isUri(uri))
|
||||||
throw EvalError(format("'%s' is not a valid URI") % uri);
|
throw EvalError(format("‘%s’ is not a valid URI") % uri);
|
||||||
|
|
||||||
Path cacheDir = getCacheDir() + "/nix/git";
|
Path cacheDir = getCacheDir() + "/nix/git";
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ Path exportGit(ref<Store> store, const std::string & uri, const std::string & re
|
||||||
runProgram("git", true, { "init", "--bare", cacheDir });
|
runProgram("git", true, { "init", "--bare", cacheDir });
|
||||||
}
|
}
|
||||||
|
|
||||||
Activity act(*logger, lvlInfo, format("fetching Git repository '%s'") % uri);
|
Activity act(*logger, lvlInfo, format("fetching Git repository ‘%s’") % uri);
|
||||||
|
|
||||||
std::string localRef = "pid-" + std::to_string(getpid());
|
std::string localRef = "pid-" + std::to_string(getpid());
|
||||||
Path localRefFile = cacheDir + "/refs/heads/" + localRef;
|
Path localRefFile = cacheDir + "/refs/heads/" + localRef;
|
||||||
|
@ -28,7 +28,7 @@ Path exportGit(ref<Store> store, const std::string & uri, const std::string & re
|
||||||
|
|
||||||
unlink(localRefFile.c_str());
|
unlink(localRefFile.c_str());
|
||||||
|
|
||||||
debug(format("got revision '%s'") % commitHash);
|
debug(format("got revision ‘%s’") % commitHash);
|
||||||
|
|
||||||
// FIXME: should pipe this, or find some better way to extract a
|
// FIXME: should pipe this, or find some better way to extract a
|
||||||
// revision.
|
// revision.
|
||||||
|
@ -45,7 +45,7 @@ Path exportGit(ref<Store> store, const std::string & uri, const std::string & re
|
||||||
static void prim_fetchgit(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_fetchgit(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
// FIXME: cut&paste from fetch().
|
// FIXME: cut&paste from fetch().
|
||||||
if (state.restricted) throw Error("'fetchgit' is not allowed in restricted mode");
|
if (state.restricted) throw Error("‘fetchgit’ is not allowed in restricted mode");
|
||||||
|
|
||||||
std::string url;
|
std::string url;
|
||||||
std::string rev = "master";
|
std::string rev = "master";
|
||||||
|
@ -63,11 +63,11 @@ static void prim_fetchgit(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
else if (name == "rev")
|
else if (name == "rev")
|
||||||
rev = state.forceStringNoCtx(*attr.value, *attr.pos);
|
rev = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||||
else
|
else
|
||||||
throw EvalError(format("unsupported argument '%1%' to 'fetchgit', at %3%") % attr.name % attr.pos);
|
throw EvalError(format("unsupported argument ‘%1%’ to ‘fetchgit’, at %3%") % attr.name % attr.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.empty())
|
if (url.empty())
|
||||||
throw EvalError(format("'url' argument required, at %1%") % pos);
|
throw EvalError(format("‘url’ argument required, at %1%") % pos);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
url = state.forceStringNoCtx(*args[0], pos);
|
url = state.forceStringNoCtx(*args[0], pos);
|
||||||
|
|
|
@ -37,7 +37,7 @@ void printGCWarning()
|
||||||
if (!gcWarning) return;
|
if (!gcWarning) return;
|
||||||
static bool haveWarned = false;
|
static bool haveWarned = false;
|
||||||
warnOnce(haveWarned,
|
warnOnce(haveWarned,
|
||||||
"you did not specify '--add-root'; "
|
"you did not specify ‘--add-root’; "
|
||||||
"the result might be removed by the garbage collector");
|
"the result might be removed by the garbage collector");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ string getArg(const string & opt,
|
||||||
Strings::iterator & i, const Strings::iterator & end)
|
Strings::iterator & i, const Strings::iterator & end)
|
||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
if (i == end) throw UsageError(format("'%1%' requires an argument") % opt);
|
if (i == end) throw UsageError(format("‘%1%’ requires an argument") % opt);
|
||||||
return *i;
|
return *i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ struct LegacyArgs : public MixCommonArgs
|
||||||
mkFlag(0, "show-trace", "show Nix expression stack trace in evaluation errors",
|
mkFlag(0, "show-trace", "show Nix expression stack trace in evaluation errors",
|
||||||
&settings.showTrace);
|
&settings.showTrace);
|
||||||
|
|
||||||
mkFlag(0, "no-gc-warning", "disable warning about not using '--add-root'",
|
mkFlag(0, "no-gc-warning", "disable warning about not using ‘--add-root’",
|
||||||
&gcWarning, false);
|
&gcWarning, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ struct LegacyArgs : public MixCommonArgs
|
||||||
Strings ss(args);
|
Strings ss(args);
|
||||||
auto pos = ss.begin();
|
auto pos = ss.begin();
|
||||||
if (!parseArg(pos, ss.end()))
|
if (!parseArg(pos, ss.end()))
|
||||||
throw UsageError(format("unexpected argument '%1%'") % args.front());
|
throw UsageError(format("unexpected argument ‘%1%’") % args.front());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -261,7 +261,7 @@ void showManPage(const string & name)
|
||||||
{
|
{
|
||||||
restoreSIGPIPE();
|
restoreSIGPIPE();
|
||||||
execlp("man", "man", name.c_str(), NULL);
|
execlp("man", "man", name.c_str(), NULL);
|
||||||
throw SysError(format("command 'man %1%' failed") % name.c_str());
|
throw SysError(format("command ‘man %1%’ failed") % name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -283,13 +283,13 @@ int handleExceptions(const string & programName, std::function<void()> fun)
|
||||||
return e.status;
|
return e.status;
|
||||||
} catch (UsageError & e) {
|
} catch (UsageError & e) {
|
||||||
printError(
|
printError(
|
||||||
format(error + "%1%\nTry '%2% --help' for more information.")
|
format(error + "%1%\nTry ‘%2% --help’ for more information.")
|
||||||
% e.what() % programName);
|
% e.what() % programName);
|
||||||
return 1;
|
return 1;
|
||||||
} catch (BaseError & e) {
|
} catch (BaseError & e) {
|
||||||
printError(format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg());
|
printError(format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg());
|
||||||
if (e.prefix() != "" && !settings.showTrace)
|
if (e.prefix() != "" && !settings.showTrace)
|
||||||
printError("(use '--show-trace' to show detailed location information)");
|
printError("(use ‘--show-trace’ to show detailed location information)");
|
||||||
return e.status;
|
return e.status;
|
||||||
} catch (std::bad_alloc & e) {
|
} catch (std::bad_alloc & e) {
|
||||||
printError(error + "out of memory");
|
printError(error + "out of memory");
|
||||||
|
@ -333,7 +333,7 @@ RunPager::RunPager()
|
||||||
execlp("pager", "pager", NULL);
|
execlp("pager", "pager", NULL);
|
||||||
execlp("less", "less", NULL);
|
execlp("less", "less", NULL);
|
||||||
execlp("more", "more", NULL);
|
execlp("more", "more", NULL);
|
||||||
throw SysError(format("executing '%1%'") % pager);
|
throw SysError(format("executing ‘%1%’") % pager);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (dup2(toPager.writeSide.get(), STDOUT_FILENO) == -1)
|
if (dup2(toPager.writeSide.get(), STDOUT_FILENO) == -1)
|
||||||
|
|
|
@ -45,7 +45,7 @@ template<class N> N getIntArg(const string & opt,
|
||||||
Strings::iterator & i, const Strings::iterator & end, bool allowUnit)
|
Strings::iterator & i, const Strings::iterator & end, bool allowUnit)
|
||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
if (i == end) throw UsageError(format("'%1%' requires an argument") % opt);
|
if (i == end) throw UsageError(format("‘%1%’ requires an argument") % opt);
|
||||||
string s = *i;
|
string s = *i;
|
||||||
N multiplier = 1;
|
N multiplier = 1;
|
||||||
if (allowUnit && !s.empty()) {
|
if (allowUnit && !s.empty()) {
|
||||||
|
@ -55,13 +55,13 @@ template<class N> N getIntArg(const string & opt,
|
||||||
else if (u == 'M') multiplier = 1ULL << 20;
|
else if (u == 'M') multiplier = 1ULL << 20;
|
||||||
else if (u == 'G') multiplier = 1ULL << 30;
|
else if (u == 'G') multiplier = 1ULL << 30;
|
||||||
else if (u == 'T') multiplier = 1ULL << 40;
|
else if (u == 'T') multiplier = 1ULL << 40;
|
||||||
else throw UsageError(format("invalid unit specifier '%1%'") % u);
|
else throw UsageError(format("invalid unit specifier ‘%1%’") % u);
|
||||||
s.resize(s.size() - 1);
|
s.resize(s.size() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
N n;
|
N n;
|
||||||
if (!string2Int(s, n))
|
if (!string2Int(s, n))
|
||||||
throw UsageError(format("'%1%' requires an integer argument") % opt);
|
throw UsageError(format("‘%1%’ requires an integer argument") % opt);
|
||||||
return n * multiplier;
|
return n * multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ struct BinaryCacheStoreAccessor : public FSAccessor
|
||||||
std::string restPath = std::string(path, storePath.size());
|
std::string restPath = std::string(path, storePath.size());
|
||||||
|
|
||||||
if (!store->isValidPath(storePath))
|
if (!store->isValidPath(storePath))
|
||||||
throw InvalidPath(format("path '%1%' is not a valid store path") % storePath);
|
throw InvalidPath(format("path ‘%1%’ is not a valid store path") % storePath);
|
||||||
|
|
||||||
auto i = nars.find(storePath);
|
auto i = nars.find(storePath);
|
||||||
if (i != nars.end()) return {i->second, restPath};
|
if (i != nars.end()) return {i->second, restPath};
|
||||||
|
@ -106,7 +106,7 @@ void BinaryCacheStore::init()
|
||||||
auto value = trim(line.substr(colon + 1, std::string::npos));
|
auto value = trim(line.substr(colon + 1, std::string::npos));
|
||||||
if (name == "StoreDir") {
|
if (name == "StoreDir") {
|
||||||
if (value != storeDir)
|
if (value != storeDir)
|
||||||
throw Error(format("binary cache '%s' is for Nix stores with prefix '%s', not '%s'")
|
throw Error(format("binary cache ‘%s’ is for Nix stores with prefix ‘%s’, not ‘%s’")
|
||||||
% getUri() % value % storeDir);
|
% getUri() % value % storeDir);
|
||||||
} else if (name == "WantMassQuery") {
|
} else if (name == "WantMassQuery") {
|
||||||
wantMassQuery_ = value == "1";
|
wantMassQuery_ = value == "1";
|
||||||
|
@ -153,7 +153,7 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str
|
||||||
if (ref != info.path)
|
if (ref != info.path)
|
||||||
queryPathInfo(ref);
|
queryPathInfo(ref);
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
throw Error(format("cannot add '%s' to the binary cache because the reference '%s' is not valid")
|
throw Error(format("cannot add ‘%s’ to the binary cache because the reference ‘%s’ is not valid")
|
||||||
% info.path % ref);
|
% info.path % ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str
|
||||||
narInfo->narHash = hashString(htSHA256, *nar);
|
narInfo->narHash = hashString(htSHA256, *nar);
|
||||||
|
|
||||||
if (info.narHash && info.narHash != narInfo->narHash)
|
if (info.narHash && info.narHash != narInfo->narHash)
|
||||||
throw Error(format("refusing to copy corrupted path '%1%' to binary cache") % info.path);
|
throw Error(format("refusing to copy corrupted path ‘%1%’ to binary cache") % info.path);
|
||||||
|
|
||||||
auto accessor_ = std::dynamic_pointer_cast<BinaryCacheStoreAccessor>(accessor);
|
auto accessor_ = std::dynamic_pointer_cast<BinaryCacheStoreAccessor>(accessor);
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str
|
||||||
narInfo->fileSize = narCompressed->size();
|
narInfo->fileSize = narCompressed->size();
|
||||||
|
|
||||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now2 - now1).count();
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now2 - now1).count();
|
||||||
printMsg(lvlTalkative, format("copying path '%1%' (%2% bytes, compressed %3$.1f%% in %4% ms) to binary cache")
|
printMsg(lvlTalkative, format("copying path ‘%1%’ (%2% bytes, compressed %3$.1f%% in %4% ms) to binary cache")
|
||||||
% narInfo->path % narInfo->narSize
|
% narInfo->path % narInfo->narSize
|
||||||
% ((1.0 - (double) narCompressed->size() / nar->size()) * 100.0)
|
% ((1.0 - (double) narCompressed->size() / nar->size()) * 100.0)
|
||||||
% duration);
|
% duration);
|
||||||
|
@ -282,7 +282,7 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str
|
||||||
bool BinaryCacheStore::isValidPathUncached(const Path & storePath)
|
bool BinaryCacheStore::isValidPathUncached(const Path & storePath)
|
||||||
{
|
{
|
||||||
// FIXME: this only checks whether a .narinfo with a matching hash
|
// FIXME: this only checks whether a .narinfo with a matching hash
|
||||||
// part exists. So 'f4kb...-foo' matches 'f4kb...-bar', even
|
// part exists. So ‘f4kb...-foo’ matches ‘f4kb...-bar’, even
|
||||||
// though they shouldn't. Not easily fixed.
|
// though they shouldn't. Not easily fixed.
|
||||||
return fileExists(narInfoFileFor(storePath));
|
return fileExists(narInfoFileFor(storePath));
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ void BinaryCacheStore::narFromPath(const Path & storePath, Sink & sink)
|
||||||
|
|
||||||
auto nar = getFile(info->url);
|
auto nar = getFile(info->url);
|
||||||
|
|
||||||
if (!nar) throw Error(format("file '%s' missing from binary cache") % info->url);
|
if (!nar) throw Error(format("file ‘%s’ missing from binary cache") % info->url);
|
||||||
|
|
||||||
stats.narRead++;
|
stats.narRead++;
|
||||||
stats.narReadCompressedBytes += nar->size();
|
stats.narReadCompressedBytes += nar->size();
|
||||||
|
@ -303,13 +303,13 @@ void BinaryCacheStore::narFromPath(const Path & storePath, Sink & sink)
|
||||||
try {
|
try {
|
||||||
nar = decompress(info->compression, *nar);
|
nar = decompress(info->compression, *nar);
|
||||||
} catch (UnknownCompressionMethod &) {
|
} catch (UnknownCompressionMethod &) {
|
||||||
throw Error(format("binary cache path '%s' uses unknown compression method '%s'")
|
throw Error(format("binary cache path ‘%s’ uses unknown compression method ‘%s’")
|
||||||
% storePath % info->compression);
|
% storePath % info->compression);
|
||||||
}
|
}
|
||||||
|
|
||||||
stats.narReadBytes += nar->size();
|
stats.narReadBytes += nar->size();
|
||||||
|
|
||||||
printMsg(lvlTalkative, format("exporting path '%1%' (%2% bytes)") % storePath % nar->size());
|
printMsg(lvlTalkative, format("exporting path ‘%1%’ (%2% bytes)") % storePath % nar->size());
|
||||||
|
|
||||||
assert(nar->size() % 8 == 0);
|
assert(nar->size() % 8 == 0);
|
||||||
|
|
||||||
|
|
|
@ -342,7 +342,7 @@ void Goal::waiteeDone(GoalPtr waitee, ExitCode result)
|
||||||
assert(waitees.find(waitee) != waitees.end());
|
assert(waitees.find(waitee) != waitees.end());
|
||||||
waitees.erase(waitee);
|
waitees.erase(waitee);
|
||||||
|
|
||||||
trace(format("waitee '%1%' done; %2% left") %
|
trace(format("waitee ‘%1%’ done; %2% left") %
|
||||||
waitee->name % waitees.size());
|
waitee->name % waitees.size());
|
||||||
|
|
||||||
if (result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure) ++nrFailed;
|
if (result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure) ++nrFailed;
|
||||||
|
@ -414,7 +414,7 @@ static void commonChildInit(Pipe & logPipe)
|
||||||
/* Reroute stdin to /dev/null. */
|
/* Reroute stdin to /dev/null. */
|
||||||
int fdDevNull = open(pathNullDevice.c_str(), O_RDWR);
|
int fdDevNull = open(pathNullDevice.c_str(), O_RDWR);
|
||||||
if (fdDevNull == -1)
|
if (fdDevNull == -1)
|
||||||
throw SysError(format("cannot open '%1%'") % pathNullDevice);
|
throw SysError(format("cannot open ‘%1%’") % pathNullDevice);
|
||||||
if (dup2(fdDevNull, STDIN_FILENO) == -1)
|
if (dup2(fdDevNull, STDIN_FILENO) == -1)
|
||||||
throw SysError("cannot dup null device into stdin");
|
throw SysError("cannot dup null device into stdin");
|
||||||
close(fdDevNull);
|
close(fdDevNull);
|
||||||
|
@ -477,29 +477,29 @@ void UserLock::acquire()
|
||||||
/* Get the members of the build-users-group. */
|
/* Get the members of the build-users-group. */
|
||||||
struct group * gr = getgrnam(settings.buildUsersGroup.c_str());
|
struct group * gr = getgrnam(settings.buildUsersGroup.c_str());
|
||||||
if (!gr)
|
if (!gr)
|
||||||
throw Error(format("the group '%1%' specified in 'build-users-group' does not exist")
|
throw Error(format("the group ‘%1%’ specified in ‘build-users-group’ does not exist")
|
||||||
% settings.buildUsersGroup);
|
% settings.buildUsersGroup);
|
||||||
gid = gr->gr_gid;
|
gid = gr->gr_gid;
|
||||||
|
|
||||||
/* Copy the result of getgrnam. */
|
/* Copy the result of getgrnam. */
|
||||||
Strings users;
|
Strings users;
|
||||||
for (char * * p = gr->gr_mem; *p; ++p) {
|
for (char * * p = gr->gr_mem; *p; ++p) {
|
||||||
debug(format("found build user '%1%'") % *p);
|
debug(format("found build user ‘%1%’") % *p);
|
||||||
users.push_back(*p);
|
users.push_back(*p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (users.empty())
|
if (users.empty())
|
||||||
throw Error(format("the build users group '%1%' has no members")
|
throw Error(format("the build users group ‘%1%’ has no members")
|
||||||
% settings.buildUsersGroup);
|
% settings.buildUsersGroup);
|
||||||
|
|
||||||
/* Find a user account that isn't currently in use for another
|
/* Find a user account that isn't currently in use for another
|
||||||
build. */
|
build. */
|
||||||
for (auto & i : users) {
|
for (auto & i : users) {
|
||||||
debug(format("trying user '%1%'") % i);
|
debug(format("trying user ‘%1%’") % i);
|
||||||
|
|
||||||
struct passwd * pw = getpwnam(i.c_str());
|
struct passwd * pw = getpwnam(i.c_str());
|
||||||
if (!pw)
|
if (!pw)
|
||||||
throw Error(format("the user '%1%' in the group '%2%' does not exist")
|
throw Error(format("the user ‘%1%’ in the group ‘%2%’ does not exist")
|
||||||
% i % settings.buildUsersGroup);
|
% i % settings.buildUsersGroup);
|
||||||
|
|
||||||
createDirs(settings.nixStateDir + "/userpool");
|
createDirs(settings.nixStateDir + "/userpool");
|
||||||
|
@ -512,7 +512,7 @@ void UserLock::acquire()
|
||||||
|
|
||||||
AutoCloseFD fd = open(fnUserLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
|
AutoCloseFD fd = open(fnUserLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
|
||||||
if (!fd)
|
if (!fd)
|
||||||
throw SysError(format("opening user lock '%1%'") % fnUserLock);
|
throw SysError(format("opening user lock ‘%1%’") % fnUserLock);
|
||||||
|
|
||||||
if (lockFile(fd.get(), ltWrite, false)) {
|
if (lockFile(fd.get(), ltWrite, false)) {
|
||||||
fdUserLock = std::move(fd);
|
fdUserLock = std::move(fd);
|
||||||
|
@ -522,7 +522,7 @@ void UserLock::acquire()
|
||||||
|
|
||||||
/* Sanity check... */
|
/* Sanity check... */
|
||||||
if (uid == getuid() || uid == geteuid())
|
if (uid == getuid() || uid == geteuid())
|
||||||
throw Error(format("the Nix user should not be a member of '%1%'")
|
throw Error(format("the Nix user should not be a member of ‘%1%’")
|
||||||
% settings.buildUsersGroup);
|
% settings.buildUsersGroup);
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
|
@ -533,7 +533,7 @@ void UserLock::acquire()
|
||||||
int err = getgrouplist(pw->pw_name, pw->pw_gid,
|
int err = getgrouplist(pw->pw_name, pw->pw_gid,
|
||||||
supplementaryGIDs.data(), &ngroups);
|
supplementaryGIDs.data(), &ngroups);
|
||||||
if (err == -1)
|
if (err == -1)
|
||||||
throw Error(format("failed to get list of supplementary groups for '%1%'") % pw->pw_name);
|
throw Error(format("failed to get list of supplementary groups for ‘%1%’") % pw->pw_name);
|
||||||
|
|
||||||
supplementaryGIDs.resize(ngroups);
|
supplementaryGIDs.resize(ngroups);
|
||||||
#endif
|
#endif
|
||||||
|
@ -543,7 +543,7 @@ void UserLock::acquire()
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Error(format("all build users are currently in use; "
|
throw Error(format("all build users are currently in use; "
|
||||||
"consider creating additional users and adding them to the '%1%' group")
|
"consider creating additional users and adding them to the ‘%1%’ group")
|
||||||
% settings.buildUsersGroup);
|
% settings.buildUsersGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,7 +630,7 @@ HookInstance::HookInstance()
|
||||||
|
|
||||||
execv(buildHook.c_str(), stringsToCharPtrs(args).data());
|
execv(buildHook.c_str(), stringsToCharPtrs(args).data());
|
||||||
|
|
||||||
throw SysError(format("executing '%1%'") % buildHook);
|
throw SysError(format("executing ‘%1%’") % buildHook);
|
||||||
});
|
});
|
||||||
|
|
||||||
pid.setSeparatePG(true);
|
pid.setSeparatePG(true);
|
||||||
|
@ -910,7 +910,7 @@ DerivationGoal::DerivationGoal(const Path & drvPath, const StringSet & wantedOut
|
||||||
, buildMode(buildMode)
|
, buildMode(buildMode)
|
||||||
{
|
{
|
||||||
state = &DerivationGoal::getDerivation;
|
state = &DerivationGoal::getDerivation;
|
||||||
name = (format("building of '%1%'") % drvPath).str();
|
name = (format("building of ‘%1%’") % drvPath).str();
|
||||||
trace("created");
|
trace("created");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1021,7 +1021,7 @@ void DerivationGoal::loadDerivation()
|
||||||
trace("loading derivation");
|
trace("loading derivation");
|
||||||
|
|
||||||
if (nrFailed != 0) {
|
if (nrFailed != 0) {
|
||||||
printError(format("cannot build missing derivation '%1%'") % drvPath);
|
printError(format("cannot build missing derivation ‘%1%’") % drvPath);
|
||||||
done(BuildResult::MiscFailure);
|
done(BuildResult::MiscFailure);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1062,7 +1062,7 @@ void DerivationGoal::haveDerivation()
|
||||||
if (drv->outputs.size() != 1 ||
|
if (drv->outputs.size() != 1 ||
|
||||||
drv->outputs.find("out") == drv->outputs.end() ||
|
drv->outputs.find("out") == drv->outputs.end() ||
|
||||||
drv->outputs["out"].hashAlgo == "")
|
drv->outputs["out"].hashAlgo == "")
|
||||||
throw Error(format("cannot do a hash build of non-fixed-output derivation '%1%'") % drvPath);
|
throw Error(format("cannot do a hash build of non-fixed-output derivation ‘%1%’") % drvPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We are first going to try to create the invalid output paths
|
/* We are first going to try to create the invalid output paths
|
||||||
|
@ -1084,7 +1084,7 @@ void DerivationGoal::outputsSubstituted()
|
||||||
trace("all outputs substituted (maybe)");
|
trace("all outputs substituted (maybe)");
|
||||||
|
|
||||||
if (nrFailed > 0 && nrFailed > nrNoSubstituters + nrIncompleteClosure && !settings.tryFallback) {
|
if (nrFailed > 0 && nrFailed > nrNoSubstituters + nrIncompleteClosure && !settings.tryFallback) {
|
||||||
done(BuildResult::TransientFailure, (format("some substitutes for the outputs of derivation '%1%' failed (usually happens due to networking issues); try '--fallback' to build derivation from source ") % drvPath).str());
|
done(BuildResult::TransientFailure, (format("some substitutes for the outputs of derivation ‘%1%’ failed (usually happens due to networking issues); try ‘--fallback’ to build derivation from source ") % drvPath).str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1111,7 +1111,7 @@ void DerivationGoal::outputsSubstituted()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (buildMode == bmCheck && nrInvalid > 0)
|
if (buildMode == bmCheck && nrInvalid > 0)
|
||||||
throw Error(format("some outputs of '%1%' are not valid, so checking is not possible") % drvPath);
|
throw Error(format("some outputs of ‘%1%’ are not valid, so checking is not possible") % drvPath);
|
||||||
|
|
||||||
/* Otherwise, at least one of the output paths could not be
|
/* Otherwise, at least one of the output paths could not be
|
||||||
produced using a substitute. So we have to build instead. */
|
produced using a substitute. So we have to build instead. */
|
||||||
|
@ -1128,7 +1128,7 @@ void DerivationGoal::outputsSubstituted()
|
||||||
for (auto & i : drv->inputSrcs) {
|
for (auto & i : drv->inputSrcs) {
|
||||||
if (worker.store.isValidPath(i)) continue;
|
if (worker.store.isValidPath(i)) continue;
|
||||||
if (!settings.useSubstitutes)
|
if (!settings.useSubstitutes)
|
||||||
throw Error(format("dependency of '%1%' of '%2%' does not exist, and substitution is disabled")
|
throw Error(format("dependency of ‘%1%’ of ‘%2%’ does not exist, and substitution is disabled")
|
||||||
% i % drvPath);
|
% i % drvPath);
|
||||||
addWaitee(worker.makeSubstitutionGoal(i));
|
addWaitee(worker.makeSubstitutionGoal(i));
|
||||||
}
|
}
|
||||||
|
@ -1175,7 +1175,7 @@ void DerivationGoal::repairClosure()
|
||||||
PathSet broken;
|
PathSet broken;
|
||||||
for (auto & i : outputClosure) {
|
for (auto & i : outputClosure) {
|
||||||
if (worker.pathContentsGood(i)) continue;
|
if (worker.pathContentsGood(i)) continue;
|
||||||
printError(format("found corrupted or missing path '%1%' in the output closure of '%2%'") % i % drvPath);
|
printError(format("found corrupted or missing path ‘%1%’ in the output closure of ‘%2%’") % i % drvPath);
|
||||||
Path drvPath2 = outputsToDrv[i];
|
Path drvPath2 = outputsToDrv[i];
|
||||||
if (drvPath2 == "")
|
if (drvPath2 == "")
|
||||||
addWaitee(worker.makeSubstitutionGoal(i, true));
|
addWaitee(worker.makeSubstitutionGoal(i, true));
|
||||||
|
@ -1196,7 +1196,7 @@ void DerivationGoal::closureRepaired()
|
||||||
{
|
{
|
||||||
trace("closure repaired");
|
trace("closure repaired");
|
||||||
if (nrFailed > 0)
|
if (nrFailed > 0)
|
||||||
throw Error(format("some paths in the output closure of derivation '%1%' could not be repaired") % drvPath);
|
throw Error(format("some paths in the output closure of derivation ‘%1%’ could not be repaired") % drvPath);
|
||||||
done(BuildResult::AlreadyValid);
|
done(BuildResult::AlreadyValid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1207,9 +1207,9 @@ void DerivationGoal::inputsRealised()
|
||||||
|
|
||||||
if (nrFailed != 0) {
|
if (nrFailed != 0) {
|
||||||
if (!useDerivation)
|
if (!useDerivation)
|
||||||
throw Error(format("some dependencies of '%1%' are missing") % drvPath);
|
throw Error(format("some dependencies of ‘%1%’ are missing") % drvPath);
|
||||||
printError(
|
printError(
|
||||||
format("cannot build derivation '%1%': %2% dependencies couldn't be built")
|
format("cannot build derivation ‘%1%’: %2% dependencies couldn't be built")
|
||||||
% drvPath % nrFailed);
|
% drvPath % nrFailed);
|
||||||
done(BuildResult::DependencyFailed);
|
done(BuildResult::DependencyFailed);
|
||||||
return;
|
return;
|
||||||
|
@ -1225,7 +1225,7 @@ void DerivationGoal::inputsRealised()
|
||||||
|
|
||||||
/* The outputs are referenceable paths. */
|
/* The outputs are referenceable paths. */
|
||||||
for (auto & i : drv->outputs) {
|
for (auto & i : drv->outputs) {
|
||||||
debug(format("building path '%1%'") % i.second.path);
|
debug(format("building path ‘%1%’") % i.second.path);
|
||||||
allPaths.insert(i.second.path);
|
allPaths.insert(i.second.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1244,7 +1244,7 @@ void DerivationGoal::inputsRealised()
|
||||||
worker.store.computeFSClosure(inDrv.outputs[j].path, inputPaths);
|
worker.store.computeFSClosure(inDrv.outputs[j].path, inputPaths);
|
||||||
else
|
else
|
||||||
throw Error(
|
throw Error(
|
||||||
format("derivation '%1%' requires non-existent output '%2%' from input derivation '%3%'")
|
format("derivation ‘%1%’ requires non-existent output ‘%2%’ from input derivation ‘%3%’")
|
||||||
% drvPath % j % i.first);
|
% drvPath % j % i.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1283,7 +1283,7 @@ void DerivationGoal::tryToBuild()
|
||||||
goal to sleep until another goal finishes, then try again. */
|
goal to sleep until another goal finishes, then try again. */
|
||||||
for (auto & i : drv->outputs)
|
for (auto & i : drv->outputs)
|
||||||
if (pathIsLockedByMe(worker.store.toRealPath(i.second.path))) {
|
if (pathIsLockedByMe(worker.store.toRealPath(i.second.path))) {
|
||||||
debug(format("putting derivation '%1%' to sleep because '%2%' is locked by another goal")
|
debug(format("putting derivation ‘%1%’ to sleep because ‘%2%’ is locked by another goal")
|
||||||
% drvPath % i.second.path);
|
% drvPath % i.second.path);
|
||||||
worker.waitForAnyGoal(shared_from_this());
|
worker.waitForAnyGoal(shared_from_this());
|
||||||
return;
|
return;
|
||||||
|
@ -1312,7 +1312,7 @@ void DerivationGoal::tryToBuild()
|
||||||
build this derivation, so no further checks are necessary. */
|
build this derivation, so no further checks are necessary. */
|
||||||
validPaths = checkPathValidity(true, buildMode == bmRepair);
|
validPaths = checkPathValidity(true, buildMode == bmRepair);
|
||||||
if (buildMode != bmCheck && validPaths.size() == drv->outputs.size()) {
|
if (buildMode != bmCheck && validPaths.size() == drv->outputs.size()) {
|
||||||
debug(format("skipping build of derivation '%1%', someone beat us to it") % drvPath);
|
debug(format("skipping build of derivation ‘%1%’, someone beat us to it") % drvPath);
|
||||||
outputLocks.setDeletion(true);
|
outputLocks.setDeletion(true);
|
||||||
done(BuildResult::AlreadyValid);
|
done(BuildResult::AlreadyValid);
|
||||||
return;
|
return;
|
||||||
|
@ -1327,7 +1327,7 @@ void DerivationGoal::tryToBuild()
|
||||||
for (auto & i : drv->outputs) {
|
for (auto & i : drv->outputs) {
|
||||||
Path path = i.second.path;
|
Path path = i.second.path;
|
||||||
if (worker.store.isValidPath(path)) continue;
|
if (worker.store.isValidPath(path)) continue;
|
||||||
debug(format("removing invalid path '%1%'") % path);
|
debug(format("removing invalid path ‘%1%’") % path);
|
||||||
deletePath(worker.store.toRealPath(path));
|
deletePath(worker.store.toRealPath(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1396,7 +1396,7 @@ void replaceValidPath(const Path & storePath, const Path tmpPath)
|
||||||
if (pathExists(storePath))
|
if (pathExists(storePath))
|
||||||
rename(storePath.c_str(), oldPath.c_str());
|
rename(storePath.c_str(), oldPath.c_str());
|
||||||
if (rename(tmpPath.c_str(), storePath.c_str()) == -1)
|
if (rename(tmpPath.c_str(), storePath.c_str()) == -1)
|
||||||
throw SysError(format("moving '%1%' to '%2%'") % tmpPath % storePath);
|
throw SysError(format("moving ‘%1%’ to ‘%2%’") % tmpPath % storePath);
|
||||||
deletePath(oldPath);
|
deletePath(oldPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1416,7 +1416,7 @@ void DerivationGoal::buildDone()
|
||||||
child */
|
child */
|
||||||
int status = hook ? hook->pid.wait(true) : pid.wait(true);
|
int status = hook ? hook->pid.wait(true) : pid.wait(true);
|
||||||
|
|
||||||
debug(format("builder process for '%1%' finished") % drvPath);
|
debug(format("builder process for ‘%1%’ finished") % drvPath);
|
||||||
|
|
||||||
/* So the child is gone now. */
|
/* So the child is gone now. */
|
||||||
worker.childTerminated(this);
|
worker.childTerminated(this);
|
||||||
|
@ -1470,7 +1470,7 @@ void DerivationGoal::buildDone()
|
||||||
if (pathExists(chrootRootDir + i))
|
if (pathExists(chrootRootDir + i))
|
||||||
rename((chrootRootDir + i).c_str(), i.c_str());
|
rename((chrootRootDir + i).c_str(), i.c_str());
|
||||||
|
|
||||||
std::string msg = (format("builder for '%1%' %2%")
|
std::string msg = (format("builder for ‘%1%’ %2%")
|
||||||
% drvPath % statusToString(status)).str();
|
% drvPath % statusToString(status)).str();
|
||||||
|
|
||||||
if (!settings.verboseBuild && !logTail.empty()) {
|
if (!settings.verboseBuild && !logTail.empty()) {
|
||||||
|
@ -1583,12 +1583,12 @@ HookReply DerivationGoal::tryBuildHook()
|
||||||
writeToStderr(s);
|
writeToStderr(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(format("hook reply is '%1%'") % reply);
|
debug(format("hook reply is ‘%1%’") % reply);
|
||||||
|
|
||||||
if (reply == "decline" || reply == "postpone")
|
if (reply == "decline" || reply == "postpone")
|
||||||
return reply == "decline" ? rpDecline : rpPostpone;
|
return reply == "decline" ? rpDecline : rpPostpone;
|
||||||
else if (reply != "accept")
|
else if (reply != "accept")
|
||||||
throw Error(format("bad hook reply '%1%'") % reply);
|
throw Error(format("bad hook reply ‘%1%’") % reply);
|
||||||
|
|
||||||
printMsg(lvlTalkative, format("using hook to build path(s) %1%") % showPaths(missingPaths));
|
printMsg(lvlTalkative, format("using hook to build path(s) %1%") % showPaths(missingPaths));
|
||||||
|
|
||||||
|
@ -1631,7 +1631,7 @@ HookReply DerivationGoal::tryBuildHook()
|
||||||
void chmod_(const Path & path, mode_t mode)
|
void chmod_(const Path & path, mode_t mode)
|
||||||
{
|
{
|
||||||
if (chmod(path.c_str(), mode) == -1)
|
if (chmod(path.c_str(), mode) == -1)
|
||||||
throw SysError(format("setting permissions on '%1%'") % path);
|
throw SysError(format("setting permissions on ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1655,7 +1655,7 @@ void DerivationGoal::startBuilder()
|
||||||
/* Right platform? */
|
/* Right platform? */
|
||||||
if (!drv->canBuildLocally()) {
|
if (!drv->canBuildLocally()) {
|
||||||
throw Error(
|
throw Error(
|
||||||
format("a '%1%' is required to build '%3%', but I am a '%2%'")
|
format("a ‘%1%’ is required to build ‘%3%’, but I am a ‘%2%’")
|
||||||
% drv->platform % settings.thisSystem % drvPath);
|
% drv->platform % settings.thisSystem % drvPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1673,15 +1673,15 @@ void DerivationGoal::startBuilder()
|
||||||
/* deprecated alias */
|
/* deprecated alias */
|
||||||
settings.get("build-use-chroot", string("false")));
|
settings.get("build-use-chroot", string("false")));
|
||||||
if (x != "true" && x != "false" && x != "relaxed")
|
if (x != "true" && x != "false" && x != "relaxed")
|
||||||
throw Error("option 'build-use-sandbox' must be set to one of 'true', 'false' or 'relaxed'");
|
throw Error("option ‘build-use-sandbox’ must be set to one of ‘true’, ‘false’ or ‘relaxed’");
|
||||||
if (x == "true") {
|
if (x == "true") {
|
||||||
if (get(drv->env, "__noChroot") == "1")
|
if (get(drv->env, "__noChroot") == "1")
|
||||||
throw Error(format("derivation '%1%' has '__noChroot' set, "
|
throw Error(format("derivation ‘%1%’ has ‘__noChroot’ set, "
|
||||||
"but that's not allowed when 'build-use-sandbox' is 'true'") % drvPath);
|
"but that's not allowed when ‘build-use-sandbox’ is ‘true’") % drvPath);
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
if (additionalSandboxProfile != "")
|
if (additionalSandboxProfile != "")
|
||||||
throw Error(format("derivation '%1%' specifies a sandbox profile, "
|
throw Error(format("derivation ‘%1%’ specifies a sandbox profile, "
|
||||||
"but this is only allowed when 'build-use-sandbox' is 'relaxed'") % drvPath);
|
"but this is only allowed when ‘build-use-sandbox’ is ‘relaxed’") % drvPath);
|
||||||
#endif
|
#endif
|
||||||
useChroot = true;
|
useChroot = true;
|
||||||
}
|
}
|
||||||
|
@ -1795,7 +1795,7 @@ void DerivationGoal::startBuilder()
|
||||||
string s = get(drv->env, "exportReferencesGraph");
|
string s = get(drv->env, "exportReferencesGraph");
|
||||||
Strings ss = tokenizeString<Strings>(s);
|
Strings ss = tokenizeString<Strings>(s);
|
||||||
if (ss.size() % 2 != 0)
|
if (ss.size() % 2 != 0)
|
||||||
throw BuildError(format("odd number of tokens in 'exportReferencesGraph': '%1%'") % s);
|
throw BuildError(format("odd number of tokens in ‘exportReferencesGraph’: ‘%1%’") % s);
|
||||||
for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
|
for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
|
||||||
string fileName = *i++;
|
string fileName = *i++;
|
||||||
checkStoreName(fileName); /* !!! abuse of this function */
|
checkStoreName(fileName); /* !!! abuse of this function */
|
||||||
|
@ -1803,11 +1803,11 @@ void DerivationGoal::startBuilder()
|
||||||
/* Check that the store path is valid. */
|
/* Check that the store path is valid. */
|
||||||
Path storePath = *i++;
|
Path storePath = *i++;
|
||||||
if (!worker.store.isInStore(storePath))
|
if (!worker.store.isInStore(storePath))
|
||||||
throw BuildError(format("'exportReferencesGraph' contains a non-store path '%1%'")
|
throw BuildError(format("‘exportReferencesGraph’ contains a non-store path ‘%1%’")
|
||||||
% storePath);
|
% storePath);
|
||||||
storePath = worker.store.toStorePath(storePath);
|
storePath = worker.store.toStorePath(storePath);
|
||||||
if (!worker.store.isValidPath(storePath))
|
if (!worker.store.isValidPath(storePath))
|
||||||
throw BuildError(format("'exportReferencesGraph' contains an invalid path '%1%'")
|
throw BuildError(format("‘exportReferencesGraph’ contains an invalid path ‘%1%’")
|
||||||
% storePath);
|
% storePath);
|
||||||
|
|
||||||
/* If there are derivations in the graph, then include their
|
/* If there are derivations in the graph, then include their
|
||||||
|
@ -1846,7 +1846,7 @@ void DerivationGoal::startBuilder()
|
||||||
|
|
||||||
for (auto & p : filesToChown)
|
for (auto & p : filesToChown)
|
||||||
if (chown(p.c_str(), buildUser.getUID(), buildUser.getGID()) == -1)
|
if (chown(p.c_str(), buildUser.getUID(), buildUser.getGID()) == -1)
|
||||||
throw SysError(format("cannot change ownership of '%1%'") % p);
|
throw SysError(format("cannot change ownership of ‘%1%’") % p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1893,7 +1893,7 @@ void DerivationGoal::startBuilder()
|
||||||
if (worker.store.isInStore(i.second.source))
|
if (worker.store.isInStore(i.second.source))
|
||||||
worker.store.computeFSClosure(worker.store.toStorePath(i.second.source), closure);
|
worker.store.computeFSClosure(worker.store.toStorePath(i.second.source), closure);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
throw Error(format("while processing 'build-sandbox-paths': %s") % e.what());
|
throw Error(format("while processing ‘build-sandbox-paths’: %s") % e.what());
|
||||||
}
|
}
|
||||||
for (auto & i : closure)
|
for (auto & i : closure)
|
||||||
dirsInChroot[i] = i;
|
dirsInChroot[i] = i;
|
||||||
|
@ -1919,7 +1919,7 @@ void DerivationGoal::startBuilder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found)
|
if (!found)
|
||||||
throw Error(format("derivation '%1%' requested impure path '%2%', but it was not in allowed-impure-host-deps ('%3%')") % drvPath % i % allowed);
|
throw Error(format("derivation ‘%1%’ requested impure path ‘%2%’, but it was not in allowed-impure-host-deps (‘%3%’)") % drvPath % i % allowed);
|
||||||
|
|
||||||
dirsInChroot[i] = i;
|
dirsInChroot[i] = i;
|
||||||
}
|
}
|
||||||
|
@ -1935,13 +1935,13 @@ void DerivationGoal::startBuilder()
|
||||||
/* Clean up the chroot directory automatically. */
|
/* Clean up the chroot directory automatically. */
|
||||||
autoDelChroot = std::make_shared<AutoDelete>(chrootRootDir);
|
autoDelChroot = std::make_shared<AutoDelete>(chrootRootDir);
|
||||||
|
|
||||||
printMsg(lvlChatty, format("setting up chroot environment in '%1%'") % chrootRootDir);
|
printMsg(lvlChatty, format("setting up chroot environment in ‘%1%’") % chrootRootDir);
|
||||||
|
|
||||||
if (mkdir(chrootRootDir.c_str(), 0750) == -1)
|
if (mkdir(chrootRootDir.c_str(), 0750) == -1)
|
||||||
throw SysError(format("cannot create '%1%'") % chrootRootDir);
|
throw SysError(format("cannot create ‘%1%’") % chrootRootDir);
|
||||||
|
|
||||||
if (buildUser.enabled() && chown(chrootRootDir.c_str(), 0, buildUser.getGID()) == -1)
|
if (buildUser.enabled() && chown(chrootRootDir.c_str(), 0, buildUser.getGID()) == -1)
|
||||||
throw SysError(format("cannot change ownership of '%1%'") % chrootRootDir);
|
throw SysError(format("cannot change ownership of ‘%1%’") % chrootRootDir);
|
||||||
|
|
||||||
/* Create a writable /tmp in the chroot. Many builders need
|
/* Create a writable /tmp in the chroot. Many builders need
|
||||||
this. (Of course they should really respect $TMPDIR
|
this. (Of course they should really respect $TMPDIR
|
||||||
|
@ -1985,13 +1985,13 @@ void DerivationGoal::startBuilder()
|
||||||
chmod_(chrootStoreDir, 01775);
|
chmod_(chrootStoreDir, 01775);
|
||||||
|
|
||||||
if (buildUser.enabled() && chown(chrootStoreDir.c_str(), 0, buildUser.getGID()) == -1)
|
if (buildUser.enabled() && chown(chrootStoreDir.c_str(), 0, buildUser.getGID()) == -1)
|
||||||
throw SysError(format("cannot change ownership of '%1%'") % chrootStoreDir);
|
throw SysError(format("cannot change ownership of ‘%1%’") % chrootStoreDir);
|
||||||
|
|
||||||
for (auto & i : inputPaths) {
|
for (auto & i : inputPaths) {
|
||||||
Path r = worker.store.toRealPath(i);
|
Path r = worker.store.toRealPath(i);
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(r.c_str(), &st))
|
if (lstat(r.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % i);
|
throw SysError(format("getting attributes of path ‘%1%’") % i);
|
||||||
if (S_ISDIR(st.st_mode))
|
if (S_ISDIR(st.st_mode))
|
||||||
dirsInChroot[i] = r;
|
dirsInChroot[i] = r;
|
||||||
else {
|
else {
|
||||||
|
@ -2002,7 +2002,7 @@ void DerivationGoal::startBuilder()
|
||||||
which is quite possible after a `nix-store
|
which is quite possible after a `nix-store
|
||||||
--optimise'. */
|
--optimise'. */
|
||||||
if (errno != EMLINK)
|
if (errno != EMLINK)
|
||||||
throw SysError(format("linking '%1%' to '%2%'") % p % i);
|
throw SysError(format("linking ‘%1%’ to ‘%2%’") % p % i);
|
||||||
StringSink sink;
|
StringSink sink;
|
||||||
dumpPath(r, sink);
|
dumpPath(r, sink);
|
||||||
StringSource source(*sink.s);
|
StringSource source(*sink.s);
|
||||||
|
@ -2030,7 +2030,7 @@ void DerivationGoal::startBuilder()
|
||||||
else {
|
else {
|
||||||
|
|
||||||
if (pathExists(homeDir))
|
if (pathExists(homeDir))
|
||||||
throw Error(format("directory '%1%' exists; please remove it") % homeDir);
|
throw Error(format("directory ‘%1%’ exists; please remove it") % homeDir);
|
||||||
|
|
||||||
/* We're not doing a chroot build, but we have some valid
|
/* We're not doing a chroot build, but we have some valid
|
||||||
output paths. Since we can't just overwrite or delete
|
output paths. Since we can't just overwrite or delete
|
||||||
|
@ -2056,7 +2056,7 @@ void DerivationGoal::startBuilder()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.preBuildHook != "") {
|
if (settings.preBuildHook != "") {
|
||||||
printMsg(lvlChatty, format("executing pre-build hook '%1%'")
|
printMsg(lvlChatty, format("executing pre-build hook ‘%1%’")
|
||||||
% settings.preBuildHook);
|
% settings.preBuildHook);
|
||||||
auto args = useChroot ? Strings({drvPath, chrootRootDir}) :
|
auto args = useChroot ? Strings({drvPath, chrootRootDir}) :
|
||||||
Strings({ drvPath });
|
Strings({ drvPath });
|
||||||
|
@ -2075,7 +2075,7 @@ void DerivationGoal::startBuilder()
|
||||||
if (line == "extra-sandbox-paths" || line == "extra-chroot-dirs") {
|
if (line == "extra-sandbox-paths" || line == "extra-chroot-dirs") {
|
||||||
state = stExtraChrootDirs;
|
state = stExtraChrootDirs;
|
||||||
} else {
|
} else {
|
||||||
throw Error(format("unknown pre-build hook command '%1%'")
|
throw Error(format("unknown pre-build hook command ‘%1%’")
|
||||||
% line);
|
% line);
|
||||||
}
|
}
|
||||||
} else if (state == stExtraChrootDirs) {
|
} else if (state == stExtraChrootDirs) {
|
||||||
|
@ -2093,7 +2093,7 @@ void DerivationGoal::startBuilder()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run the builder. */
|
/* Run the builder. */
|
||||||
printMsg(lvlChatty, format("executing builder '%1%'") % drv->builder);
|
printMsg(lvlChatty, format("executing builder ‘%1%’") % drv->builder);
|
||||||
|
|
||||||
/* Create the log file. */
|
/* Create the log file. */
|
||||||
Path logFile = openLogFile();
|
Path logFile = openLogFile();
|
||||||
|
@ -2288,13 +2288,13 @@ void DerivationGoal::runChild()
|
||||||
vector<string> fields = tokenizeString<vector<string> >(i, " ");
|
vector<string> fields = tokenizeString<vector<string> >(i, " ");
|
||||||
string fs = decodeOctalEscaped(fields.at(4));
|
string fs = decodeOctalEscaped(fields.at(4));
|
||||||
if (mount(0, fs.c_str(), 0, MS_PRIVATE, 0) == -1)
|
if (mount(0, fs.c_str(), 0, MS_PRIVATE, 0) == -1)
|
||||||
throw SysError(format("unable to make filesystem '%1%' private") % fs);
|
throw SysError(format("unable to make filesystem ‘%1%’ private") % fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bind-mount chroot directory to itself, to treat it as a
|
/* Bind-mount chroot directory to itself, to treat it as a
|
||||||
different filesystem from /, as needed for pivot_root. */
|
different filesystem from /, as needed for pivot_root. */
|
||||||
if (mount(chrootRootDir.c_str(), chrootRootDir.c_str(), 0, MS_BIND, 0) == -1)
|
if (mount(chrootRootDir.c_str(), chrootRootDir.c_str(), 0, MS_BIND, 0) == -1)
|
||||||
throw SysError(format("unable to bind mount '%1%'") % chrootRootDir);
|
throw SysError(format("unable to bind mount ‘%1%’") % chrootRootDir);
|
||||||
|
|
||||||
/* Set up a nearly empty /dev, unless the user asked to
|
/* Set up a nearly empty /dev, unless the user asked to
|
||||||
bind-mount the host /dev. */
|
bind-mount the host /dev. */
|
||||||
|
@ -2340,12 +2340,12 @@ void DerivationGoal::runChild()
|
||||||
Path source = i.second.source;
|
Path source = i.second.source;
|
||||||
Path target = chrootRootDir + i.first;
|
Path target = chrootRootDir + i.first;
|
||||||
if (source == "/proc") continue; // backwards compatibility
|
if (source == "/proc") continue; // backwards compatibility
|
||||||
debug(format("bind mounting '%1%' to '%2%'") % source % target);
|
debug(format("bind mounting ‘%1%’ to ‘%2%’") % source % target);
|
||||||
if (stat(source.c_str(), &st) == -1) {
|
if (stat(source.c_str(), &st) == -1) {
|
||||||
if (i.second.optional && errno == ENOENT)
|
if (i.second.optional && errno == ENOENT)
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
throw SysError(format("getting attributes of path '%1%'") % source);
|
throw SysError(format("getting attributes of path ‘%1%’") % source);
|
||||||
}
|
}
|
||||||
if (S_ISDIR(st.st_mode))
|
if (S_ISDIR(st.st_mode))
|
||||||
createDirs(target);
|
createDirs(target);
|
||||||
|
@ -2354,7 +2354,7 @@ void DerivationGoal::runChild()
|
||||||
writeFile(target, "");
|
writeFile(target, "");
|
||||||
}
|
}
|
||||||
if (mount(source.c_str(), target.c_str(), "", MS_BIND | MS_REC, 0) == -1)
|
if (mount(source.c_str(), target.c_str(), "", MS_BIND | MS_REC, 0) == -1)
|
||||||
throw SysError(format("bind mount from '%1%' to '%2%' failed") % source % target);
|
throw SysError(format("bind mount from ‘%1%’ to ‘%2%’ failed") % source % target);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bind a new instance of procfs on /proc. */
|
/* Bind a new instance of procfs on /proc. */
|
||||||
|
@ -2392,16 +2392,16 @@ void DerivationGoal::runChild()
|
||||||
|
|
||||||
/* Do the chroot(). */
|
/* Do the chroot(). */
|
||||||
if (chdir(chrootRootDir.c_str()) == -1)
|
if (chdir(chrootRootDir.c_str()) == -1)
|
||||||
throw SysError(format("cannot change directory to '%1%'") % chrootRootDir);
|
throw SysError(format("cannot change directory to ‘%1%’") % chrootRootDir);
|
||||||
|
|
||||||
if (mkdir("real-root", 0) == -1)
|
if (mkdir("real-root", 0) == -1)
|
||||||
throw SysError("cannot create real-root directory");
|
throw SysError("cannot create real-root directory");
|
||||||
|
|
||||||
if (pivot_root(".", "real-root") == -1)
|
if (pivot_root(".", "real-root") == -1)
|
||||||
throw SysError(format("cannot pivot old root directory onto '%1%'") % (chrootRootDir + "/real-root"));
|
throw SysError(format("cannot pivot old root directory onto ‘%1%’") % (chrootRootDir + "/real-root"));
|
||||||
|
|
||||||
if (chroot(".") == -1)
|
if (chroot(".") == -1)
|
||||||
throw SysError(format("cannot change root directory to '%1%'") % chrootRootDir);
|
throw SysError(format("cannot change root directory to ‘%1%’") % chrootRootDir);
|
||||||
|
|
||||||
if (umount2("real-root", MNT_DETACH) == -1)
|
if (umount2("real-root", MNT_DETACH) == -1)
|
||||||
throw SysError("cannot unmount real root filesystem");
|
throw SysError("cannot unmount real root filesystem");
|
||||||
|
@ -2422,7 +2422,7 @@ void DerivationGoal::runChild()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (chdir(tmpDirInSandbox.c_str()) == -1)
|
if (chdir(tmpDirInSandbox.c_str()) == -1)
|
||||||
throw SysError(format("changing into '%1%'") % tmpDir);
|
throw SysError(format("changing into ‘%1%’") % tmpDir);
|
||||||
|
|
||||||
/* Close all other file descriptors. */
|
/* Close all other file descriptors. */
|
||||||
closeMostFDs(set<int>());
|
closeMostFDs(set<int>());
|
||||||
|
@ -2564,7 +2564,7 @@ void DerivationGoal::runChild()
|
||||||
if (lstat(path.c_str(), &st)) {
|
if (lstat(path.c_str(), &st)) {
|
||||||
if (i.second.optional && errno == ENOENT)
|
if (i.second.optional && errno == ENOENT)
|
||||||
continue;
|
continue;
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError(format("getting attributes of path ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
if (S_ISDIR(st.st_mode))
|
if (S_ISDIR(st.st_mode))
|
||||||
sandboxProfile += (format("\t(subpath \"%1%\")\n") % path).str();
|
sandboxProfile += (format("\t(subpath \"%1%\")\n") % path).str();
|
||||||
|
@ -2619,7 +2619,7 @@ void DerivationGoal::runChild()
|
||||||
if (drv->builder == "builtin:fetchurl")
|
if (drv->builder == "builtin:fetchurl")
|
||||||
builtinFetchurl(*drv);
|
builtinFetchurl(*drv);
|
||||||
else
|
else
|
||||||
throw Error(format("unsupported builtin function '%1%'") % string(drv->builder, 8));
|
throw Error(format("unsupported builtin function ‘%1%’") % string(drv->builder, 8));
|
||||||
_exit(0);
|
_exit(0);
|
||||||
} catch (std::exception & e) {
|
} catch (std::exception & e) {
|
||||||
writeFull(STDERR_FILENO, "error: " + string(e.what()) + "\n");
|
writeFull(STDERR_FILENO, "error: " + string(e.what()) + "\n");
|
||||||
|
@ -2629,7 +2629,7 @@ void DerivationGoal::runChild()
|
||||||
|
|
||||||
execve(builder, stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data());
|
execve(builder, stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data());
|
||||||
|
|
||||||
throw SysError(format("executing '%1%'") % drv->builder);
|
throw SysError(format("executing ‘%1%’") % drv->builder);
|
||||||
|
|
||||||
} catch (std::exception & e) {
|
} catch (std::exception & e) {
|
||||||
writeFull(STDERR_FILENO, "\1while setting up the build environment: " + string(e.what()) + "\n");
|
writeFull(STDERR_FILENO, "\1while setting up the build environment: " + string(e.what()) + "\n");
|
||||||
|
@ -2651,7 +2651,7 @@ PathSet parseReferenceSpecifiers(Store & store, const BasicDerivation & drv, str
|
||||||
else if (drv.outputs.find(i) != drv.outputs.end())
|
else if (drv.outputs.find(i) != drv.outputs.end())
|
||||||
result.insert(drv.outputs.find(i)->second.path);
|
result.insert(drv.outputs.find(i)->second.path);
|
||||||
else throw BuildError(
|
else throw BuildError(
|
||||||
format("derivation contains an illegal reference specifier '%1%'") % i);
|
format("derivation contains an illegal reference specifier ‘%1%’") % i);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2694,7 +2694,7 @@ void DerivationGoal::registerOutputs()
|
||||||
replaceValidPath(path, actualPath);
|
replaceValidPath(path, actualPath);
|
||||||
else
|
else
|
||||||
if (buildMode != bmCheck && rename(actualPath.c_str(), worker.store.toRealPath(path).c_str()) == -1)
|
if (buildMode != bmCheck && rename(actualPath.c_str(), worker.store.toRealPath(path).c_str()) == -1)
|
||||||
throw SysError(format("moving build output '%1%' from the sandbox to the Nix store") % path);
|
throw SysError(format("moving build output ‘%1%’ from the sandbox to the Nix store") % path);
|
||||||
}
|
}
|
||||||
if (buildMode != bmCheck) actualPath = worker.store.toRealPath(path);
|
if (buildMode != bmCheck) actualPath = worker.store.toRealPath(path);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2711,9 +2711,9 @@ void DerivationGoal::registerOutputs()
|
||||||
if (lstat(actualPath.c_str(), &st) == -1) {
|
if (lstat(actualPath.c_str(), &st) == -1) {
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
throw BuildError(
|
throw BuildError(
|
||||||
format("builder for '%1%' failed to produce output path '%2%'")
|
format("builder for ‘%1%’ failed to produce output path ‘%2%’")
|
||||||
% drvPath % path);
|
% drvPath % path);
|
||||||
throw SysError(format("getting attributes of path '%1%'") % actualPath);
|
throw SysError(format("getting attributes of path ‘%1%’") % actualPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __CYGWIN__
|
#ifndef __CYGWIN__
|
||||||
|
@ -2723,13 +2723,13 @@ void DerivationGoal::registerOutputs()
|
||||||
user. */
|
user. */
|
||||||
if ((!S_ISLNK(st.st_mode) && (st.st_mode & (S_IWGRP | S_IWOTH))) ||
|
if ((!S_ISLNK(st.st_mode) && (st.st_mode & (S_IWGRP | S_IWOTH))) ||
|
||||||
(buildUser.enabled() && st.st_uid != buildUser.getUID()))
|
(buildUser.enabled() && st.st_uid != buildUser.getUID()))
|
||||||
throw BuildError(format("suspicious ownership or permission on '%1%'; rejecting this build output") % path);
|
throw BuildError(format("suspicious ownership or permission on ‘%1%’; rejecting this build output") % path);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Apply hash rewriting if necessary. */
|
/* Apply hash rewriting if necessary. */
|
||||||
bool rewritten = false;
|
bool rewritten = false;
|
||||||
if (!outputRewrites.empty()) {
|
if (!outputRewrites.empty()) {
|
||||||
printError(format("warning: rewriting hashes in '%1%'; cross fingers") % path);
|
printError(format("warning: rewriting hashes in ‘%1%’; cross fingers") % path);
|
||||||
|
|
||||||
/* Canonicalise first. This ensures that the path we're
|
/* Canonicalise first. This ensures that the path we're
|
||||||
rewriting doesn't contain a hard link to /etc/shadow or
|
rewriting doesn't contain a hard link to /etc/shadow or
|
||||||
|
@ -2760,7 +2760,7 @@ void DerivationGoal::registerOutputs()
|
||||||
execute permission. */
|
execute permission. */
|
||||||
if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0)
|
if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0)
|
||||||
throw BuildError(
|
throw BuildError(
|
||||||
format("output path '%1%' should be a non-executable regular file") % path);
|
format("output path ‘%1%’ should be a non-executable regular file") % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the hash. In hash mode, move the path produced by
|
/* Check the hash. In hash mode, move the path produced by
|
||||||
|
@ -2768,7 +2768,7 @@ void DerivationGoal::registerOutputs()
|
||||||
Hash h2 = recursive ? hashPath(h.type, actualPath).first : hashFile(h.type, actualPath);
|
Hash h2 = recursive ? hashPath(h.type, actualPath).first : hashFile(h.type, actualPath);
|
||||||
if (buildMode == bmHash) {
|
if (buildMode == bmHash) {
|
||||||
Path dest = worker.store.makeFixedOutputPath(recursive, h2, drv->env["name"]);
|
Path dest = worker.store.makeFixedOutputPath(recursive, h2, drv->env["name"]);
|
||||||
printError(format("build produced path '%1%' with %2% hash '%3%'")
|
printError(format("build produced path ‘%1%’ with %2% hash ‘%3%’")
|
||||||
% dest % printHashType(h.type) % printHash16or32(h2));
|
% dest % printHashType(h.type) % printHash16or32(h2));
|
||||||
if (worker.store.isValidPath(dest))
|
if (worker.store.isValidPath(dest))
|
||||||
return;
|
return;
|
||||||
|
@ -2777,14 +2777,14 @@ void DerivationGoal::registerOutputs()
|
||||||
PathLocks outputLocks({actualDest});
|
PathLocks outputLocks({actualDest});
|
||||||
deletePath(actualDest);
|
deletePath(actualDest);
|
||||||
if (rename(actualPath.c_str(), actualDest.c_str()) == -1)
|
if (rename(actualPath.c_str(), actualDest.c_str()) == -1)
|
||||||
throw SysError(format("moving '%1%' to '%2%'") % actualPath % dest);
|
throw SysError(format("moving ‘%1%’ to ‘%2%’") % actualPath % dest);
|
||||||
}
|
}
|
||||||
path = dest;
|
path = dest;
|
||||||
actualPath = actualDest;
|
actualPath = actualDest;
|
||||||
} else {
|
} else {
|
||||||
if (h != h2)
|
if (h != h2)
|
||||||
throw BuildError(
|
throw BuildError(
|
||||||
format("output path '%1%' has %2% hash '%3%' when '%4%' was expected")
|
format("output path ‘%1%’ has %2% hash ‘%3%’ when ‘%4%’ was expected")
|
||||||
% path % i.second.hashAlgo % printHash16or32(h2) % printHash16or32(h));
|
% path % i.second.hashAlgo % printHash16or32(h2) % printHash16or32(h));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2798,7 +2798,7 @@ void DerivationGoal::registerOutputs()
|
||||||
contained in it. Compute the SHA-256 NAR hash at the same
|
contained in it. Compute the SHA-256 NAR hash at the same
|
||||||
time. The hash is stored in the database so that we can
|
time. The hash is stored in the database so that we can
|
||||||
verify later on whether nobody has messed with the store. */
|
verify later on whether nobody has messed with the store. */
|
||||||
Activity act(*logger, lvlTalkative, format("scanning for references inside '%1%'") % path);
|
Activity act(*logger, lvlTalkative, format("scanning for references inside ‘%1%’") % path);
|
||||||
HashResult hash;
|
HashResult hash;
|
||||||
PathSet references = scanForReferences(actualPath, allPaths, hash);
|
PathSet references = scanForReferences(actualPath, allPaths, hash);
|
||||||
|
|
||||||
|
@ -2810,11 +2810,11 @@ void DerivationGoal::registerOutputs()
|
||||||
Path dst = worker.store.toRealPath(path + checkSuffix);
|
Path dst = worker.store.toRealPath(path + checkSuffix);
|
||||||
deletePath(dst);
|
deletePath(dst);
|
||||||
if (rename(actualPath.c_str(), dst.c_str()))
|
if (rename(actualPath.c_str(), dst.c_str()))
|
||||||
throw SysError(format("renaming '%1%' to '%2%'") % actualPath % dst);
|
throw SysError(format("renaming ‘%1%’ to ‘%2%’") % actualPath % dst);
|
||||||
throw Error(format("derivation '%1%' may not be deterministic: output '%2%' differs from '%3%'")
|
throw Error(format("derivation ‘%1%’ may not be deterministic: output ‘%2%’ differs from ‘%3%’")
|
||||||
% drvPath % path % dst);
|
% drvPath % path % dst);
|
||||||
} else
|
} else
|
||||||
throw Error(format("derivation '%1%' may not be deterministic: output '%2%' differs")
|
throw Error(format("derivation ‘%1%’ may not be deterministic: output ‘%2%’ differs")
|
||||||
% drvPath % path);
|
% drvPath % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2834,9 +2834,9 @@ void DerivationGoal::registerOutputs()
|
||||||
for (auto & i : inputPaths) {
|
for (auto & i : inputPaths) {
|
||||||
PathSet::iterator j = references.find(i);
|
PathSet::iterator j = references.find(i);
|
||||||
if (j == references.end())
|
if (j == references.end())
|
||||||
debug(format("unreferenced input: '%1%'") % i);
|
debug(format("unreferenced input: ‘%1%’") % i);
|
||||||
else
|
else
|
||||||
debug(format("referenced input: '%1%'") % i);
|
debug(format("referenced input: ‘%1%’") % i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enforce `allowedReferences' and friends. */
|
/* Enforce `allowedReferences' and friends. */
|
||||||
|
@ -2872,7 +2872,7 @@ void DerivationGoal::registerOutputs()
|
||||||
badPathsStr += "\n\t";
|
badPathsStr += "\n\t";
|
||||||
badPathsStr += i;
|
badPathsStr += i;
|
||||||
}
|
}
|
||||||
throw BuildError(format("output '%1%' is not allowed to refer to the following paths:%2%") % actualPath % badPathsStr);
|
throw BuildError(format("output ‘%1%’ is not allowed to refer to the following paths:%2%") % actualPath % badPathsStr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2909,11 +2909,11 @@ void DerivationGoal::registerOutputs()
|
||||||
Path prev = i->path + checkSuffix;
|
Path prev = i->path + checkSuffix;
|
||||||
if (pathExists(prev))
|
if (pathExists(prev))
|
||||||
throw NotDeterministic(
|
throw NotDeterministic(
|
||||||
format("output '%1%' of '%2%' differs from '%3%' from previous round")
|
format("output ‘%1%’ of ‘%2%’ differs from ‘%3%’ from previous round")
|
||||||
% i->path % drvPath % prev);
|
% i->path % drvPath % prev);
|
||||||
else
|
else
|
||||||
throw NotDeterministic(
|
throw NotDeterministic(
|
||||||
format("output '%1%' of '%2%' differs from previous round")
|
format("output ‘%1%’ of ‘%2%’ differs from previous round")
|
||||||
% i->path % drvPath);
|
% i->path % drvPath);
|
||||||
}
|
}
|
||||||
abort(); // shouldn't happen
|
abort(); // shouldn't happen
|
||||||
|
@ -2926,7 +2926,7 @@ void DerivationGoal::registerOutputs()
|
||||||
if (curRound < nrRounds) {
|
if (curRound < nrRounds) {
|
||||||
Path dst = i.second.path + checkSuffix;
|
Path dst = i.second.path + checkSuffix;
|
||||||
if (rename(i.second.path.c_str(), dst.c_str()))
|
if (rename(i.second.path.c_str(), dst.c_str()))
|
||||||
throw SysError(format("renaming '%1%' to '%2%'") % i.second.path % dst);
|
throw SysError(format("renaming ‘%1%’ to ‘%2%’") % i.second.path % dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2965,7 +2965,7 @@ Path DerivationGoal::openLogFile()
|
||||||
% (settings.compressLog ? ".bz2" : "")).str();
|
% (settings.compressLog ? ".bz2" : "")).str();
|
||||||
|
|
||||||
fdLogFile = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0666);
|
fdLogFile = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0666);
|
||||||
if (!fdLogFile) throw SysError(format("creating log file '%1%'") % logFileName);
|
if (!fdLogFile) throw SysError(format("creating log file ‘%1%’") % logFileName);
|
||||||
|
|
||||||
logFileSink = std::make_shared<FdSink>(fdLogFile.get());
|
logFileSink = std::make_shared<FdSink>(fdLogFile.get());
|
||||||
|
|
||||||
|
@ -2993,7 +2993,7 @@ void DerivationGoal::deleteTmpDir(bool force)
|
||||||
if (tmpDir != "") {
|
if (tmpDir != "") {
|
||||||
if (settings.keepFailed && !force) {
|
if (settings.keepFailed && !force) {
|
||||||
printError(
|
printError(
|
||||||
format("note: keeping build directory '%2%'")
|
format("note: keeping build directory ‘%2%’")
|
||||||
% drvPath % tmpDir);
|
% drvPath % tmpDir);
|
||||||
chmod(tmpDir.c_str(), 0755);
|
chmod(tmpDir.c_str(), 0755);
|
||||||
}
|
}
|
||||||
|
@ -3177,7 +3177,7 @@ SubstitutionGoal::SubstitutionGoal(const Path & storePath, Worker & worker, bool
|
||||||
{
|
{
|
||||||
this->storePath = storePath;
|
this->storePath = storePath;
|
||||||
state = &SubstitutionGoal::init;
|
state = &SubstitutionGoal::init;
|
||||||
name = (format("substitution of '%1%'") % storePath).str();
|
name = (format("substitution of ‘%1%’") % storePath).str();
|
||||||
trace("created");
|
trace("created");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3215,7 +3215,7 @@ void SubstitutionGoal::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.readOnlyMode)
|
if (settings.readOnlyMode)
|
||||||
throw Error(format("cannot substitute path '%1%' - no write access to the Nix store") % storePath);
|
throw Error(format("cannot substitute path ‘%1%’ - no write access to the Nix store") % storePath);
|
||||||
|
|
||||||
subs = settings.useSubstitutes ? getDefaultSubstituters() : std::list<ref<Store>>();
|
subs = settings.useSubstitutes ? getDefaultSubstituters() : std::list<ref<Store>>();
|
||||||
|
|
||||||
|
@ -3230,7 +3230,7 @@ void SubstitutionGoal::tryNext()
|
||||||
if (subs.size() == 0) {
|
if (subs.size() == 0) {
|
||||||
/* None left. Terminate this goal and let someone else deal
|
/* None left. Terminate this goal and let someone else deal
|
||||||
with it. */
|
with it. */
|
||||||
debug(format("path '%1%' is required, but there is no substituter that can build it") % storePath);
|
debug(format("path ‘%1%’ is required, but there is no substituter that can build it") % storePath);
|
||||||
|
|
||||||
/* Hack: don't indicate failure if there were no substituters.
|
/* Hack: don't indicate failure if there were no substituters.
|
||||||
In that case the calling derivation should just do a
|
In that case the calling derivation should just do a
|
||||||
|
@ -3261,7 +3261,7 @@ void SubstitutionGoal::tryNext()
|
||||||
signature. LocalStore::addToStore() also checks for this, but
|
signature. LocalStore::addToStore() also checks for this, but
|
||||||
only after we've downloaded the path. */
|
only after we've downloaded the path. */
|
||||||
if (worker.store.requireSigs && !info->checkSignatures(worker.store, worker.store.publicKeys)) {
|
if (worker.store.requireSigs && !info->checkSignatures(worker.store, worker.store.publicKeys)) {
|
||||||
printInfo(format("warning: substituter '%s' does not have a valid signature for path '%s'")
|
printInfo(format("warning: substituter ‘%s’ does not have a valid signature for path ‘%s’")
|
||||||
% sub->getUri() % storePath);
|
% sub->getUri() % storePath);
|
||||||
tryNext();
|
tryNext();
|
||||||
return;
|
return;
|
||||||
|
@ -3285,7 +3285,7 @@ void SubstitutionGoal::referencesValid()
|
||||||
trace("all references realised");
|
trace("all references realised");
|
||||||
|
|
||||||
if (nrFailed > 0) {
|
if (nrFailed > 0) {
|
||||||
debug(format("some references of path '%1%' could not be realised") % storePath);
|
debug(format("some references of path ‘%1%’ could not be realised") % storePath);
|
||||||
amDone(nrNoSubstituters > 0 || nrIncompleteClosure > 0 ? ecIncompleteClosure : ecFailed);
|
amDone(nrNoSubstituters > 0 || nrIncompleteClosure > 0 ? ecIncompleteClosure : ecFailed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3312,7 +3312,7 @@ void SubstitutionGoal::tryToRun()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printInfo(format("fetching path '%1%'...") % storePath);
|
printInfo(format("fetching path ‘%1%’...") % storePath);
|
||||||
|
|
||||||
outPipe.create();
|
outPipe.create();
|
||||||
|
|
||||||
|
@ -3359,7 +3359,7 @@ void SubstitutionGoal::finished()
|
||||||
worker.markContentsGood(storePath);
|
worker.markContentsGood(storePath);
|
||||||
|
|
||||||
printMsg(lvlChatty,
|
printMsg(lvlChatty,
|
||||||
format("substitution of path '%1%' succeeded") % storePath);
|
format("substitution of path ‘%1%’ succeeded") % storePath);
|
||||||
|
|
||||||
amDone(ecSuccess);
|
amDone(ecSuccess);
|
||||||
}
|
}
|
||||||
|
@ -3589,7 +3589,7 @@ void Worker::run(const Goals & _topGoals)
|
||||||
waitForInput();
|
waitForInput();
|
||||||
else {
|
else {
|
||||||
if (awake.empty() && settings.maxBuildJobs == 0) throw Error(
|
if (awake.empty() && settings.maxBuildJobs == 0) throw Error(
|
||||||
"unable to start any build; either increase '--max-jobs' "
|
"unable to start any build; either increase ‘--max-jobs’ "
|
||||||
"or enable distributed builds");
|
"or enable distributed builds");
|
||||||
assert(!awake.empty());
|
assert(!awake.empty());
|
||||||
}
|
}
|
||||||
|
@ -3744,7 +3744,7 @@ bool Worker::pathContentsGood(const Path & path)
|
||||||
{
|
{
|
||||||
std::map<Path, bool>::iterator i = pathContentsGoodCache.find(path);
|
std::map<Path, bool>::iterator i = pathContentsGoodCache.find(path);
|
||||||
if (i != pathContentsGoodCache.end()) return i->second;
|
if (i != pathContentsGoodCache.end()) return i->second;
|
||||||
printInfo(format("checking path '%1%'...") % path);
|
printInfo(format("checking path ‘%1%’...") % path);
|
||||||
auto info = store.queryPathInfo(path);
|
auto info = store.queryPathInfo(path);
|
||||||
bool res;
|
bool res;
|
||||||
if (!pathExists(path))
|
if (!pathExists(path))
|
||||||
|
@ -3755,7 +3755,7 @@ bool Worker::pathContentsGood(const Path & path)
|
||||||
res = info->narHash == nullHash || info->narHash == current.first;
|
res = info->narHash == nullHash || info->narHash == current.first;
|
||||||
}
|
}
|
||||||
pathContentsGoodCache[path] = res;
|
pathContentsGoodCache[path] = res;
|
||||||
if (!res) printError(format("path '%1%' is corrupted or missing!") % path);
|
if (!res) printError(format("path ‘%1%’ is corrupted or missing!") % path);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3829,7 +3829,7 @@ void LocalStore::ensurePath(const Path & path)
|
||||||
worker.run(goals);
|
worker.run(goals);
|
||||||
|
|
||||||
if (goal->getExitCode() != Goal::ecSuccess)
|
if (goal->getExitCode() != Goal::ecSuccess)
|
||||||
throw Error(worker.exitStatus(), "path '%s' does not exist and cannot be created", path);
|
throw Error(worker.exitStatus(), "path ‘%s’ does not exist and cannot be created", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3850,7 +3850,7 @@ void LocalStore::repairPath(const Path & path)
|
||||||
goals.insert(worker.makeDerivationGoal(deriver, StringSet(), bmRepair));
|
goals.insert(worker.makeDerivationGoal(deriver, StringSet(), bmRepair));
|
||||||
worker.run(goals);
|
worker.run(goals);
|
||||||
} else
|
} else
|
||||||
throw Error(worker.exitStatus(), "cannot repair path '%s'", path);
|
throw Error(worker.exitStatus(), "cannot repair path ‘%s’", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ void builtinFetchurl(const BasicDerivation & drv)
|
||||||
{
|
{
|
||||||
auto getAttr = [&](const string & name) {
|
auto getAttr = [&](const string & name) {
|
||||||
auto i = drv.env.find(name);
|
auto i = drv.env.find(name);
|
||||||
if (i == drv.env.end()) throw Error(format("attribute '%s' missing") % name);
|
if (i == drv.env.end()) throw Error(format("attribute ‘%s’ missing") % name);
|
||||||
return i->second;
|
return i->second;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ void builtinFetchurl(const BasicDerivation & drv)
|
||||||
auto executable = drv.env.find("executable");
|
auto executable = drv.env.find("executable");
|
||||||
if (executable != drv.env.end() && executable->second == "1") {
|
if (executable != drv.env.end() && executable->second == "1") {
|
||||||
if (chmod(storePath.c_str(), 0755) == -1)
|
if (chmod(storePath.c_str(), 0755) == -1)
|
||||||
throw SysError(format("making '%1%' executable") % storePath);
|
throw SysError(format("making ‘%1%’ executable") % storePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct Key
|
||||||
std::string key;
|
std::string key;
|
||||||
|
|
||||||
/* Construct Key from a string in the format
|
/* Construct Key from a string in the format
|
||||||
'<name>:<key-in-base64>'. */
|
‘<name>:<key-in-base64>’. */
|
||||||
Key(const std::string & s);
|
Key(const std::string & s);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -44,7 +44,7 @@ private:
|
||||||
|
|
||||||
typedef std::map<std::string, PublicKey> PublicKeys;
|
typedef std::map<std::string, PublicKey> PublicKeys;
|
||||||
|
|
||||||
/* Return true iff 'sig' is a correct signature over 'data' using one
|
/* Return true iff ‘sig’ is a correct signature over ‘data’ using one
|
||||||
of the given public keys. */
|
of the given public keys. */
|
||||||
bool verifyDetached(const std::string & data, const std::string & sig,
|
bool verifyDetached(const std::string & data, const std::string & sig,
|
||||||
const PublicKeys & publicKeys);
|
const PublicKeys & publicKeys);
|
||||||
|
|
|
@ -21,7 +21,7 @@ void DerivationOutput::parseHashInfo(bool & recursive, Hash & hash) const
|
||||||
|
|
||||||
HashType hashType = parseHashType(algo);
|
HashType hashType = parseHashType(algo);
|
||||||
if (hashType == htUnknown)
|
if (hashType == htUnknown)
|
||||||
throw Error(format("unknown hash algorithm '%1%'") % algo);
|
throw Error(format("unknown hash algorithm ‘%1%’") % algo);
|
||||||
|
|
||||||
hash = parseHash(hashType, this->hash);
|
hash = parseHash(hashType, this->hash);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ Path BasicDerivation::findOutput(const string & id) const
|
||||||
{
|
{
|
||||||
auto i = outputs.find(id);
|
auto i = outputs.find(id);
|
||||||
if (i == outputs.end())
|
if (i == outputs.end())
|
||||||
throw Error(format("derivation has no output '%1%'") % id);
|
throw Error(format("derivation has no output ‘%1%’") % id);
|
||||||
return i->second.path;
|
return i->second.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ static void expect(std::istream & str, const string & s)
|
||||||
char s2[s.size()];
|
char s2[s.size()];
|
||||||
str.read(s2, s.size());
|
str.read(s2, s.size());
|
||||||
if (string(s2, s.size()) != s)
|
if (string(s2, s.size()) != s)
|
||||||
throw FormatError(format("expected string '%1%'") % s);
|
throw FormatError(format("expected string ‘%1%’") % s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ static Path parsePath(std::istream & str)
|
||||||
{
|
{
|
||||||
string s = parseString(str);
|
string s = parseString(str);
|
||||||
if (s.size() == 0 || s[0] != '/')
|
if (s.size() == 0 || s[0] != '/')
|
||||||
throw FormatError(format("bad path '%1%' in derivation") % s);
|
throw FormatError(format("bad path ‘%1%’ in derivation") % s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ Derivation readDerivation(const Path & drvPath)
|
||||||
try {
|
try {
|
||||||
return parseDerivation(readFile(drvPath));
|
return parseDerivation(readFile(drvPath));
|
||||||
} catch (FormatError & e) {
|
} catch (FormatError & e) {
|
||||||
throw Error(format("error parsing derivation '%1%': %2%") % drvPath % e.msg());
|
throw Error(format("error parsing derivation ‘%1%’: %2%") % drvPath % e.msg());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ Derivation Store::derivationFromPath(const Path & drvPath)
|
||||||
try {
|
try {
|
||||||
return parseDerivation(accessor->readFile(drvPath));
|
return parseDerivation(accessor->readFile(drvPath));
|
||||||
} catch (FormatError & e) {
|
} catch (FormatError & e) {
|
||||||
throw Error(format("error parsing derivation '%1%': %2%") % drvPath % e.msg());
|
throw Error(format("error parsing derivation ‘%1%’: %2%") % drvPath % e.msg());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ struct CurlDownloader : public Downloader
|
||||||
if (requestHeaders) curl_slist_free_all(requestHeaders);
|
if (requestHeaders) curl_slist_free_all(requestHeaders);
|
||||||
try {
|
try {
|
||||||
if (!done)
|
if (!done)
|
||||||
fail(DownloadError(Interrupted, format("download of '%s' was interrupted") % request.uri));
|
fail(DownloadError(Interrupted, format("download of ‘%s’ was interrupted") % request.uri));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
ignoreException();
|
ignoreException();
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ struct CurlDownloader : public Downloader
|
||||||
{
|
{
|
||||||
size_t realSize = size * nmemb;
|
size_t realSize = size * nmemb;
|
||||||
std::string line((char *) contents, realSize);
|
std::string line((char *) contents, realSize);
|
||||||
printMsg(lvlVomit, format("got header for '%s': %s") % request.uri % trim(line));
|
printMsg(lvlVomit, format("got header for ‘%s’: %s") % request.uri % trim(line));
|
||||||
if (line.compare(0, 5, "HTTP/") == 0) { // new response starts
|
if (line.compare(0, 5, "HTTP/") == 0) { // new response starts
|
||||||
result.etag = "";
|
result.etag = "";
|
||||||
auto ss = tokenizeString<vector<string>>(line, " ");
|
auto ss = tokenizeString<vector<string>>(line, " ");
|
||||||
|
@ -176,7 +176,7 @@ struct CurlDownloader : public Downloader
|
||||||
{
|
{
|
||||||
// FIXME: handle parallel downloads.
|
// FIXME: handle parallel downloads.
|
||||||
if (showProgress) {
|
if (showProgress) {
|
||||||
std::cerr << (format("downloading '%1%'... ") % request.uri);
|
std::cerr << (format("downloading ‘%1%’... ") % request.uri);
|
||||||
std::cerr.flush();
|
std::cerr.flush();
|
||||||
startTime = getTime();
|
startTime = getTime();
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ struct CurlDownloader : public Downloader
|
||||||
if (effectiveUrlCStr)
|
if (effectiveUrlCStr)
|
||||||
result.effectiveUrl = effectiveUrlCStr;
|
result.effectiveUrl = effectiveUrlCStr;
|
||||||
|
|
||||||
debug(format("finished download of '%s'; curl status = %d, HTTP status = %d, body = %d bytes")
|
debug(format("finished download of ‘%s’; curl status = %d, HTTP status = %d, body = %d bytes")
|
||||||
% request.uri % code % httpStatus % (result.data ? result.data->size() : 0));
|
% request.uri % code % httpStatus % (result.data ? result.data->size() : 0));
|
||||||
|
|
||||||
if (code == CURLE_WRITE_ERROR && result.etag == request.expectedETag) {
|
if (code == CURLE_WRITE_ERROR && result.etag == request.expectedETag) {
|
||||||
|
@ -261,10 +261,10 @@ struct CurlDownloader : public Downloader
|
||||||
|
|
||||||
auto exc =
|
auto exc =
|
||||||
code == CURLE_ABORTED_BY_CALLBACK && _isInterrupted
|
code == CURLE_ABORTED_BY_CALLBACK && _isInterrupted
|
||||||
? DownloadError(Interrupted, format("download of '%s' was interrupted") % request.uri)
|
? DownloadError(Interrupted, format("download of ‘%s’ was interrupted") % request.uri)
|
||||||
: httpStatus != 0
|
: httpStatus != 0
|
||||||
? DownloadError(err, format("unable to download '%s': HTTP error %d") % request.uri % httpStatus)
|
? DownloadError(err, format("unable to download ‘%s’: HTTP error %d") % request.uri % httpStatus)
|
||||||
: DownloadError(err, format("unable to download '%s': %s (%d)") % request.uri % curl_easy_strerror(code) % code);
|
: DownloadError(err, format("unable to download ‘%s’: %s (%d)") % request.uri % curl_easy_strerror(code) % code);
|
||||||
|
|
||||||
/* If this is a transient error, then maybe retry the
|
/* If this is a transient error, then maybe retry the
|
||||||
download after a while. */
|
download after a while. */
|
||||||
|
@ -534,7 +534,7 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
|
||||||
if (effectiveUrl)
|
if (effectiveUrl)
|
||||||
*effectiveUrl = url_;
|
*effectiveUrl = url_;
|
||||||
} else if (!ss[1].empty()) {
|
} else if (!ss[1].empty()) {
|
||||||
debug(format("verifying previous ETag '%1%'") % ss[1]);
|
debug(format("verifying previous ETag ‘%1%’") % ss[1]);
|
||||||
expectedETag = ss[1];
|
expectedETag = ss[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -582,7 +582,7 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
|
||||||
unpackedStorePath = "";
|
unpackedStorePath = "";
|
||||||
}
|
}
|
||||||
if (unpackedStorePath.empty()) {
|
if (unpackedStorePath.empty()) {
|
||||||
printInfo(format("unpacking '%1%'...") % url);
|
printInfo(format("unpacking ‘%1%’...") % url);
|
||||||
Path tmpDir = createTempDir();
|
Path tmpDir = createTempDir();
|
||||||
AutoDelete autoDelete(tmpDir, true);
|
AutoDelete autoDelete(tmpDir, true);
|
||||||
// FIXME: this requires GNU tar for decompression.
|
// FIXME: this requires GNU tar for decompression.
|
||||||
|
@ -594,7 +594,7 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedStorePath != "" && storePath != expectedStorePath)
|
if (expectedStorePath != "" && storePath != expectedStorePath)
|
||||||
throw nix::Error(format("hash mismatch in file downloaded from '%s'") % url);
|
throw nix::Error(format("hash mismatch in file downloaded from ‘%s’") % url);
|
||||||
|
|
||||||
return storePath;
|
return storePath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ struct Downloader
|
||||||
DownloadResult download(const DownloadRequest & request);
|
DownloadResult download(const DownloadRequest & request);
|
||||||
|
|
||||||
/* Check if the specified file is already in ~/.cache/nix/tarballs
|
/* Check if the specified file is already in ~/.cache/nix/tarballs
|
||||||
and is more recent than 'tarball-ttl' seconds. Otherwise,
|
and is more recent than ‘tarball-ttl’ seconds. Otherwise,
|
||||||
use the recorded ETag to verify if the server has a more
|
use the recorded ETag to verify if the server has a more
|
||||||
recent version, and if so, download it to the Nix store. */
|
recent version, and if so, download it to the Nix store. */
|
||||||
Path downloadCached(ref<Store> store, const string & uri, bool unpack, string name = "",
|
Path downloadCached(ref<Store> store, const string & uri, bool unpack, string name = "",
|
||||||
|
|
|
@ -33,7 +33,7 @@ void Store::exportPaths(const Paths & paths, Sink & sink)
|
||||||
logger->incExpected(doneLabel, sorted.size());
|
logger->incExpected(doneLabel, sorted.size());
|
||||||
|
|
||||||
for (auto & path : sorted) {
|
for (auto & path : sorted) {
|
||||||
Activity act(*logger, lvlInfo, format("exporting path '%s'") % path);
|
Activity act(*logger, lvlInfo, format("exporting path ‘%s’") % path);
|
||||||
sink << 1;
|
sink << 1;
|
||||||
exportPath(path, sink);
|
exportPath(path, sink);
|
||||||
logger->incProgress(doneLabel);
|
logger->incProgress(doneLabel);
|
||||||
|
@ -55,7 +55,7 @@ void Store::exportPath(const Path & path, Sink & sink)
|
||||||
Don't complain if the stored hash is zero (unknown). */
|
Don't complain if the stored hash is zero (unknown). */
|
||||||
Hash hash = hashAndWriteSink.currentHash();
|
Hash hash = hashAndWriteSink.currentHash();
|
||||||
if (hash != info->narHash && info->narHash != Hash(info->narHash.type))
|
if (hash != info->narHash && info->narHash != Hash(info->narHash.type))
|
||||||
throw Error(format("hash of path '%1%' has changed from '%2%' to '%3%'!") % path
|
throw Error(format("hash of path ‘%1%’ has changed from ‘%2%’ to ‘%3%’!") % path
|
||||||
% printHash(info->narHash) % printHash(hash));
|
% printHash(info->narHash) % printHash(hash));
|
||||||
|
|
||||||
hashAndWriteSink << exportMagic << path << info->references << info->deriver << 0;
|
hashAndWriteSink << exportMagic << path << info->references << info->deriver << 0;
|
||||||
|
@ -88,7 +88,7 @@ Paths Store::importPaths(Source & source, std::shared_ptr<FSAccessor> accessor,
|
||||||
while (true) {
|
while (true) {
|
||||||
unsigned long long n = readLongLong(source);
|
unsigned long long n = readLongLong(source);
|
||||||
if (n == 0) break;
|
if (n == 0) break;
|
||||||
if (n != 1) throw Error("input doesn't look like something created by 'nix-store --export'");
|
if (n != 1) throw Error("input doesn't look like something created by ‘nix-store --export’");
|
||||||
|
|
||||||
/* Extract the NAR from the source. */
|
/* Extract the NAR from the source. */
|
||||||
TeeSource tee(source);
|
TeeSource tee(source);
|
||||||
|
@ -103,7 +103,7 @@ Paths Store::importPaths(Source & source, std::shared_ptr<FSAccessor> accessor,
|
||||||
|
|
||||||
info.path = readStorePath(*this, source);
|
info.path = readStorePath(*this, source);
|
||||||
|
|
||||||
Activity act(*logger, lvlInfo, format("importing path '%s'") % info.path);
|
Activity act(*logger, lvlInfo, format("importing path ‘%s’") % info.path);
|
||||||
|
|
||||||
info.references = readStorePaths<PathSet>(*this, source);
|
info.references = readStorePaths<PathSet>(*this, source);
|
||||||
|
|
||||||
|
|
|
@ -32,11 +32,11 @@ int LocalStore::openGCLock(LockType lockType)
|
||||||
Path fnGCLock = (format("%1%/%2%")
|
Path fnGCLock = (format("%1%/%2%")
|
||||||
% stateDir % gcLockName).str();
|
% stateDir % gcLockName).str();
|
||||||
|
|
||||||
debug(format("acquiring global GC lock '%1%'") % fnGCLock);
|
debug(format("acquiring global GC lock ‘%1%’") % fnGCLock);
|
||||||
|
|
||||||
AutoCloseFD fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
|
AutoCloseFD fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
|
||||||
if (!fdGCLock)
|
if (!fdGCLock)
|
||||||
throw SysError(format("opening global GC lock '%1%'") % fnGCLock);
|
throw SysError(format("opening global GC lock ‘%1%’") % fnGCLock);
|
||||||
|
|
||||||
if (!lockFile(fdGCLock.get(), lockType, false)) {
|
if (!lockFile(fdGCLock.get(), lockType, false)) {
|
||||||
printError(format("waiting for the big garbage collector lock..."));
|
printError(format("waiting for the big garbage collector lock..."));
|
||||||
|
@ -63,7 +63,7 @@ static void makeSymlink(const Path & link, const Path & target)
|
||||||
|
|
||||||
/* Atomically replace the old one. */
|
/* Atomically replace the old one. */
|
||||||
if (rename(tempLink.c_str(), link.c_str()) == -1)
|
if (rename(tempLink.c_str(), link.c_str()) == -1)
|
||||||
throw SysError(format("cannot rename '%1%' to '%2%'")
|
throw SysError(format("cannot rename ‘%1%’ to ‘%2%’")
|
||||||
% tempLink % link);
|
% tempLink % link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ Path LocalFSStore::addPermRoot(const Path & _storePath,
|
||||||
/* Don't clobber the link if it already exists and doesn't
|
/* Don't clobber the link if it already exists and doesn't
|
||||||
point to the Nix store. */
|
point to the Nix store. */
|
||||||
if (pathExists(gcRoot) && (!isLink(gcRoot) || !isInStore(readLink(gcRoot))))
|
if (pathExists(gcRoot) && (!isLink(gcRoot) || !isInStore(readLink(gcRoot))))
|
||||||
throw Error(format("cannot create symlink '%1%'; already exists") % gcRoot);
|
throw Error(format("cannot create symlink ‘%1%’; already exists") % gcRoot);
|
||||||
makeSymlink(gcRoot, storePath);
|
makeSymlink(gcRoot, storePath);
|
||||||
addIndirectRoot(gcRoot);
|
addIndirectRoot(gcRoot);
|
||||||
}
|
}
|
||||||
|
@ -110,8 +110,8 @@ Path LocalFSStore::addPermRoot(const Path & _storePath,
|
||||||
|
|
||||||
if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/")
|
if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/")
|
||||||
throw Error(format(
|
throw Error(format(
|
||||||
"path '%1%' is not a valid garbage collector root; "
|
"path ‘%1%’ is not a valid garbage collector root; "
|
||||||
"it's not in the directory '%2%'")
|
"it's not in the directory ‘%2%’")
|
||||||
% gcRoot % rootsDir);
|
% gcRoot % rootsDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,8 +131,8 @@ Path LocalFSStore::addPermRoot(const Path & _storePath,
|
||||||
if (roots.find(gcRoot) == roots.end())
|
if (roots.find(gcRoot) == roots.end())
|
||||||
printError(
|
printError(
|
||||||
format(
|
format(
|
||||||
"warning: '%1%' is not in a directory where the garbage collector looks for roots; "
|
"warning: ‘%1%’ is not in a directory where the garbage collector looks for roots; "
|
||||||
"therefore, '%2%' might be removed by the garbage collector")
|
"therefore, ‘%2%’ might be removed by the garbage collector")
|
||||||
% gcRoot % storePath);
|
% gcRoot % storePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,14 +169,14 @@ void LocalStore::addTempRoot(const Path & path)
|
||||||
|
|
||||||
fdGCLock = -1;
|
fdGCLock = -1;
|
||||||
|
|
||||||
debug(format("acquiring read lock on '%1%'") % state->fnTempRoots);
|
debug(format("acquiring read lock on ‘%1%’") % state->fnTempRoots);
|
||||||
lockFile(state->fdTempRoots.get(), ltRead, true);
|
lockFile(state->fdTempRoots.get(), ltRead, true);
|
||||||
|
|
||||||
/* Check whether the garbage collector didn't get in our
|
/* Check whether the garbage collector didn't get in our
|
||||||
way. */
|
way. */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat(state->fdTempRoots.get(), &st) == -1)
|
if (fstat(state->fdTempRoots.get(), &st) == -1)
|
||||||
throw SysError(format("statting '%1%'") % state->fnTempRoots);
|
throw SysError(format("statting ‘%1%’") % state->fnTempRoots);
|
||||||
if (st.st_size == 0) break;
|
if (st.st_size == 0) break;
|
||||||
|
|
||||||
/* The garbage collector deleted this file before we could
|
/* The garbage collector deleted this file before we could
|
||||||
|
@ -188,14 +188,14 @@ void LocalStore::addTempRoot(const Path & path)
|
||||||
|
|
||||||
/* Upgrade the lock to a write lock. This will cause us to block
|
/* Upgrade the lock to a write lock. This will cause us to block
|
||||||
if the garbage collector is holding our lock. */
|
if the garbage collector is holding our lock. */
|
||||||
debug(format("acquiring write lock on '%1%'") % state->fnTempRoots);
|
debug(format("acquiring write lock on ‘%1%’") % state->fnTempRoots);
|
||||||
lockFile(state->fdTempRoots.get(), ltWrite, true);
|
lockFile(state->fdTempRoots.get(), ltWrite, true);
|
||||||
|
|
||||||
string s = path + '\0';
|
string s = path + '\0';
|
||||||
writeFull(state->fdTempRoots.get(), s);
|
writeFull(state->fdTempRoots.get(), s);
|
||||||
|
|
||||||
/* Downgrade to a read lock. */
|
/* Downgrade to a read lock. */
|
||||||
debug(format("downgrading to read lock on '%1%'") % state->fnTempRoots);
|
debug(format("downgrading to read lock on ‘%1%’") % state->fnTempRoots);
|
||||||
lockFile(state->fdTempRoots.get(), ltRead, true);
|
lockFile(state->fdTempRoots.get(), ltRead, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,12 +210,12 @@ void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds)
|
||||||
for (auto & i : tempRootFiles) {
|
for (auto & i : tempRootFiles) {
|
||||||
Path path = (format("%1%/%2%/%3%") % stateDir % tempRootsDir % i.name).str();
|
Path path = (format("%1%/%2%/%3%") % stateDir % tempRootsDir % i.name).str();
|
||||||
|
|
||||||
debug(format("reading temporary root file '%1%'") % path);
|
debug(format("reading temporary root file ‘%1%’") % path);
|
||||||
FDPtr fd(new AutoCloseFD(open(path.c_str(), O_CLOEXEC | O_RDWR, 0666)));
|
FDPtr fd(new AutoCloseFD(open(path.c_str(), O_CLOEXEC | O_RDWR, 0666)));
|
||||||
if (!*fd) {
|
if (!*fd) {
|
||||||
/* It's okay if the file has disappeared. */
|
/* It's okay if the file has disappeared. */
|
||||||
if (errno == ENOENT) continue;
|
if (errno == ENOENT) continue;
|
||||||
throw SysError(format("opening temporary roots file '%1%'") % path);
|
throw SysError(format("opening temporary roots file ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This should work, but doesn't, for some reason. */
|
/* This should work, but doesn't, for some reason. */
|
||||||
|
@ -226,7 +226,7 @@ void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds)
|
||||||
only succeed if the owning process has died. In that case
|
only succeed if the owning process has died. In that case
|
||||||
we don't care about its temporary roots. */
|
we don't care about its temporary roots. */
|
||||||
if (lockFile(fd->get(), ltWrite, false)) {
|
if (lockFile(fd->get(), ltWrite, false)) {
|
||||||
printError(format("removing stale temporary roots file '%1%'") % path);
|
printError(format("removing stale temporary roots file ‘%1%’") % path);
|
||||||
unlink(path.c_str());
|
unlink(path.c_str());
|
||||||
writeFull(fd->get(), "d");
|
writeFull(fd->get(), "d");
|
||||||
continue;
|
continue;
|
||||||
|
@ -235,7 +235,7 @@ void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds)
|
||||||
/* Acquire a read lock. This will prevent the owning process
|
/* Acquire a read lock. This will prevent the owning process
|
||||||
from upgrading to a write lock, therefore it will block in
|
from upgrading to a write lock, therefore it will block in
|
||||||
addTempRoot(). */
|
addTempRoot(). */
|
||||||
debug(format("waiting for read lock on '%1%'") % path);
|
debug(format("waiting for read lock on ‘%1%’") % path);
|
||||||
lockFile(fd->get(), ltRead, true);
|
lockFile(fd->get(), ltRead, true);
|
||||||
|
|
||||||
/* Read the entire file. */
|
/* Read the entire file. */
|
||||||
|
@ -246,7 +246,7 @@ void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds)
|
||||||
|
|
||||||
while ((end = contents.find((char) 0, pos)) != string::npos) {
|
while ((end = contents.find((char) 0, pos)) != string::npos) {
|
||||||
Path root(contents, pos, end - pos);
|
Path root(contents, pos, end - pos);
|
||||||
debug(format("got temporary root '%1%'") % root);
|
debug(format("got temporary root ‘%1%’") % root);
|
||||||
assertStorePath(root);
|
assertStorePath(root);
|
||||||
tempRoots.insert(root);
|
tempRoots.insert(root);
|
||||||
pos = end + 1;
|
pos = end + 1;
|
||||||
|
@ -264,7 +264,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
|
||||||
if (isStorePath(storePath) && isValidPath(storePath))
|
if (isStorePath(storePath) && isValidPath(storePath))
|
||||||
roots[path] = storePath;
|
roots[path] = storePath;
|
||||||
else
|
else
|
||||||
printInfo(format("skipping invalid root from '%1%' to '%2%'") % path % storePath);
|
printInfo(format("skipping invalid root from ‘%1%’ to ‘%2%’") % path % storePath);
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -287,7 +287,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
|
||||||
target = absPath(target, dirOf(path));
|
target = absPath(target, dirOf(path));
|
||||||
if (!pathExists(target)) {
|
if (!pathExists(target)) {
|
||||||
if (isInDir(path, stateDir + "/" + gcRootsDir + "/auto")) {
|
if (isInDir(path, stateDir + "/" + gcRootsDir + "/auto")) {
|
||||||
printInfo(format("removing stale link from '%1%' to '%2%'") % path % target);
|
printInfo(format("removing stale link from ‘%1%’ to ‘%2%’") % path % target);
|
||||||
unlink(path.c_str());
|
unlink(path.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -310,7 +310,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
|
||||||
catch (SysError & e) {
|
catch (SysError & e) {
|
||||||
/* We only ignore permanent failures. */
|
/* We only ignore permanent failures. */
|
||||||
if (e.errNo == EACCES || e.errNo == ENOENT || e.errNo == ENOTDIR)
|
if (e.errNo == EACCES || e.errNo == ENOENT || e.errNo == ENOTDIR)
|
||||||
printInfo(format("cannot read potential root '%1%'") % path);
|
printInfo(format("cannot read potential root ‘%1%’") % path);
|
||||||
else
|
else
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@ -447,7 +447,7 @@ void LocalStore::findRuntimeRoots(PathSet & roots)
|
||||||
if (isInStore(i)) {
|
if (isInStore(i)) {
|
||||||
Path path = toStorePath(i);
|
Path path = toStorePath(i);
|
||||||
if (roots.find(path) == roots.end() && isStorePath(path) && isValidPath(path)) {
|
if (roots.find(path) == roots.end() && isStorePath(path) && isValidPath(path)) {
|
||||||
debug(format("got additional root '%1%'") % path);
|
debug(format("got additional root ‘%1%’") % path);
|
||||||
roots.insert(path);
|
roots.insert(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -513,7 +513,7 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
|
||||||
throw SysError(format("getting status of %1%") % realPath);
|
throw SysError(format("getting status of %1%") % realPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
printInfo(format("deleting '%1%'") % path);
|
printInfo(format("deleting ‘%1%’") % path);
|
||||||
|
|
||||||
state.results.paths.insert(path);
|
state.results.paths.insert(path);
|
||||||
|
|
||||||
|
@ -528,14 +528,14 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
|
||||||
// size.
|
// size.
|
||||||
try {
|
try {
|
||||||
if (chmod(realPath.c_str(), st.st_mode | S_IWUSR) == -1)
|
if (chmod(realPath.c_str(), st.st_mode | S_IWUSR) == -1)
|
||||||
throw SysError(format("making '%1%' writable") % realPath);
|
throw SysError(format("making ‘%1%’ writable") % realPath);
|
||||||
Path tmp = trashDir + "/" + baseNameOf(path);
|
Path tmp = trashDir + "/" + baseNameOf(path);
|
||||||
if (rename(realPath.c_str(), tmp.c_str()))
|
if (rename(realPath.c_str(), tmp.c_str()))
|
||||||
throw SysError(format("unable to rename '%1%' to '%2%'") % realPath % tmp);
|
throw SysError(format("unable to rename ‘%1%’ to ‘%2%’") % realPath % tmp);
|
||||||
state.bytesInvalidated += size;
|
state.bytesInvalidated += size;
|
||||||
} catch (SysError & e) {
|
} catch (SysError & e) {
|
||||||
if (e.errNo == ENOSPC) {
|
if (e.errNo == ENOSPC) {
|
||||||
printInfo(format("note: can't create move '%1%': %2%") % realPath % e.msg());
|
printInfo(format("note: can't create move ‘%1%’: %2%") % realPath % e.msg());
|
||||||
deleteGarbage(state, realPath);
|
deleteGarbage(state, realPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -562,7 +562,7 @@ bool LocalStore::canReachRoot(GCState & state, PathSet & visited, const Path & p
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.roots.find(path) != state.roots.end()) {
|
if (state.roots.find(path) != state.roots.end()) {
|
||||||
debug(format("cannot delete '%1%' because it's a root") % path);
|
debug(format("cannot delete ‘%1%’ because it's a root") % path);
|
||||||
state.alive.insert(path);
|
state.alive.insert(path);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -611,7 +611,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
|
||||||
auto realPath = realStoreDir + "/" + baseNameOf(path);
|
auto realPath = realStoreDir + "/" + baseNameOf(path);
|
||||||
if (realPath == linksDir || realPath == trashDir) return;
|
if (realPath == linksDir || realPath == trashDir) return;
|
||||||
|
|
||||||
Activity act(*logger, lvlDebug, format("considering whether to delete '%1%'") % path);
|
Activity act(*logger, lvlDebug, format("considering whether to delete ‘%1%’") % path);
|
||||||
|
|
||||||
if (!isStorePath(path) || !isValidPath(path)) {
|
if (!isStorePath(path) || !isValidPath(path)) {
|
||||||
/* A lock file belonging to a path that we're building right
|
/* A lock file belonging to a path that we're building right
|
||||||
|
@ -626,11 +626,11 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
|
||||||
PathSet visited;
|
PathSet visited;
|
||||||
|
|
||||||
if (canReachRoot(state, visited, path)) {
|
if (canReachRoot(state, visited, path)) {
|
||||||
debug(format("cannot delete '%1%' because it's still reachable") % path);
|
debug(format("cannot delete ‘%1%’ because it's still reachable") % path);
|
||||||
} else {
|
} else {
|
||||||
/* No path we visited was a root, so everything is garbage.
|
/* No path we visited was a root, so everything is garbage.
|
||||||
But we only delete 'path' and its referrers here so that
|
But we only delete ‘path’ and its referrers here so that
|
||||||
'nix-store --delete' doesn't have the unexpected effect of
|
‘nix-store --delete’ doesn't have the unexpected effect of
|
||||||
recursing into derivations and outputs. */
|
recursing into derivations and outputs. */
|
||||||
state.dead.insert(visited.begin(), visited.end());
|
state.dead.insert(visited.begin(), visited.end());
|
||||||
if (state.shouldDelete)
|
if (state.shouldDelete)
|
||||||
|
@ -647,7 +647,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
|
||||||
void LocalStore::removeUnusedLinks(const GCState & state)
|
void LocalStore::removeUnusedLinks(const GCState & state)
|
||||||
{
|
{
|
||||||
AutoCloseDir dir = opendir(linksDir.c_str());
|
AutoCloseDir dir = opendir(linksDir.c_str());
|
||||||
if (!dir) throw SysError(format("opening directory '%1%'") % linksDir);
|
if (!dir) throw SysError(format("opening directory ‘%1%’") % linksDir);
|
||||||
|
|
||||||
long long actualSize = 0, unsharedSize = 0;
|
long long actualSize = 0, unsharedSize = 0;
|
||||||
|
|
||||||
|
@ -660,7 +660,7 @@ void LocalStore::removeUnusedLinks(const GCState & state)
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st) == -1)
|
if (lstat(path.c_str(), &st) == -1)
|
||||||
throw SysError(format("statting '%1%'") % path);
|
throw SysError(format("statting ‘%1%’") % path);
|
||||||
|
|
||||||
if (st.st_nlink != 1) {
|
if (st.st_nlink != 1) {
|
||||||
unsigned long long size = st.st_blocks * 512ULL;
|
unsigned long long size = st.st_blocks * 512ULL;
|
||||||
|
@ -669,17 +669,17 @@ void LocalStore::removeUnusedLinks(const GCState & state)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
printMsg(lvlTalkative, format("deleting unused link '%1%'") % path);
|
printMsg(lvlTalkative, format("deleting unused link ‘%1%’") % path);
|
||||||
|
|
||||||
if (unlink(path.c_str()) == -1)
|
if (unlink(path.c_str()) == -1)
|
||||||
throw SysError(format("deleting '%1%'") % path);
|
throw SysError(format("deleting ‘%1%’") % path);
|
||||||
|
|
||||||
state.results.bytesFreed += st.st_blocks * 512;
|
state.results.bytesFreed += st.st_blocks * 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(linksDir.c_str(), &st) == -1)
|
if (stat(linksDir.c_str(), &st) == -1)
|
||||||
throw SysError(format("statting '%1%'") % linksDir);
|
throw SysError(format("statting ‘%1%’") % linksDir);
|
||||||
long long overhead = st.st_blocks * 512ULL;
|
long long overhead = st.st_blocks * 512ULL;
|
||||||
|
|
||||||
printInfo(format("note: currently hard linking saves %.2f MiB")
|
printInfo(format("note: currently hard linking saves %.2f MiB")
|
||||||
|
@ -759,7 +759,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
assertStorePath(i);
|
assertStorePath(i);
|
||||||
tryToDelete(state, i);
|
tryToDelete(state, i);
|
||||||
if (state.dead.find(i) == state.dead.end())
|
if (state.dead.find(i) == state.dead.end())
|
||||||
throw Error(format("cannot delete path '%1%' since it is still alive") % i);
|
throw Error(format("cannot delete path ‘%1%’ since it is still alive") % i);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (options.maxFreed > 0) {
|
} else if (options.maxFreed > 0) {
|
||||||
|
@ -772,7 +772,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
try {
|
try {
|
||||||
|
|
||||||
AutoCloseDir dir = opendir(realStoreDir.c_str());
|
AutoCloseDir dir = opendir(realStoreDir.c_str());
|
||||||
if (!dir) throw SysError(format("opening directory '%1%'") % realStoreDir);
|
if (!dir) throw SysError(format("opening directory ‘%1%’") % realStoreDir);
|
||||||
|
|
||||||
/* Read the store and immediately delete all paths that
|
/* Read the store and immediately delete all paths that
|
||||||
aren't valid. When using --max-freed etc., deleting
|
aren't valid. When using --max-freed etc., deleting
|
||||||
|
@ -825,7 +825,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
fds.clear();
|
fds.clear();
|
||||||
|
|
||||||
/* Delete the trash directory. */
|
/* Delete the trash directory. */
|
||||||
printInfo(format("deleting '%1%'") % trashDir);
|
printInfo(format("deleting ‘%1%’") % trashDir);
|
||||||
deleteGarbage(state, trashDir);
|
deleteGarbage(state, trashDir);
|
||||||
|
|
||||||
/* Clean up the links directory. */
|
/* Clean up the links directory. */
|
||||||
|
|
|
@ -103,7 +103,7 @@ void Settings::loadConfFile()
|
||||||
if (tokens.empty()) continue;
|
if (tokens.empty()) continue;
|
||||||
|
|
||||||
if (tokens.size() < 2 || tokens[1] != "=")
|
if (tokens.size() < 2 || tokens[1] != "=")
|
||||||
throw Error(format("illegal configuration line '%1%' in '%2%'") % line % settingsFile);
|
throw Error(format("illegal configuration line ‘%1%’ in ‘%2%’") % line % settingsFile);
|
||||||
|
|
||||||
string name = tokens[0];
|
string name = tokens[0];
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ void Settings::_get(bool & res, const string & name)
|
||||||
if (i == settings.end()) return;
|
if (i == settings.end()) return;
|
||||||
if (i->second == "true") res = true;
|
if (i->second == "true") res = true;
|
||||||
else if (i->second == "false") res = false;
|
else if (i->second == "false") res = false;
|
||||||
else throw Error(format("configuration option '%1%' should be either 'true' or 'false', not '%2%'")
|
else throw Error(format("configuration option ‘%1%’ should be either ‘true’ or ‘false’, not ‘%2%’")
|
||||||
% name % i->second);
|
% name % i->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ template<class N> void Settings::_get(N & res, const string & name)
|
||||||
SettingsMap::iterator i = settings.find(name);
|
SettingsMap::iterator i = settings.find(name);
|
||||||
if (i == settings.end()) return;
|
if (i == settings.end()) return;
|
||||||
if (!string2Int(i->second, res))
|
if (!string2Int(i->second, res))
|
||||||
throw Error(format("configuration setting '%1%' should have an integer value") % name);
|
throw Error(format("configuration setting ‘%1%’ should have an integer value") % name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
try {
|
try {
|
||||||
BinaryCacheStore::init();
|
BinaryCacheStore::init();
|
||||||
} catch (UploadToHTTP &) {
|
} catch (UploadToHTTP &) {
|
||||||
throw Error(format("'%s' does not appear to be a binary cache") % cacheUri);
|
throw Error(format("‘%s’ does not appear to be a binary cache") % cacheUri);
|
||||||
}
|
}
|
||||||
diskCache->createCache(cacheUri, storeDir, wantMassQuery_, priority);
|
diskCache->createCache(cacheUri, storeDir, wantMassQuery_, priority);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ static void atomicWrite(const Path & path, const std::string & s)
|
||||||
AutoDelete del(tmp, false);
|
AutoDelete del(tmp, false);
|
||||||
writeFile(tmp, s);
|
writeFile(tmp, s);
|
||||||
if (rename(tmp.c_str(), path.c_str()))
|
if (rename(tmp.c_str(), path.c_str()))
|
||||||
throw SysError(format("renaming '%1%' to '%2%'") % tmp % path);
|
throw SysError(format("renaming ‘%1%’ to ‘%2%’") % tmp % path);
|
||||||
del.cancel();
|
del.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ struct LocalStoreAccessor : public FSAccessor
|
||||||
{
|
{
|
||||||
Path storePath = store->toStorePath(path);
|
Path storePath = store->toStorePath(path);
|
||||||
if (!store->isValidPath(storePath))
|
if (!store->isValidPath(storePath))
|
||||||
throw InvalidPath(format("path '%1%' is not a valid store path") % storePath);
|
throw InvalidPath(format("path ‘%1%’ is not a valid store path") % storePath);
|
||||||
return store->getRealStoreDir() + std::string(path, store->storeDir.size());
|
return store->getRealStoreDir() + std::string(path, store->storeDir.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,11 +34,11 @@ struct LocalStoreAccessor : public FSAccessor
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st)) {
|
if (lstat(path.c_str(), &st)) {
|
||||||
if (errno == ENOENT || errno == ENOTDIR) return {Type::tMissing, 0, false};
|
if (errno == ENOENT || errno == ENOTDIR) return {Type::tMissing, 0, false};
|
||||||
throw SysError(format("getting status of '%1%'") % path);
|
throw SysError(format("getting status of ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode))
|
if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode))
|
||||||
throw Error(format("file '%1%' has unsupported type") % path);
|
throw Error(format("file ‘%1%’ has unsupported type") % path);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
S_ISREG(st.st_mode) ? Type::tRegular :
|
S_ISREG(st.st_mode) ? Type::tRegular :
|
||||||
|
@ -80,7 +80,7 @@ ref<FSAccessor> LocalFSStore::getFSAccessor()
|
||||||
void LocalFSStore::narFromPath(const Path & path, Sink & sink)
|
void LocalFSStore::narFromPath(const Path & path, Sink & sink)
|
||||||
{
|
{
|
||||||
if (!isValidPath(path))
|
if (!isValidPath(path))
|
||||||
throw Error(format("path '%s' is not valid") % path);
|
throw Error(format("path ‘%s’ is not valid") % path);
|
||||||
dumpPath(getRealStoreDir() + std::string(path, storeDir.size()), sink);
|
dumpPath(getRealStoreDir() + std::string(path, storeDir.size()), sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,24 +71,24 @@ LocalStore::LocalStore(const Params & params)
|
||||||
Path perUserDir = profilesDir + "/per-user";
|
Path perUserDir = profilesDir + "/per-user";
|
||||||
createDirs(perUserDir);
|
createDirs(perUserDir);
|
||||||
if (chmod(perUserDir.c_str(), 01777) == -1)
|
if (chmod(perUserDir.c_str(), 01777) == -1)
|
||||||
throw SysError(format("could not set permissions on '%1%' to 1777") % perUserDir);
|
throw SysError(format("could not set permissions on ‘%1%’ to 1777") % perUserDir);
|
||||||
|
|
||||||
mode_t perm = 01775;
|
mode_t perm = 01775;
|
||||||
|
|
||||||
struct group * gr = getgrnam(settings.buildUsersGroup.c_str());
|
struct group * gr = getgrnam(settings.buildUsersGroup.c_str());
|
||||||
if (!gr)
|
if (!gr)
|
||||||
printError(format("warning: the group '%1%' specified in 'build-users-group' does not exist")
|
printError(format("warning: the group ‘%1%’ specified in ‘build-users-group’ does not exist")
|
||||||
% settings.buildUsersGroup);
|
% settings.buildUsersGroup);
|
||||||
else {
|
else {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(realStoreDir.c_str(), &st))
|
if (stat(realStoreDir.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % realStoreDir);
|
throw SysError(format("getting attributes of path ‘%1%’") % realStoreDir);
|
||||||
|
|
||||||
if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) {
|
if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) {
|
||||||
if (chown(realStoreDir.c_str(), 0, gr->gr_gid) == -1)
|
if (chown(realStoreDir.c_str(), 0, gr->gr_gid) == -1)
|
||||||
throw SysError(format("changing ownership of path '%1%'") % realStoreDir);
|
throw SysError(format("changing ownership of path ‘%1%’") % realStoreDir);
|
||||||
if (chmod(realStoreDir.c_str(), perm) == -1)
|
if (chmod(realStoreDir.c_str(), perm) == -1)
|
||||||
throw SysError(format("changing permissions on path '%1%'") % realStoreDir);
|
throw SysError(format("changing permissions on path ‘%1%’") % realStoreDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,10 +99,10 @@ LocalStore::LocalStore(const Params & params)
|
||||||
struct stat st;
|
struct stat st;
|
||||||
while (path != "/") {
|
while (path != "/") {
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting status of '%1%'") % path);
|
throw SysError(format("getting status of ‘%1%’") % path);
|
||||||
if (S_ISLNK(st.st_mode))
|
if (S_ISLNK(st.st_mode))
|
||||||
throw Error(format(
|
throw Error(format(
|
||||||
"the path '%1%' is a symlink; "
|
"the path ‘%1%’ is a symlink; "
|
||||||
"this is not allowed for the Nix store and its parent directories")
|
"this is not allowed for the Nix store and its parent directories")
|
||||||
% path);
|
% path);
|
||||||
path = dirOf(path);
|
path = dirOf(path);
|
||||||
|
@ -262,7 +262,7 @@ int LocalStore::getSchema()
|
||||||
if (pathExists(schemaPath)) {
|
if (pathExists(schemaPath)) {
|
||||||
string s = readFile(schemaPath);
|
string s = readFile(schemaPath);
|
||||||
if (!string2Int(s, curSchema))
|
if (!string2Int(s, curSchema))
|
||||||
throw Error(format("'%1%' is corrupt") % schemaPath);
|
throw Error(format("‘%1%’ is corrupt") % schemaPath);
|
||||||
}
|
}
|
||||||
return curSchema;
|
return curSchema;
|
||||||
}
|
}
|
||||||
|
@ -271,14 +271,14 @@ int LocalStore::getSchema()
|
||||||
void LocalStore::openDB(State & state, bool create)
|
void LocalStore::openDB(State & state, bool create)
|
||||||
{
|
{
|
||||||
if (access(dbDir.c_str(), R_OK | W_OK))
|
if (access(dbDir.c_str(), R_OK | W_OK))
|
||||||
throw SysError(format("Nix database directory '%1%' is not writable") % dbDir);
|
throw SysError(format("Nix database directory ‘%1%’ is not writable") % dbDir);
|
||||||
|
|
||||||
/* Open the Nix database. */
|
/* Open the Nix database. */
|
||||||
string dbPath = dbDir + "/db.sqlite";
|
string dbPath = dbDir + "/db.sqlite";
|
||||||
auto & db(state.db);
|
auto & db(state.db);
|
||||||
if (sqlite3_open_v2(dbPath.c_str(), &db.db,
|
if (sqlite3_open_v2(dbPath.c_str(), &db.db,
|
||||||
SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
|
SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
|
||||||
throw Error(format("cannot open Nix database '%1%'") % dbPath);
|
throw Error(format("cannot open Nix database ‘%1%’") % dbPath);
|
||||||
|
|
||||||
if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK)
|
if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK)
|
||||||
throwSQLiteError(db, "setting timeout");
|
throwSQLiteError(db, "setting timeout");
|
||||||
|
@ -363,7 +363,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
|
||||||
| 0444
|
| 0444
|
||||||
| (st.st_mode & S_IXUSR ? 0111 : 0);
|
| (st.st_mode & S_IXUSR ? 0111 : 0);
|
||||||
if (chmod(path.c_str(), mode) == -1)
|
if (chmod(path.c_str(), mode) == -1)
|
||||||
throw SysError(format("changing mode of '%1%' to %2$o") % path % mode);
|
throw SysError(format("changing mode of ‘%1%’ to %2$o") % path % mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -381,7 +381,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
|
||||||
#else
|
#else
|
||||||
if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1)
|
if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1)
|
||||||
#endif
|
#endif
|
||||||
throw SysError(format("changing modification time of '%1%'") % path);
|
throw SysError(format("changing modification time of ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,7 +390,7 @@ void canonicaliseTimestampAndPermissions(const Path & path)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError(format("getting attributes of path ‘%1%’") % path);
|
||||||
canonicaliseTimestampAndPermissions(path, st);
|
canonicaliseTimestampAndPermissions(path, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,11 +401,11 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError(format("getting attributes of path ‘%1%’") % path);
|
||||||
|
|
||||||
/* Really make sure that the path is of a supported type. */
|
/* Really make sure that the path is of a supported type. */
|
||||||
if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)))
|
if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)))
|
||||||
throw Error(format("file '%1%' has an unsupported type") % path);
|
throw Error(format("file ‘%1%’ has an unsupported type") % path);
|
||||||
|
|
||||||
/* Fail if the file is not owned by the build user. This prevents
|
/* Fail if the file is not owned by the build user. This prevents
|
||||||
us from messing up the ownership/permissions of files
|
us from messing up the ownership/permissions of files
|
||||||
|
@ -416,7 +416,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
|
||||||
if (fromUid != (uid_t) -1 && st.st_uid != fromUid) {
|
if (fromUid != (uid_t) -1 && st.st_uid != fromUid) {
|
||||||
assert(!S_ISDIR(st.st_mode));
|
assert(!S_ISDIR(st.st_mode));
|
||||||
if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end())
|
if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end())
|
||||||
throw BuildError(format("invalid ownership on file '%1%'") % path);
|
throw BuildError(format("invalid ownership on file ‘%1%’") % path);
|
||||||
mode_t mode = st.st_mode & ~S_IFMT;
|
mode_t mode = st.st_mode & ~S_IFMT;
|
||||||
assert(S_ISLNK(st.st_mode) || (st.st_uid == geteuid() && (mode == 0444 || mode == 0555) && st.st_mtime == mtimeStore));
|
assert(S_ISLNK(st.st_mode) || (st.st_uid == geteuid() && (mode == 0444 || mode == 0555) && st.st_mtime == mtimeStore));
|
||||||
return;
|
return;
|
||||||
|
@ -440,7 +440,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
|
||||||
if (!S_ISLNK(st.st_mode) &&
|
if (!S_ISLNK(st.st_mode) &&
|
||||||
chown(path.c_str(), geteuid(), getegid()) == -1)
|
chown(path.c_str(), geteuid(), getegid()) == -1)
|
||||||
#endif
|
#endif
|
||||||
throw SysError(format("changing owner of '%1%' to %2%")
|
throw SysError(format("changing owner of ‘%1%’ to %2%")
|
||||||
% path % geteuid());
|
% path % geteuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,11 +460,11 @@ void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & ino
|
||||||
be a symlink, since we can't change its ownership. */
|
be a symlink, since we can't change its ownership. */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError(format("getting attributes of path ‘%1%’") % path);
|
||||||
|
|
||||||
if (st.st_uid != geteuid()) {
|
if (st.st_uid != geteuid()) {
|
||||||
assert(S_ISLNK(st.st_mode));
|
assert(S_ISLNK(st.st_mode));
|
||||||
throw Error(format("wrong ownership of top-level store path '%1%'") % path);
|
throw Error(format("wrong ownership of top-level store path ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,7 +485,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
|
||||||
if (drv.isFixedOutput()) {
|
if (drv.isFixedOutput()) {
|
||||||
DerivationOutputs::const_iterator out = drv.outputs.find("out");
|
DerivationOutputs::const_iterator out = drv.outputs.find("out");
|
||||||
if (out == drv.outputs.end())
|
if (out == drv.outputs.end())
|
||||||
throw Error(format("derivation '%1%' does not have an output named 'out'") % drvPath);
|
throw Error(format("derivation ‘%1%’ does not have an output named ‘out’") % drvPath);
|
||||||
|
|
||||||
bool recursive; Hash h;
|
bool recursive; Hash h;
|
||||||
out->second.parseHashInfo(recursive, h);
|
out->second.parseHashInfo(recursive, h);
|
||||||
|
@ -493,7 +493,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
|
||||||
|
|
||||||
StringPairs::const_iterator j = drv.env.find("out");
|
StringPairs::const_iterator j = drv.env.find("out");
|
||||||
if (out->second.path != outPath || j == drv.env.end() || j->second != outPath)
|
if (out->second.path != outPath || j == drv.env.end() || j->second != outPath)
|
||||||
throw Error(format("derivation '%1%' has incorrect output '%2%', should be '%3%'")
|
throw Error(format("derivation ‘%1%’ has incorrect output ‘%2%’, should be ‘%3%’")
|
||||||
% drvPath % out->second.path % outPath);
|
% drvPath % out->second.path % outPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,7 +510,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
|
||||||
Path outPath = makeOutputPath(i.first, h, drvName);
|
Path outPath = makeOutputPath(i.first, h, drvName);
|
||||||
StringPairs::const_iterator j = drv.env.find(i.first);
|
StringPairs::const_iterator j = drv.env.find(i.first);
|
||||||
if (i.second.path != outPath || j == drv.env.end() || j->second != outPath)
|
if (i.second.path != outPath || j == drv.env.end() || j->second != outPath)
|
||||||
throw Error(format("derivation '%1%' has incorrect output '%2%', should be '%3%'")
|
throw Error(format("derivation ‘%1%’ has incorrect output ‘%2%’, should be ‘%3%’")
|
||||||
% drvPath % i.second.path % outPath);
|
% drvPath % i.second.path % outPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,11 +568,11 @@ Hash parseHashField(const Path & path, const string & s)
|
||||||
{
|
{
|
||||||
string::size_type colon = s.find(':');
|
string::size_type colon = s.find(':');
|
||||||
if (colon == string::npos)
|
if (colon == string::npos)
|
||||||
throw Error(format("corrupt hash '%1%' in valid-path entry for '%2%'")
|
throw Error(format("corrupt hash ‘%1%’ in valid-path entry for ‘%2%’")
|
||||||
% s % path);
|
% s % path);
|
||||||
HashType ht = parseHashType(string(s, 0, colon));
|
HashType ht = parseHashType(string(s, 0, colon));
|
||||||
if (ht == htUnknown)
|
if (ht == htUnknown)
|
||||||
throw Error(format("unknown hash type '%1%' in valid-path entry for '%2%'")
|
throw Error(format("unknown hash type ‘%1%’ in valid-path entry for ‘%2%’")
|
||||||
% string(s, 0, colon) % path);
|
% string(s, 0, colon) % path);
|
||||||
return parseHash(ht, string(s, colon + 1));
|
return parseHash(ht, string(s, colon + 1));
|
||||||
}
|
}
|
||||||
|
@ -648,7 +648,7 @@ uint64_t LocalStore::queryValidPathId(State & state, const Path & path)
|
||||||
{
|
{
|
||||||
auto use(state.stmtQueryPathInfo.use()(path));
|
auto use(state.stmtQueryPathInfo.use()(path));
|
||||||
if (!use.next())
|
if (!use.next())
|
||||||
throw Error(format("path '%1%' is not valid") % path);
|
throw Error(format("path ‘%1%’ is not valid") % path);
|
||||||
return use.getInt(0);
|
return use.getInt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,7 +815,7 @@ void LocalStore::querySubstitutablePathInfos(const PathSet & paths,
|
||||||
if (sub->storeDir != storeDir) continue;
|
if (sub->storeDir != storeDir) continue;
|
||||||
for (auto & path : paths) {
|
for (auto & path : paths) {
|
||||||
if (infos.count(path)) continue;
|
if (infos.count(path)) continue;
|
||||||
debug(format("checking substituter '%s' for path '%s'")
|
debug(format("checking substituter ‘%s’ for path ‘%s’")
|
||||||
% sub->getUri() % path);
|
% sub->getUri() % path);
|
||||||
try {
|
try {
|
||||||
auto info = sub->queryPathInfo(path);
|
auto info = sub->queryPathInfo(path);
|
||||||
|
@ -896,7 +896,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
|
||||||
there are no referrers. */
|
there are no referrers. */
|
||||||
void LocalStore::invalidatePath(State & state, const Path & path)
|
void LocalStore::invalidatePath(State & state, const Path & path)
|
||||||
{
|
{
|
||||||
debug(format("invalidating path '%1%'") % path);
|
debug(format("invalidating path ‘%1%’") % path);
|
||||||
|
|
||||||
state.stmtInvalidatePath.use()(path).exec();
|
state.stmtInvalidatePath.use()(path).exec();
|
||||||
|
|
||||||
|
@ -915,11 +915,11 @@ void LocalStore::addToStore(const ValidPathInfo & info, const ref<std::string> &
|
||||||
{
|
{
|
||||||
Hash h = hashString(htSHA256, *nar);
|
Hash h = hashString(htSHA256, *nar);
|
||||||
if (h != info.narHash)
|
if (h != info.narHash)
|
||||||
throw Error(format("hash mismatch importing path '%s'; expected hash '%s', got '%s'") %
|
throw Error(format("hash mismatch importing path ‘%s’; expected hash ‘%s’, got ‘%s’") %
|
||||||
info.path % info.narHash.to_string() % h.to_string());
|
info.path % info.narHash.to_string() % h.to_string());
|
||||||
|
|
||||||
if (requireSigs && !dontCheckSigs && !info.checkSignatures(*this, publicKeys))
|
if (requireSigs && !dontCheckSigs && !info.checkSignatures(*this, publicKeys))
|
||||||
throw Error(format("cannot import path '%s' because it lacks a valid signature") % info.path);
|
throw Error(format("cannot import path ‘%s’ because it lacks a valid signature") % info.path);
|
||||||
|
|
||||||
addTempRoot(info.path);
|
addTempRoot(info.path);
|
||||||
|
|
||||||
|
@ -1106,7 +1106,7 @@ void LocalStore::invalidatePathChecked(const Path & path)
|
||||||
PathSet referrers; queryReferrers(*state, path, referrers);
|
PathSet referrers; queryReferrers(*state, path, referrers);
|
||||||
referrers.erase(path); /* ignore self-references */
|
referrers.erase(path); /* ignore self-references */
|
||||||
if (!referrers.empty())
|
if (!referrers.empty())
|
||||||
throw PathInUse(format("cannot delete path '%1%' because it is in use by %2%")
|
throw PathInUse(format("cannot delete path ‘%1%’ because it is in use by %2%")
|
||||||
% path % showPaths(referrers));
|
% path % showPaths(referrers));
|
||||||
invalidatePath(*state, path);
|
invalidatePath(*state, path);
|
||||||
}
|
}
|
||||||
|
@ -1151,12 +1151,12 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
|
||||||
auto info = std::const_pointer_cast<ValidPathInfo>(std::shared_ptr<const ValidPathInfo>(queryPathInfo(i)));
|
auto info = std::const_pointer_cast<ValidPathInfo>(std::shared_ptr<const ValidPathInfo>(queryPathInfo(i)));
|
||||||
|
|
||||||
/* Check the content hash (optionally - slow). */
|
/* Check the content hash (optionally - slow). */
|
||||||
printMsg(lvlTalkative, format("checking contents of '%1%'") % i);
|
printMsg(lvlTalkative, format("checking contents of ‘%1%’") % i);
|
||||||
HashResult current = hashPath(info->narHash.type, i);
|
HashResult current = hashPath(info->narHash.type, i);
|
||||||
|
|
||||||
if (info->narHash != nullHash && info->narHash != current.first) {
|
if (info->narHash != nullHash && info->narHash != current.first) {
|
||||||
printError(format("path '%1%' was modified! "
|
printError(format("path ‘%1%’ was modified! "
|
||||||
"expected hash '%2%', got '%3%'")
|
"expected hash ‘%2%’, got ‘%3%’")
|
||||||
% i % printHash(info->narHash) % printHash(current.first));
|
% i % printHash(info->narHash) % printHash(current.first));
|
||||||
if (repair) repairPath(i); else errors = true;
|
if (repair) repairPath(i); else errors = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1165,14 +1165,14 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
|
||||||
|
|
||||||
/* Fill in missing hashes. */
|
/* Fill in missing hashes. */
|
||||||
if (info->narHash == nullHash) {
|
if (info->narHash == nullHash) {
|
||||||
printError(format("fixing missing hash on '%1%'") % i);
|
printError(format("fixing missing hash on ‘%1%’") % i);
|
||||||
info->narHash = current.first;
|
info->narHash = current.first;
|
||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill in missing narSize fields (from old stores). */
|
/* Fill in missing narSize fields (from old stores). */
|
||||||
if (info->narSize == 0) {
|
if (info->narSize == 0) {
|
||||||
printError(format("updating size field on '%1%' to %2%") % i % current.second);
|
printError(format("updating size field on ‘%1%’ to %2%") % i % current.second);
|
||||||
info->narSize = current.second;
|
info->narSize = current.second;
|
||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
|
@ -1209,7 +1209,7 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
|
||||||
done.insert(path);
|
done.insert(path);
|
||||||
|
|
||||||
if (!isStorePath(path)) {
|
if (!isStorePath(path)) {
|
||||||
printError(format("path '%1%' is not in the Nix store") % path);
|
printError(format("path ‘%1%’ is not in the Nix store") % path);
|
||||||
auto state(_state.lock());
|
auto state(_state.lock());
|
||||||
invalidatePath(*state, path);
|
invalidatePath(*state, path);
|
||||||
return;
|
return;
|
||||||
|
@ -1228,11 +1228,11 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canInvalidate) {
|
if (canInvalidate) {
|
||||||
printError(format("path '%1%' disappeared, removing from database...") % path);
|
printError(format("path ‘%1%’ disappeared, removing from database...") % path);
|
||||||
auto state(_state.lock());
|
auto state(_state.lock());
|
||||||
invalidatePath(*state, path);
|
invalidatePath(*state, path);
|
||||||
} else {
|
} else {
|
||||||
printError(format("path '%1%' disappeared, but it still has valid referrers!") % path);
|
printError(format("path ‘%1%’ disappeared, but it still has valid referrers!") % path);
|
||||||
if (repair)
|
if (repair)
|
||||||
try {
|
try {
|
||||||
repairPath(path);
|
repairPath(path);
|
||||||
|
@ -1271,7 +1271,7 @@ static void makeMutable(const Path & path)
|
||||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
|
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
if (errno == ELOOP) return; // it's a symlink
|
if (errno == ELOOP) return; // it's a symlink
|
||||||
throw SysError(format("opening file '%1%'") % path);
|
throw SysError(format("opening file ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int flags = 0, old;
|
unsigned int flags = 0, old;
|
||||||
|
|
|
@ -261,7 +261,7 @@ private:
|
||||||
void queryReferrers(State & state, const Path & path, PathSet & referrers);
|
void queryReferrers(State & state, const Path & path, PathSet & referrers);
|
||||||
|
|
||||||
/* Add signatures to a ValidPathInfo using the secret keys
|
/* Add signatures to a ValidPathInfo using the secret keys
|
||||||
specified by the 'secret-key-files' option. */
|
specified by the ‘secret-key-files’ option. */
|
||||||
void signPathInfo(ValidPathInfo & info);
|
void signPathInfo(ValidPathInfo & info);
|
||||||
|
|
||||||
Path getRealStoreDir() override { return realStoreDir; }
|
Path getRealStoreDir() override { return realStoreDir; }
|
||||||
|
|
|
@ -245,7 +245,7 @@ Paths Store::topoSortPaths(const PathSet & paths)
|
||||||
|
|
||||||
dfsVisit = [&](const Path & path, const Path * parent) {
|
dfsVisit = [&](const Path & path, const Path * parent) {
|
||||||
if (parents.find(path) != parents.end())
|
if (parents.find(path) != parents.end())
|
||||||
throw BuildError(format("cycle detected in the references of '%1%' from '%2%'") % path % *parent);
|
throw BuildError(format("cycle detected in the references of ‘%1%’ from ‘%2%’") % path % *parent);
|
||||||
|
|
||||||
if (visited.find(path) != visited.end()) return;
|
if (visited.find(path) != visited.end()) return;
|
||||||
visited.insert(path);
|
visited.insert(path);
|
||||||
|
|
|
@ -75,7 +75,7 @@ struct NarIndexer : ParseSink, StringSource
|
||||||
{
|
{
|
||||||
auto i = members.find(path);
|
auto i = members.find(path);
|
||||||
if (i == members.end())
|
if (i == members.end())
|
||||||
throw Error(format("NAR file does not contain path '%1%'") % path);
|
throw Error(format("NAR file does not contain path ‘%1%’") % path);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -103,7 +103,7 @@ struct NarAccessor : public FSAccessor
|
||||||
auto i = indexer.find(path);
|
auto i = indexer.find(path);
|
||||||
|
|
||||||
if (i->second.type != FSAccessor::Type::tDirectory)
|
if (i->second.type != FSAccessor::Type::tDirectory)
|
||||||
throw Error(format("path '%1%' inside NAR file is not a directory") % path);
|
throw Error(format("path ‘%1%’ inside NAR file is not a directory") % path);
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
StringSet res;
|
StringSet res;
|
||||||
|
@ -120,7 +120,7 @@ struct NarAccessor : public FSAccessor
|
||||||
{
|
{
|
||||||
auto i = indexer.find(path);
|
auto i = indexer.find(path);
|
||||||
if (i->second.type != FSAccessor::Type::tRegular)
|
if (i->second.type != FSAccessor::Type::tRegular)
|
||||||
throw Error(format("path '%1%' inside NAR file is not a regular file") % path);
|
throw Error(format("path ‘%1%’ inside NAR file is not a regular file") % path);
|
||||||
return std::string(*nar, i->second.start, i->second.size);
|
return std::string(*nar, i->second.start, i->second.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ struct NarAccessor : public FSAccessor
|
||||||
{
|
{
|
||||||
auto i = indexer.find(path);
|
auto i = indexer.find(path);
|
||||||
if (i->second.type != FSAccessor::Type::tSymlink)
|
if (i->second.type != FSAccessor::Type::tSymlink)
|
||||||
throw Error(format("path '%1%' inside NAR file is not a symlink") % path);
|
throw Error(format("path ‘%1%’ inside NAR file is not a symlink") % path);
|
||||||
return i->second.target;
|
return i->second.target;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace nix {
|
||||||
NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & whence)
|
NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & whence)
|
||||||
{
|
{
|
||||||
auto corrupt = [&]() {
|
auto corrupt = [&]() {
|
||||||
throw Error(format("NAR info file '%1%' is corrupt") % whence);
|
throw Error(format("NAR info file ‘%1%’ is corrupt") % whence);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto parseHashField = [&](const string & s) {
|
auto parseHashField = [&](const string & s) {
|
||||||
|
|
|
@ -20,9 +20,9 @@ static void makeWritable(const Path & path)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError(format("getting attributes of path ‘%1%’") % path);
|
||||||
if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
|
if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
|
||||||
throw SysError(format("changing writability of '%1%'") % path);
|
throw SysError(format("changing writability of ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
|
||||||
InodeHash inodeHash;
|
InodeHash inodeHash;
|
||||||
|
|
||||||
AutoCloseDir dir = opendir(linksDir.c_str());
|
AutoCloseDir dir = opendir(linksDir.c_str());
|
||||||
if (!dir) throw SysError(format("opening directory '%1%'") % linksDir);
|
if (!dir) throw SysError(format("opening directory ‘%1%’") % linksDir);
|
||||||
|
|
||||||
struct dirent * dirent;
|
struct dirent * dirent;
|
||||||
while (errno = 0, dirent = readdir(dir)) { /* sic */
|
while (errno = 0, dirent = readdir(dir)) { /* sic */
|
||||||
|
@ -56,7 +56,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
|
||||||
// We don't care if we hit non-hash files, anything goes
|
// We don't care if we hit non-hash files, anything goes
|
||||||
inodeHash.insert(dirent->d_ino);
|
inodeHash.insert(dirent->d_ino);
|
||||||
}
|
}
|
||||||
if (errno) throw SysError(format("reading directory '%1%'") % linksDir);
|
if (errno) throw SysError(format("reading directory ‘%1%’") % linksDir);
|
||||||
|
|
||||||
printMsg(lvlTalkative, format("loaded %1% hash inodes") % inodeHash.size());
|
printMsg(lvlTalkative, format("loaded %1% hash inodes") % inodeHash.size());
|
||||||
|
|
||||||
|
@ -69,14 +69,14 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
|
||||||
Strings names;
|
Strings names;
|
||||||
|
|
||||||
AutoCloseDir dir = opendir(path.c_str());
|
AutoCloseDir dir = opendir(path.c_str());
|
||||||
if (!dir) throw SysError(format("opening directory '%1%'") % path);
|
if (!dir) throw SysError(format("opening directory ‘%1%’") % path);
|
||||||
|
|
||||||
struct dirent * dirent;
|
struct dirent * dirent;
|
||||||
while (errno = 0, dirent = readdir(dir)) { /* sic */
|
while (errno = 0, dirent = readdir(dir)) { /* sic */
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
if (inodeHash.count(dirent->d_ino)) {
|
if (inodeHash.count(dirent->d_ino)) {
|
||||||
debug(format("'%1%' is already linked") % dirent->d_name);
|
debug(format("‘%1%’ is already linked") % dirent->d_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
|
||||||
if (name == "." || name == "..") continue;
|
if (name == "." || name == "..") continue;
|
||||||
names.push_back(name);
|
names.push_back(name);
|
||||||
}
|
}
|
||||||
if (errno) throw SysError(format("reading directory '%1%'") % path);
|
if (errno) throw SysError(format("reading directory ‘%1%’") % path);
|
||||||
|
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError(format("getting attributes of path ‘%1%’") % path);
|
||||||
|
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
Strings names = readDirectoryIgnoringInodes(path, inodeHash);
|
Strings names = readDirectoryIgnoringInodes(path, inodeHash);
|
||||||
|
@ -117,13 +117,13 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||||
NixOS (example: $fontconfig/var/cache being modified). Skip
|
NixOS (example: $fontconfig/var/cache being modified). Skip
|
||||||
those files. FIXME: check the modification time. */
|
those files. FIXME: check the modification time. */
|
||||||
if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) {
|
if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) {
|
||||||
printError(format("skipping suspicious writable file '%1%'") % path);
|
printError(format("skipping suspicious writable file ‘%1%’") % path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This can still happen on top-level files. */
|
/* This can still happen on top-level files. */
|
||||||
if (st.st_nlink > 1 && inodeHash.count(st.st_ino)) {
|
if (st.st_nlink > 1 && inodeHash.count(st.st_ino)) {
|
||||||
debug(format("'%1%' is already linked, with %2% other file(s)") % path % (st.st_nlink - 2));
|
debug(format("‘%1%’ is already linked, with %2% other file(s)") % path % (st.st_nlink - 2));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||||
contents of the symlink (i.e. the result of readlink()), not
|
contents of the symlink (i.e. the result of readlink()), not
|
||||||
the contents of the target (which may not even exist). */
|
the contents of the target (which may not even exist). */
|
||||||
Hash hash = hashPath(htSHA256, path).first;
|
Hash hash = hashPath(htSHA256, path).first;
|
||||||
debug(format("'%1%' has hash '%2%'") % path % printHash(hash));
|
debug(format("‘%1%’ has hash ‘%2%’") % path % printHash(hash));
|
||||||
|
|
||||||
/* Check if this is a known hash. */
|
/* Check if this is a known hash. */
|
||||||
Path linkPath = linksDir + "/" + printHash32(hash);
|
Path linkPath = linksDir + "/" + printHash32(hash);
|
||||||
|
@ -152,7 +152,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||||
|
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case EEXIST:
|
case EEXIST:
|
||||||
/* Fall through if another process created 'linkPath' before
|
/* Fall through if another process created ‘linkPath’ before
|
||||||
we did. */
|
we did. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -161,11 +161,11 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||||
full. When that happens, it's fine to ignore it: we
|
full. When that happens, it's fine to ignore it: we
|
||||||
just effectively disable deduplication of this
|
just effectively disable deduplication of this
|
||||||
file. */
|
file. */
|
||||||
printInfo("cannot link '%s' to '%s': %s", linkPath, path, strerror(errno));
|
printInfo("cannot link ‘%s’ to ‘%s’: %s", linkPath, path, strerror(errno));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw SysError("cannot link '%1%' to '%2%'", linkPath, path);
|
throw SysError("cannot link ‘%1%’ to ‘%2%’", linkPath, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,20 +173,20 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||||
current file with a hard link to that file. */
|
current file with a hard link to that file. */
|
||||||
struct stat stLink;
|
struct stat stLink;
|
||||||
if (lstat(linkPath.c_str(), &stLink))
|
if (lstat(linkPath.c_str(), &stLink))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % linkPath);
|
throw SysError(format("getting attributes of path ‘%1%’") % linkPath);
|
||||||
|
|
||||||
if (st.st_ino == stLink.st_ino) {
|
if (st.st_ino == stLink.st_ino) {
|
||||||
debug(format("'%1%' is already linked to '%2%'") % path % linkPath);
|
debug(format("‘%1%’ is already linked to ‘%2%’") % path % linkPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st.st_size != stLink.st_size) {
|
if (st.st_size != stLink.st_size) {
|
||||||
printError(format("removing corrupted link '%1%'") % linkPath);
|
printError(format("removing corrupted link ‘%1%’") % linkPath);
|
||||||
unlink(linkPath.c_str());
|
unlink(linkPath.c_str());
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
printMsg(lvlTalkative, format("linking '%1%' to '%2%'") % path % linkPath);
|
printMsg(lvlTalkative, format("linking ‘%1%’ to ‘%2%’") % path % linkPath);
|
||||||
|
|
||||||
/* Make the containing directory writable, but only if it's not
|
/* Make the containing directory writable, but only if it's not
|
||||||
the store itself (we don't want or need to mess with its
|
the store itself (we don't want or need to mess with its
|
||||||
|
@ -207,26 +207,26 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||||
systems). This is likely to happen with empty files.
|
systems). This is likely to happen with empty files.
|
||||||
Just shrug and ignore. */
|
Just shrug and ignore. */
|
||||||
if (st.st_size)
|
if (st.st_size)
|
||||||
printInfo(format("'%1%' has maximum number of links") % linkPath);
|
printInfo(format("‘%1%’ has maximum number of links") % linkPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw SysError("cannot link '%1%' to '%2%'", tempLink, linkPath);
|
throw SysError("cannot link ‘%1%’ to ‘%2%’", tempLink, linkPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Atomically replace the old file with the new hard link. */
|
/* Atomically replace the old file with the new hard link. */
|
||||||
if (rename(tempLink.c_str(), path.c_str()) == -1) {
|
if (rename(tempLink.c_str(), path.c_str()) == -1) {
|
||||||
if (unlink(tempLink.c_str()) == -1)
|
if (unlink(tempLink.c_str()) == -1)
|
||||||
printError(format("unable to unlink '%1%'") % tempLink);
|
printError(format("unable to unlink ‘%1%’") % tempLink);
|
||||||
if (errno == EMLINK) {
|
if (errno == EMLINK) {
|
||||||
/* Some filesystems generate too many links on the rename,
|
/* Some filesystems generate too many links on the rename,
|
||||||
rather than on the original link. (Probably it
|
rather than on the original link. (Probably it
|
||||||
temporarily increases the st_nlink field before
|
temporarily increases the st_nlink field before
|
||||||
decreasing it again.) */
|
decreasing it again.) */
|
||||||
if (st.st_size)
|
if (st.st_size)
|
||||||
printInfo(format("'%1%' has maximum number of links") % linkPath);
|
printInfo(format("‘%1%’ has maximum number of links") % linkPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw SysError(format("cannot rename '%1%' to '%2%'") % tempLink % path);
|
throw SysError(format("cannot rename ‘%1%’ to ‘%2%’") % tempLink % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
stats.filesLinked++;
|
stats.filesLinked++;
|
||||||
|
@ -243,7 +243,7 @@ void LocalStore::optimiseStore(OptimiseStats & stats)
|
||||||
for (auto & i : paths) {
|
for (auto & i : paths) {
|
||||||
addTempRoot(i);
|
addTempRoot(i);
|
||||||
if (!isValidPath(i)) continue; /* path was GC'ed, probably */
|
if (!isValidPath(i)) continue; /* path was GC'ed, probably */
|
||||||
Activity act(*logger, lvlChatty, format("hashing files in '%1%'") % i);
|
Activity act(*logger, lvlChatty, format("hashing files in ‘%1%’") % i);
|
||||||
optimisePath_(stats, realStoreDir + "/" + baseNameOf(i), inodeHash);
|
optimisePath_(stats, realStoreDir + "/" + baseNameOf(i), inodeHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ int openLockFile(const Path & path, bool create)
|
||||||
|
|
||||||
fd = open(path.c_str(), O_CLOEXEC | O_RDWR | (create ? O_CREAT : 0), 0600);
|
fd = open(path.c_str(), O_CLOEXEC | O_RDWR | (create ? O_CREAT : 0), 0600);
|
||||||
if (!fd && (create || errno != ENOENT))
|
if (!fd && (create || errno != ENOENT))
|
||||||
throw SysError(format("opening lock file '%1%'") % path);
|
throw SysError(format("opening lock file ‘%1%’") % path);
|
||||||
|
|
||||||
return fd.release();
|
return fd.release();
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ bool PathLocks::lockPaths(const PathSet & _paths,
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
Path lockPath = path + ".lock";
|
Path lockPath = path + ".lock";
|
||||||
|
|
||||||
debug(format("locking path '%1%'") % path);
|
debug(format("locking path ‘%1%’") % path);
|
||||||
|
|
||||||
if (lockedPaths.find(lockPath) != lockedPaths.end())
|
if (lockedPaths.find(lockPath) != lockedPaths.end())
|
||||||
throw Error("deadlock: trying to re-acquire self-held lock");
|
throw Error("deadlock: trying to re-acquire self-held lock");
|
||||||
|
@ -131,19 +131,19 @@ bool PathLocks::lockPaths(const PathSet & _paths,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(format("lock acquired on '%1%'") % lockPath);
|
debug(format("lock acquired on ‘%1%’") % lockPath);
|
||||||
|
|
||||||
/* Check that the lock file hasn't become stale (i.e.,
|
/* Check that the lock file hasn't become stale (i.e.,
|
||||||
hasn't been unlinked). */
|
hasn't been unlinked). */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat(fd.get(), &st) == -1)
|
if (fstat(fd.get(), &st) == -1)
|
||||||
throw SysError(format("statting lock file '%1%'") % lockPath);
|
throw SysError(format("statting lock file ‘%1%’") % lockPath);
|
||||||
if (st.st_size != 0)
|
if (st.st_size != 0)
|
||||||
/* This lock file has been unlinked, so we're holding
|
/* This lock file has been unlinked, so we're holding
|
||||||
a lock on a deleted file. This means that other
|
a lock on a deleted file. This means that other
|
||||||
processes may create and acquire a lock on
|
processes may create and acquire a lock on
|
||||||
`lockPath', and proceed. So we must retry. */
|
`lockPath', and proceed. So we must retry. */
|
||||||
debug(format("open lock file '%1%' has become stale") % lockPath);
|
debug(format("open lock file ‘%1%’ has become stale") % lockPath);
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -175,9 +175,9 @@ void PathLocks::unlock()
|
||||||
lockedPaths.erase(i.second);
|
lockedPaths.erase(i.second);
|
||||||
if (close(i.first) == -1)
|
if (close(i.first) == -1)
|
||||||
printError(
|
printError(
|
||||||
format("error (ignored): cannot close lock file on '%1%'") % i.second);
|
format("error (ignored): cannot close lock file on ‘%1%’") % i.second);
|
||||||
|
|
||||||
debug(format("lock released on '%1%'") % i.second);
|
debug(format("lock released on ‘%1%’") % i.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
fds.clear();
|
fds.clear();
|
||||||
|
|
|
@ -50,7 +50,7 @@ Generations findGenerations(Path profile, int & curGen)
|
||||||
gen.number = n;
|
gen.number = n;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(gen.path.c_str(), &st) != 0)
|
if (lstat(gen.path.c_str(), &st) != 0)
|
||||||
throw SysError(format("statting '%1%'") % gen.path);
|
throw SysError(format("statting ‘%1%’") % gen.path);
|
||||||
gen.creationTime = st.st_mtime;
|
gen.creationTime = st.st_mtime;
|
||||||
gens.push_back(gen);
|
gens.push_back(gen);
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ Path createGeneration(ref<LocalFSStore> store, Path profile, Path outPath)
|
||||||
static void removeFile(const Path & path)
|
static void removeFile(const Path & path)
|
||||||
{
|
{
|
||||||
if (remove(path.c_str()) == -1)
|
if (remove(path.c_str()) == -1)
|
||||||
throw SysError(format("cannot unlink '%1%'") % path);
|
throw SysError(format("cannot unlink ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ void deleteGenerations(const Path & profile, const std::set<unsigned int> & gens
|
||||||
Generations gens = findGenerations(profile, curGen);
|
Generations gens = findGenerations(profile, curGen);
|
||||||
|
|
||||||
if (gensToDelete.find(curGen) != gensToDelete.end())
|
if (gensToDelete.find(curGen) != gensToDelete.end())
|
||||||
throw Error(format("cannot delete current generation of profile %1%'") % profile);
|
throw Error(format("cannot delete current generation of profile %1%’") % profile);
|
||||||
|
|
||||||
for (auto & i : gens) {
|
for (auto & i : gens) {
|
||||||
if (gensToDelete.find(i.number) == gensToDelete.end()) continue;
|
if (gensToDelete.find(i.number) == gensToDelete.end()) continue;
|
||||||
|
@ -203,7 +203,7 @@ void deleteGenerationsOlderThan(const Path & profile, const string & timeSpec, b
|
||||||
int days;
|
int days;
|
||||||
|
|
||||||
if (!string2Int(strDays, days) || days < 1)
|
if (!string2Int(strDays, days) || days < 1)
|
||||||
throw Error(format("invalid number of days specifier '%1%'") % timeSpec);
|
throw Error(format("invalid number of days specifier ‘%1%’") % timeSpec);
|
||||||
|
|
||||||
time_t oldTime = curTime - days * 24 * 3600;
|
time_t oldTime = curTime - days * 24 * 3600;
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ void switchLink(Path link, Path target)
|
||||||
|
|
||||||
void lockProfile(PathLocks & lock, const Path & profile)
|
void lockProfile(PathLocks & lock, const Path & profile)
|
||||||
{
|
{
|
||||||
lock.lockPaths({profile}, (format("waiting for lock on profile '%1%'") % profile).str());
|
lock.lockPaths({profile}, (format("waiting for lock on profile ‘%1%’") % profile).str());
|
||||||
lock.setDeletion(true);
|
lock.setDeletion(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ static void search(const unsigned char * s, unsigned int len,
|
||||||
if (!match) continue;
|
if (!match) continue;
|
||||||
string ref((const char *) s + i, refLength);
|
string ref((const char *) s + i, refLength);
|
||||||
if (hashes.find(ref) != hashes.end()) {
|
if (hashes.find(ref) != hashes.end()) {
|
||||||
debug(format("found reference to '%1%' at offset '%2%'")
|
debug(format("found reference to ‘%1%’ at offset ‘%2%’")
|
||||||
% ref % i);
|
% ref % i);
|
||||||
seen.insert(ref);
|
seen.insert(ref);
|
||||||
hashes.erase(ref);
|
hashes.erase(ref);
|
||||||
|
@ -93,7 +93,7 @@ PathSet scanForReferences(const string & path,
|
||||||
string baseName = baseNameOf(i);
|
string baseName = baseNameOf(i);
|
||||||
string::size_type pos = baseName.find('-');
|
string::size_type pos = baseName.find('-');
|
||||||
if (pos == string::npos)
|
if (pos == string::npos)
|
||||||
throw Error(format("bad reference '%1%'") % i);
|
throw Error(format("bad reference ‘%1%’") % i);
|
||||||
string s = string(baseName, 0, pos);
|
string s = string(baseName, 0, pos);
|
||||||
assert(s.size() == refLength);
|
assert(s.size() == refLength);
|
||||||
assert(backMap.find(s) == backMap.end());
|
assert(backMap.find(s) == backMap.end());
|
||||||
|
|
|
@ -17,7 +17,7 @@ std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path & path_)
|
||||||
std::string restPath = std::string(path, storePath.size());
|
std::string restPath = std::string(path, storePath.size());
|
||||||
|
|
||||||
if (!store->isValidPath(storePath))
|
if (!store->isValidPath(storePath))
|
||||||
throw InvalidPath(format("path '%1%' is not a valid store path") % storePath);
|
throw InvalidPath(format("path ‘%1%’ is not a valid store path") % storePath);
|
||||||
|
|
||||||
auto i = nars.find(storePath);
|
auto i = nars.find(storePath);
|
||||||
if (i != nars.end()) return {i->second, restPath};
|
if (i != nars.end()) return {i->second, restPath};
|
||||||
|
|
|
@ -83,11 +83,11 @@ ref<RemoteStore::Connection> UDSRemoteStore::openConnection()
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
addr.sun_family = AF_UNIX;
|
addr.sun_family = AF_UNIX;
|
||||||
if (socketPath.size() + 1 >= sizeof(addr.sun_path))
|
if (socketPath.size() + 1 >= sizeof(addr.sun_path))
|
||||||
throw Error(format("socket path '%1%' is too long") % socketPath);
|
throw Error(format("socket path ‘%1%’ is too long") % socketPath);
|
||||||
strcpy(addr.sun_path, socketPath.c_str());
|
strcpy(addr.sun_path, socketPath.c_str());
|
||||||
|
|
||||||
if (connect(conn->fd.get(), (struct sockaddr *) &addr, sizeof(addr)) == -1)
|
if (connect(conn->fd.get(), (struct sockaddr *) &addr, sizeof(addr)) == -1)
|
||||||
throw SysError(format("cannot connect to daemon at '%1%'") % socketPath);
|
throw SysError(format("cannot connect to daemon at ‘%1%’") % socketPath);
|
||||||
|
|
||||||
conn->from.fd = conn->fd.get();
|
conn->from.fd = conn->fd.get();
|
||||||
conn->to.fd = conn->fd.get();
|
conn->to.fd = conn->fd.get();
|
||||||
|
@ -277,7 +277,7 @@ void RemoteStore::queryPathInfoUncached(const Path & path,
|
||||||
}
|
}
|
||||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 17) {
|
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 17) {
|
||||||
bool valid = readInt(conn->from) != 0;
|
bool valid = readInt(conn->from) != 0;
|
||||||
if (!valid) throw InvalidPath(format("path '%s' is not valid") % path);
|
if (!valid) throw InvalidPath(format("path ‘%s’ is not valid") % path);
|
||||||
}
|
}
|
||||||
auto info = std::make_shared<ValidPathInfo>();
|
auto info = std::make_shared<ValidPathInfo>();
|
||||||
info->path = path;
|
info->path = path;
|
||||||
|
|
|
@ -81,9 +81,9 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
|
|
||||||
if (!res.IsSuccess()) {
|
if (!res.IsSuccess()) {
|
||||||
if (res.GetError().GetErrorType() != Aws::S3::S3Errors::NO_SUCH_BUCKET)
|
if (res.GetError().GetErrorType() != Aws::S3::S3Errors::NO_SUCH_BUCKET)
|
||||||
throw Error(format("AWS error checking bucket '%s': %s") % bucketName % res.GetError().GetMessage());
|
throw Error(format("AWS error checking bucket ‘%s’: %s") % bucketName % res.GetError().GetMessage());
|
||||||
|
|
||||||
checkAws(format("AWS error creating bucket '%s'") % bucketName,
|
checkAws(format("AWS error creating bucket ‘%s’") % bucketName,
|
||||||
client->CreateBucket(
|
client->CreateBucket(
|
||||||
Aws::S3::Model::CreateBucketRequest()
|
Aws::S3::Model::CreateBucketRequest()
|
||||||
.WithBucket(bucketName)
|
.WithBucket(bucketName)
|
||||||
|
@ -132,7 +132,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
if (error.GetErrorType() == Aws::S3::S3Errors::UNKNOWN // FIXME
|
if (error.GetErrorType() == Aws::S3::S3Errors::UNKNOWN // FIXME
|
||||||
&& error.GetMessage().find("404") != std::string::npos)
|
&& error.GetMessage().find("404") != std::string::npos)
|
||||||
return false;
|
return false;
|
||||||
throw Error(format("AWS error fetching '%s': %s") % path % error.GetMessage());
|
throw Error(format("AWS error fetching ‘%s’: %s") % path % error.GetMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -154,14 +154,14 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
|
|
||||||
auto now1 = std::chrono::steady_clock::now();
|
auto now1 = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
auto result = checkAws(format("AWS error uploading '%s'") % path,
|
auto result = checkAws(format("AWS error uploading ‘%s’") % path,
|
||||||
client->PutObject(request));
|
client->PutObject(request));
|
||||||
|
|
||||||
auto now2 = std::chrono::steady_clock::now();
|
auto now2 = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now2 - now1).count();
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now2 - now1).count();
|
||||||
|
|
||||||
printInfo(format("uploaded 's3://%1%/%2%' (%3% bytes) in %4% ms")
|
printInfo(format("uploaded ‘s3://%1%/%2%’ (%3% bytes) in %4% ms")
|
||||||
% bucketName % path % data.size() % duration);
|
% bucketName % path % data.size() % duration);
|
||||||
|
|
||||||
stats.putTimeMs += duration;
|
stats.putTimeMs += duration;
|
||||||
|
@ -172,7 +172,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
std::function<void(std::exception_ptr exc)> failure) override
|
std::function<void(std::exception_ptr exc)> failure) override
|
||||||
{
|
{
|
||||||
sync2async<std::shared_ptr<std::string>>(success, failure, [&]() {
|
sync2async<std::shared_ptr<std::string>>(success, failure, [&]() {
|
||||||
debug(format("fetching 's3://%1%/%2%'...") % bucketName % path);
|
debug(format("fetching ‘s3://%1%/%2%’...") % bucketName % path);
|
||||||
|
|
||||||
auto request =
|
auto request =
|
||||||
Aws::S3::Model::GetObjectRequest()
|
Aws::S3::Model::GetObjectRequest()
|
||||||
|
@ -189,7 +189,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
|
|
||||||
auto now1 = std::chrono::steady_clock::now();
|
auto now1 = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
auto result = checkAws(format("AWS error fetching '%s'") % path,
|
auto result = checkAws(format("AWS error fetching ‘%s’") % path,
|
||||||
client->GetObject(request));
|
client->GetObject(request));
|
||||||
|
|
||||||
auto now2 = std::chrono::steady_clock::now();
|
auto now2 = std::chrono::steady_clock::now();
|
||||||
|
@ -198,7 +198,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
|
|
||||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now2 - now1).count();
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now2 - now1).count();
|
||||||
|
|
||||||
printMsg(lvlTalkative, format("downloaded 's3://%1%/%2%' (%3% bytes) in %4% ms")
|
printMsg(lvlTalkative, format("downloaded ‘s3://%1%/%2%’ (%3% bytes) in %4% ms")
|
||||||
% bucketName % path % res.size() % duration);
|
% bucketName % path % res.size() % duration);
|
||||||
|
|
||||||
stats.getBytes += res.size();
|
stats.getBytes += res.size();
|
||||||
|
@ -219,9 +219,9 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
std::string marker;
|
std::string marker;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
debug(format("listing bucket 's3://%s' from key '%s'...") % bucketName % marker);
|
debug(format("listing bucket ‘s3://%s’ from key ‘%s’...") % bucketName % marker);
|
||||||
|
|
||||||
auto res = checkAws(format("AWS error listing bucket '%s'") % bucketName,
|
auto res = checkAws(format("AWS error listing bucket ‘%s’") % bucketName,
|
||||||
client->ListObjects(
|
client->ListObjects(
|
||||||
Aws::S3::Model::ListObjectsRequest()
|
Aws::S3::Model::ListObjectsRequest()
|
||||||
.WithBucket(bucketName)
|
.WithBucket(bucketName)
|
||||||
|
@ -230,7 +230,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
|
|
||||||
auto & contents = res.GetContents();
|
auto & contents = res.GetContents();
|
||||||
|
|
||||||
debug(format("got %d keys, next marker '%s'")
|
debug(format("got %d keys, next marker ‘%s’")
|
||||||
% contents.size() % res.GetNextMarker());
|
% contents.size() % res.GetNextMarker());
|
||||||
|
|
||||||
for (auto object : contents) {
|
for (auto object : contents) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ SQLite::SQLite(const Path & path)
|
||||||
{
|
{
|
||||||
if (sqlite3_open_v2(path.c_str(), &db,
|
if (sqlite3_open_v2(path.c_str(), &db,
|
||||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0) != SQLITE_OK)
|
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0) != SQLITE_OK)
|
||||||
throw Error(format("cannot open SQLite database '%s'") % path);
|
throw Error(format("cannot open SQLite database ‘%s’") % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
SQLite::~SQLite()
|
SQLite::~SQLite()
|
||||||
|
@ -55,7 +55,7 @@ SQLite::~SQLite()
|
||||||
void SQLite::exec(const std::string & stmt)
|
void SQLite::exec(const std::string & stmt)
|
||||||
{
|
{
|
||||||
if (sqlite3_exec(db, stmt.c_str(), 0, 0, 0) != SQLITE_OK)
|
if (sqlite3_exec(db, stmt.c_str(), 0, 0, 0) != SQLITE_OK)
|
||||||
throwSQLiteError(db, format("executing SQLite statement '%s'") % stmt);
|
throwSQLiteError(db, format("executing SQLite statement ‘%s’") % stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SQLiteStmt::create(sqlite3 * db, const string & s)
|
void SQLiteStmt::create(sqlite3 * db, const string & s)
|
||||||
|
|
|
@ -27,14 +27,14 @@ bool Store::isStorePath(const Path & path) const
|
||||||
void Store::assertStorePath(const Path & path) const
|
void Store::assertStorePath(const Path & path) const
|
||||||
{
|
{
|
||||||
if (!isStorePath(path))
|
if (!isStorePath(path))
|
||||||
throw Error(format("path '%1%' is not in the Nix store") % path);
|
throw Error(format("path ‘%1%’ is not in the Nix store") % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path Store::toStorePath(const Path & path) const
|
Path Store::toStorePath(const Path & path) const
|
||||||
{
|
{
|
||||||
if (!isInStore(path))
|
if (!isInStore(path))
|
||||||
throw Error(format("path '%1%' is not in the Nix store") % path);
|
throw Error(format("path ‘%1%’ is not in the Nix store") % path);
|
||||||
Path::size_type slash = path.find('/', storeDir.size() + 1);
|
Path::size_type slash = path.find('/', storeDir.size() + 1);
|
||||||
if (slash == Path::npos)
|
if (slash == Path::npos)
|
||||||
return path;
|
return path;
|
||||||
|
@ -52,7 +52,7 @@ Path Store::followLinksToStore(const Path & _path) const
|
||||||
path = absPath(target, dirOf(path));
|
path = absPath(target, dirOf(path));
|
||||||
}
|
}
|
||||||
if (!isInStore(path))
|
if (!isInStore(path))
|
||||||
throw Error(format("path '%1%' is not in the Nix store") % path);
|
throw Error(format("path ‘%1%’ is not in the Nix store") % path);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,14 +85,14 @@ void checkStoreName(const string & name)
|
||||||
/* Disallow names starting with a dot for possible security
|
/* Disallow names starting with a dot for possible security
|
||||||
reasons (e.g., "." and ".."). */
|
reasons (e.g., "." and ".."). */
|
||||||
if (string(name, 0, 1) == ".")
|
if (string(name, 0, 1) == ".")
|
||||||
throw Error(format("illegal name: '%1%'") % name);
|
throw Error(format("illegal name: ‘%1%’") % name);
|
||||||
for (auto & i : name)
|
for (auto & i : name)
|
||||||
if (!((i >= 'A' && i <= 'Z') ||
|
if (!((i >= 'A' && i <= 'Z') ||
|
||||||
(i >= 'a' && i <= 'z') ||
|
(i >= 'a' && i <= 'z') ||
|
||||||
(i >= '0' && i <= '9') ||
|
(i >= '0' && i <= '9') ||
|
||||||
validChars.find(i) != string::npos))
|
validChars.find(i) != string::npos))
|
||||||
{
|
{
|
||||||
throw Error(format("invalid character '%1%' in name '%2%'")
|
throw Error(format("invalid character ‘%1%’ in name ‘%2%’")
|
||||||
% i % name);
|
% i % name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -312,7 +312,7 @@ void Store::queryPathInfo(const Path & storePath,
|
||||||
if (res) {
|
if (res) {
|
||||||
stats.narInfoReadAverted++;
|
stats.narInfoReadAverted++;
|
||||||
if (!*res)
|
if (!*res)
|
||||||
throw InvalidPath(format("path '%s' is not valid") % storePath);
|
throw InvalidPath(format("path ‘%s’ is not valid") % storePath);
|
||||||
return success(ref<ValidPathInfo>(*res));
|
return success(ref<ValidPathInfo>(*res));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,7 +327,7 @@ void Store::queryPathInfo(const Path & storePath,
|
||||||
res.first == NarInfoDiskCache::oInvalid ? 0 : res.second);
|
res.first == NarInfoDiskCache::oInvalid ? 0 : res.second);
|
||||||
if (res.first == NarInfoDiskCache::oInvalid ||
|
if (res.first == NarInfoDiskCache::oInvalid ||
|
||||||
(res.second->path != storePath && storePathToName(storePath) != ""))
|
(res.second->path != storePath && storePathToName(storePath) != ""))
|
||||||
throw InvalidPath(format("path '%s' is not valid") % storePath);
|
throw InvalidPath(format("path ‘%s’ is not valid") % storePath);
|
||||||
}
|
}
|
||||||
return success(ref<ValidPathInfo>(res.second));
|
return success(ref<ValidPathInfo>(res.second));
|
||||||
}
|
}
|
||||||
|
@ -352,7 +352,7 @@ void Store::queryPathInfo(const Path & storePath,
|
||||||
|| (info->path != storePath && storePathToName(storePath) != ""))
|
|| (info->path != storePath && storePathToName(storePath) != ""))
|
||||||
{
|
{
|
||||||
stats.narInfoMissing++;
|
stats.narInfoMissing++;
|
||||||
return failure(std::make_exception_ptr(InvalidPath(format("path '%s' is not valid") % storePath)));
|
return failure(std::make_exception_ptr(InvalidPath(format("path ‘%s’ is not valid") % storePath)));
|
||||||
}
|
}
|
||||||
|
|
||||||
callSuccess(success, failure, ref<ValidPathInfo>(info));
|
callSuccess(success, failure, ref<ValidPathInfo>(info));
|
||||||
|
@ -514,7 +514,7 @@ string showPaths(const PathSet & paths)
|
||||||
string s;
|
string s;
|
||||||
for (auto & i : paths) {
|
for (auto & i : paths) {
|
||||||
if (s.size() != 0) s += ", ";
|
if (s.size() != 0) s += ", ";
|
||||||
s += "'" + i + "'";
|
s += "‘" + i + "’";
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -523,7 +523,7 @@ string showPaths(const PathSet & paths)
|
||||||
std::string ValidPathInfo::fingerprint() const
|
std::string ValidPathInfo::fingerprint() const
|
||||||
{
|
{
|
||||||
if (narSize == 0 || !narHash)
|
if (narSize == 0 || !narHash)
|
||||||
throw Error(format("cannot calculate fingerprint of path '%s' because its size/hash is not known")
|
throw Error(format("cannot calculate fingerprint of path ‘%s’ because its size/hash is not known")
|
||||||
% path);
|
% path);
|
||||||
return
|
return
|
||||||
"1;" + path + ";"
|
"1;" + path + ";"
|
||||||
|
@ -542,7 +542,7 @@ void ValidPathInfo::sign(const SecretKey & secretKey)
|
||||||
bool ValidPathInfo::isContentAddressed(const Store & store) const
|
bool ValidPathInfo::isContentAddressed(const Store & store) const
|
||||||
{
|
{
|
||||||
auto warn = [&]() {
|
auto warn = [&]() {
|
||||||
printError(format("warning: path '%s' claims to be content-addressed but isn't") % path);
|
printError(format("warning: path ‘%s’ claims to be content-addressed but isn't") % path);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (hasPrefix(ca, "text:")) {
|
if (hasPrefix(ca, "text:")) {
|
||||||
|
@ -625,7 +625,7 @@ ref<Store> openStore(const std::string & uri_)
|
||||||
if (store) return ref<Store>(store);
|
if (store) return ref<Store>(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Error(format("don't know how to open Nix store '%s'") % uri);
|
throw Error(format("don't know how to open Nix store ‘%s’") % uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -131,16 +131,16 @@ struct ValidPathInfo
|
||||||
|
|
||||||
Ideally, the content-addressability assertion would just be a
|
Ideally, the content-addressability assertion would just be a
|
||||||
Boolean, and the store path would be computed from
|
Boolean, and the store path would be computed from
|
||||||
'storePathToName(path)', 'narHash' and 'references'. However,
|
‘storePathToName(path)’, ‘narHash’ and ‘references’. However,
|
||||||
1) we've accumulated several types of content-addressed paths
|
1) we've accumulated several types of content-addressed paths
|
||||||
over the years; and 2) fixed-output derivations support
|
over the years; and 2) fixed-output derivations support
|
||||||
multiple hash algorithms and serialisation methods (flat file
|
multiple hash algorithms and serialisation methods (flat file
|
||||||
vs NAR). Thus, 'ca' has one of the following forms:
|
vs NAR). Thus, ‘ca’ has one of the following forms:
|
||||||
|
|
||||||
* 'text:sha256:<sha256 hash of file contents>': For paths
|
* ‘text:sha256:<sha256 hash of file contents>’: For paths
|
||||||
computed by makeTextPath() / addTextToStore().
|
computed by makeTextPath() / addTextToStore().
|
||||||
|
|
||||||
* 'fixed:<r?>:<ht>:<h>': For paths computed by
|
* ‘fixed:<r?>:<ht>:<h>’: For paths computed by
|
||||||
makeFixedOutputPath() / addToStore().
|
makeFixedOutputPath() / addToStore().
|
||||||
*/
|
*/
|
||||||
std::string ca;
|
std::string ca;
|
||||||
|
@ -242,15 +242,15 @@ public:
|
||||||
|
|
||||||
virtual std::string getUri() = 0;
|
virtual std::string getUri() = 0;
|
||||||
|
|
||||||
/* Return true if 'path' is in the Nix store (but not the Nix
|
/* Return true if ‘path’ is in the Nix store (but not the Nix
|
||||||
store itself). */
|
store itself). */
|
||||||
bool isInStore(const Path & path) const;
|
bool isInStore(const Path & path) const;
|
||||||
|
|
||||||
/* Return true if 'path' is a store path, i.e. a direct child of
|
/* Return true if ‘path’ is a store path, i.e. a direct child of
|
||||||
the Nix store. */
|
the Nix store. */
|
||||||
bool isStorePath(const Path & path) const;
|
bool isStorePath(const Path & path) const;
|
||||||
|
|
||||||
/* Throw an exception if 'path' is not a store path. */
|
/* Throw an exception if ‘path’ is not a store path. */
|
||||||
void assertStorePath(const Path & path) const;
|
void assertStorePath(const Path & path) const;
|
||||||
|
|
||||||
/* Chop off the parts after the top-level store name, e.g.,
|
/* Chop off the parts after the top-level store name, e.g.,
|
||||||
|
@ -363,7 +363,7 @@ public:
|
||||||
|
|
||||||
/* Query substitute info (i.e. references, derivers and download
|
/* Query substitute info (i.e. references, derivers and download
|
||||||
sizes) of a set of paths. If a path does not have substitute
|
sizes) of a set of paths. If a path does not have substitute
|
||||||
info, it's omitted from the resulting 'infos' map. */
|
info, it's omitted from the resulting ‘infos’ map. */
|
||||||
virtual void querySubstitutablePathInfos(const PathSet & paths,
|
virtual void querySubstitutablePathInfos(const PathSet & paths,
|
||||||
SubstitutablePathInfos & infos) = 0;
|
SubstitutablePathInfos & infos) = 0;
|
||||||
|
|
||||||
|
@ -401,7 +401,7 @@ public:
|
||||||
virtual void buildPaths(const PathSet & paths, BuildMode buildMode = bmNormal) = 0;
|
virtual void buildPaths(const PathSet & paths, BuildMode buildMode = bmNormal) = 0;
|
||||||
|
|
||||||
/* Build a single non-materialized derivation (i.e. not from an
|
/* Build a single non-materialized derivation (i.e. not from an
|
||||||
on-disk .drv file). Note that 'drvPath' is only used for
|
on-disk .drv file). Note that ‘drvPath’ is only used for
|
||||||
informational purposes. */
|
informational purposes. */
|
||||||
virtual BuildResult buildDerivation(const Path & drvPath, const BasicDerivation & drv,
|
virtual BuildResult buildDerivation(const Path & drvPath, const BasicDerivation & drv,
|
||||||
BuildMode buildMode = bmNormal) = 0;
|
BuildMode buildMode = bmNormal) = 0;
|
||||||
|
@ -503,8 +503,8 @@ public:
|
||||||
relation. If p refers to q, then p preceeds q in this list. */
|
relation. If p refers to q, then p preceeds q in this list. */
|
||||||
Paths topoSortPaths(const PathSet & paths);
|
Paths topoSortPaths(const PathSet & paths);
|
||||||
|
|
||||||
/* Export multiple paths in the format expected by 'nix-store
|
/* Export multiple paths in the format expected by ‘nix-store
|
||||||
--import'. */
|
--import’. */
|
||||||
void exportPaths(const Paths & paths, Sink & sink);
|
void exportPaths(const Paths & paths, Sink & sink);
|
||||||
|
|
||||||
void exportPath(const Path & path, Sink & sink);
|
void exportPath(const Path & path, Sink & sink);
|
||||||
|
@ -573,7 +573,7 @@ string storePathToName(const Path & path);
|
||||||
/* Extract the hash part of the given store path. */
|
/* Extract the hash part of the given store path. */
|
||||||
string storePathToHash(const Path & path);
|
string storePathToHash(const Path & path);
|
||||||
|
|
||||||
/* Check whether 'name' is a valid store path name part, i.e. contains
|
/* Check whether ‘name’ is a valid store path name part, i.e. contains
|
||||||
only the characters [a-zA-Z0-9\+\-\.\_\?\=] and doesn't start with
|
only the characters [a-zA-Z0-9\+\-\.\_\?\=] and doesn't start with
|
||||||
a dot. */
|
a dot. */
|
||||||
void checkStoreName(const string & name);
|
void checkStoreName(const string & name);
|
||||||
|
@ -596,17 +596,17 @@ void removeTempRoots();
|
||||||
|
|
||||||
|
|
||||||
/* Return a Store object to access the Nix store denoted by
|
/* Return a Store object to access the Nix store denoted by
|
||||||
'uri' (slight misnomer...). Supported values are:
|
‘uri’ (slight misnomer...). Supported values are:
|
||||||
|
|
||||||
* 'direct': The Nix store in /nix/store and database in
|
* ‘direct’: The Nix store in /nix/store and database in
|
||||||
/nix/var/nix/db, accessed directly.
|
/nix/var/nix/db, accessed directly.
|
||||||
|
|
||||||
* 'daemon': The Nix store accessed via a Unix domain socket
|
* ‘daemon’: The Nix store accessed via a Unix domain socket
|
||||||
connection to nix-daemon.
|
connection to nix-daemon.
|
||||||
|
|
||||||
* 'file://<path>': A binary cache stored in <path>.
|
* ‘file://<path>’: A binary cache stored in <path>.
|
||||||
|
|
||||||
If 'uri' is empty, it defaults to 'direct' or 'daemon' depending on
|
If ‘uri’ is empty, it defaults to ‘direct’ or ‘daemon’ depending on
|
||||||
whether the user has write access to the local Nix store/database.
|
whether the user has write access to the local Nix store/database.
|
||||||
set to true *unless* you're going to collect garbage. */
|
set to true *unless* you're going to collect garbage. */
|
||||||
ref<Store> openStore(const std::string & uri = getEnv("NIX_REMOTE"));
|
ref<Store> openStore(const std::string & uri = getEnv("NIX_REMOTE"));
|
||||||
|
@ -622,8 +622,8 @@ enum StoreType {
|
||||||
StoreType getStoreType(const std::string & uri = getEnv("NIX_REMOTE"), const std::string & stateDir = settings.nixStateDir);
|
StoreType getStoreType(const std::string & uri = getEnv("NIX_REMOTE"), const std::string & stateDir = settings.nixStateDir);
|
||||||
|
|
||||||
/* Return the default substituter stores, defined by the
|
/* Return the default substituter stores, defined by the
|
||||||
'substituters' option and various legacy options like
|
‘substituters’ option and various legacy options like
|
||||||
'binary-caches'. */
|
‘binary-caches’. */
|
||||||
std::list<ref<Store>> getDefaultSubstituters();
|
std::list<ref<Store>> getDefaultSubstituters();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ static void dumpContents(const Path & path, size_t size,
|
||||||
sink << "contents" << size;
|
sink << "contents" << size;
|
||||||
|
|
||||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
||||||
if (!fd) throw SysError(format("opening file '%1%'") % path);
|
if (!fd) throw SysError(format("opening file ‘%1%’") % path);
|
||||||
|
|
||||||
unsigned char buf[65536];
|
unsigned char buf[65536];
|
||||||
size_t left = size;
|
size_t left = size;
|
||||||
|
@ -60,7 +60,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError(format("getting attributes of path ‘%1%’") % path);
|
||||||
|
|
||||||
sink << "(";
|
sink << "(";
|
||||||
|
|
||||||
|
@ -82,11 +82,11 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
|
||||||
string name(i.name);
|
string name(i.name);
|
||||||
size_t pos = i.name.find(caseHackSuffix);
|
size_t pos = i.name.find(caseHackSuffix);
|
||||||
if (pos != string::npos) {
|
if (pos != string::npos) {
|
||||||
debug(format("removing case hack suffix from '%1%'") % (path + "/" + i.name));
|
debug(format("removing case hack suffix from ‘%1%’") % (path + "/" + i.name));
|
||||||
name.erase(pos);
|
name.erase(pos);
|
||||||
}
|
}
|
||||||
if (unhacked.find(name) != unhacked.end())
|
if (unhacked.find(name) != unhacked.end())
|
||||||
throw Error(format("file name collision in between '%1%' and '%2%'")
|
throw Error(format("file name collision in between ‘%1%’ and ‘%2%’")
|
||||||
% (path + "/" + unhacked[name]) % (path + "/" + i.name));
|
% (path + "/" + unhacked[name]) % (path + "/" + i.name));
|
||||||
unhacked[name] = i.name;
|
unhacked[name] = i.name;
|
||||||
} else
|
} else
|
||||||
|
@ -103,7 +103,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
|
||||||
else if (S_ISLNK(st.st_mode))
|
else if (S_ISLNK(st.st_mode))
|
||||||
sink << "type" << "symlink" << "target" << readLink(path);
|
sink << "type" << "symlink" << "target" << readLink(path);
|
||||||
|
|
||||||
else throw Error(format("file '%1%' has an unsupported type") % path);
|
else throw Error(format("file ‘%1%’ has an unsupported type") % path);
|
||||||
|
|
||||||
sink << ")";
|
sink << ")";
|
||||||
}
|
}
|
||||||
|
@ -239,14 +239,14 @@ static void parse(ParseSink & sink, Source & source, const Path & path)
|
||||||
} else if (s == "name") {
|
} else if (s == "name") {
|
||||||
name = readString(source);
|
name = readString(source);
|
||||||
if (name.empty() || name == "." || name == ".." || name.find('/') != string::npos || name.find((char) 0) != string::npos)
|
if (name.empty() || name == "." || name == ".." || name.find('/') != string::npos || name.find((char) 0) != string::npos)
|
||||||
throw Error(format("NAR contains invalid file name '%1%'") % name);
|
throw Error(format("NAR contains invalid file name ‘%1%’") % name);
|
||||||
if (name <= prevName)
|
if (name <= prevName)
|
||||||
throw Error("NAR directory is not sorted");
|
throw Error("NAR directory is not sorted");
|
||||||
prevName = name;
|
prevName = name;
|
||||||
if (useCaseHack) {
|
if (useCaseHack) {
|
||||||
auto i = names.find(name);
|
auto i = names.find(name);
|
||||||
if (i != names.end()) {
|
if (i != names.end()) {
|
||||||
debug(format("case collision between '%1%' and '%2%'") % i->first % name);
|
debug(format("case collision between ‘%1%’ and ‘%2%’") % i->first % name);
|
||||||
name += caseHackSuffix;
|
name += caseHackSuffix;
|
||||||
name += std::to_string(++i->second);
|
name += std::to_string(++i->second);
|
||||||
} else
|
} else
|
||||||
|
@ -295,14 +295,14 @@ struct RestoreSink : ParseSink
|
||||||
{
|
{
|
||||||
Path p = dstPath + path;
|
Path p = dstPath + path;
|
||||||
if (mkdir(p.c_str(), 0777) == -1)
|
if (mkdir(p.c_str(), 0777) == -1)
|
||||||
throw SysError(format("creating directory '%1%'") % p);
|
throw SysError(format("creating directory ‘%1%’") % p);
|
||||||
};
|
};
|
||||||
|
|
||||||
void createRegularFile(const Path & path)
|
void createRegularFile(const Path & path)
|
||||||
{
|
{
|
||||||
Path p = dstPath + path;
|
Path p = dstPath + path;
|
||||||
fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666);
|
fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666);
|
||||||
if (!fd) throw SysError(format("creating file '%1%'") % p);
|
if (!fd) throw SysError(format("creating file ‘%1%’") % p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void isExecutable()
|
void isExecutable()
|
||||||
|
|
|
@ -35,7 +35,7 @@ void Args::parseCmdline(const Strings & _cmdline)
|
||||||
}
|
}
|
||||||
else if (!dashDash && std::string(arg, 0, 1) == "-") {
|
else if (!dashDash && std::string(arg, 0, 1) == "-") {
|
||||||
if (!processFlag(pos, cmdline.end()))
|
if (!processFlag(pos, cmdline.end()))
|
||||||
throw UsageError(format("unrecognised flag '%1%'") % arg);
|
throw UsageError(format("unrecognised flag ‘%1%’") % arg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pendingArgs.push_back(*pos++);
|
pendingArgs.push_back(*pos++);
|
||||||
|
@ -88,7 +88,7 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
|
||||||
Strings args;
|
Strings args;
|
||||||
for (size_t n = 0 ; n < flag.arity; ++n) {
|
for (size_t n = 0 ; n < flag.arity; ++n) {
|
||||||
if (pos == end)
|
if (pos == end)
|
||||||
throw UsageError(format("flag '%1%' requires %2% argument(s)")
|
throw UsageError(format("flag ‘%1%’ requires %2% argument(s)")
|
||||||
% name % flag.arity);
|
% name % flag.arity);
|
||||||
args.push_back(*pos++);
|
args.push_back(*pos++);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ bool Args::processArgs(const Strings & args, bool finish)
|
||||||
{
|
{
|
||||||
if (expectedArgs.empty()) {
|
if (expectedArgs.empty()) {
|
||||||
if (!args.empty())
|
if (!args.empty())
|
||||||
throw UsageError(format("unexpected argument '%1%'") % args.front());
|
throw UsageError(format("unexpected argument ‘%1%’") % args.front());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,10 +140,10 @@ bool Args::processArgs(const Strings & args, bool finish)
|
||||||
|
|
||||||
void Args::mkHashTypeFlag(const std::string & name, HashType * ht)
|
void Args::mkHashTypeFlag(const std::string & name, HashType * ht)
|
||||||
{
|
{
|
||||||
mkFlag1(0, name, "TYPE", "hash algorithm ('md5', 'sha1', 'sha256', or 'sha512')", [=](std::string s) {
|
mkFlag1(0, name, "TYPE", "hash algorithm (‘md5’, ‘sha1’, ‘sha256’, or ‘sha512’)", [=](std::string s) {
|
||||||
*ht = parseHashType(s);
|
*ht = parseHashType(s);
|
||||||
if (*ht == htUnknown)
|
if (*ht == htUnknown)
|
||||||
throw UsageError(format("unknown hash type '%1%'") % s);
|
throw UsageError(format("unknown hash type ‘%1%’") % s);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ public:
|
||||||
mkFlag(shortName, longName, {"N"}, description, 1, [=](Strings ss) {
|
mkFlag(shortName, longName, {"N"}, description, 1, [=](Strings ss) {
|
||||||
I n;
|
I n;
|
||||||
if (!string2Int(ss.front(), n))
|
if (!string2Int(ss.front(), n))
|
||||||
throw UsageError(format("flag '--%1%' requires a integer argument") % longName);
|
throw UsageError(format("flag ‘--%1%’ requires a integer argument") % longName);
|
||||||
fun(n);
|
fun(n);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ ref<std::string> decompress(const std::string & method, const std::string & in)
|
||||||
else if (method == "bzip2")
|
else if (method == "bzip2")
|
||||||
return decompressBzip2(in);
|
return decompressBzip2(in);
|
||||||
else
|
else
|
||||||
throw UnknownCompressionMethod(format("unknown compression method '%s'") % method);
|
throw UnknownCompressionMethod(format("unknown compression method ‘%s’") % method);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NoneSink : CompressionSink
|
struct NoneSink : CompressionSink
|
||||||
|
@ -270,7 +270,7 @@ ref<CompressionSink> makeCompressionSink(const std::string & method, Sink & next
|
||||||
else if (method == "bzip2")
|
else if (method == "bzip2")
|
||||||
return make_ref<BzipSink>(nextSink);
|
return make_ref<BzipSink>(nextSink);
|
||||||
else
|
else
|
||||||
throw UnknownCompressionMethod(format("unknown compression method '%s'") % method);
|
throw UnknownCompressionMethod(format("unknown compression method ‘%s’") % method);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,11 +88,11 @@ Hash parseHash(const string & s)
|
||||||
{
|
{
|
||||||
string::size_type colon = s.find(':');
|
string::size_type colon = s.find(':');
|
||||||
if (colon == string::npos)
|
if (colon == string::npos)
|
||||||
throw BadHash(format("invalid hash '%s'") % s);
|
throw BadHash(format("invalid hash ‘%s’") % s);
|
||||||
string hts = string(s, 0, colon);
|
string hts = string(s, 0, colon);
|
||||||
HashType ht = parseHashType(hts);
|
HashType ht = parseHashType(hts);
|
||||||
if (ht == htUnknown)
|
if (ht == htUnknown)
|
||||||
throw BadHash(format("unknown hash type '%s'") % hts);
|
throw BadHash(format("unknown hash type ‘%s’") % hts);
|
||||||
return parseHash16or32(ht, string(s, colon + 1));
|
return parseHash16or32(ht, string(s, colon + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,11 +101,11 @@ Hash parseHash(HashType ht, const string & s)
|
||||||
{
|
{
|
||||||
Hash hash(ht);
|
Hash hash(ht);
|
||||||
if (s.length() != hash.hashSize * 2)
|
if (s.length() != hash.hashSize * 2)
|
||||||
throw BadHash(format("invalid hash '%1%'") % s);
|
throw BadHash(format("invalid hash ‘%1%’") % s);
|
||||||
for (unsigned int i = 0; i < hash.hashSize; i++) {
|
for (unsigned int i = 0; i < hash.hashSize; i++) {
|
||||||
string s2(s, i * 2, 2);
|
string s2(s, i * 2, 2);
|
||||||
if (!isxdigit(s2[0]) || !isxdigit(s2[1]))
|
if (!isxdigit(s2[0]) || !isxdigit(s2[1]))
|
||||||
throw BadHash(format("invalid hash '%1%'") % s);
|
throw BadHash(format("invalid hash ‘%1%’") % s);
|
||||||
istringstream_nocopy str(s2);
|
istringstream_nocopy str(s2);
|
||||||
int n;
|
int n;
|
||||||
str >> std::hex >> n;
|
str >> std::hex >> n;
|
||||||
|
@ -160,7 +160,7 @@ Hash parseHash32(HashType ht, const string & s)
|
||||||
for (digit = 0; digit < base32Chars.size(); ++digit) /* !!! slow */
|
for (digit = 0; digit < base32Chars.size(); ++digit) /* !!! slow */
|
||||||
if (base32Chars[digit] == c) break;
|
if (base32Chars[digit] == c) break;
|
||||||
if (digit >= 32)
|
if (digit >= 32)
|
||||||
throw BadHash(format("invalid base-32 hash '%1%'") % s);
|
throw BadHash(format("invalid base-32 hash ‘%1%’") % s);
|
||||||
unsigned int b = n * 5;
|
unsigned int b = n * 5;
|
||||||
unsigned int i = b / 8;
|
unsigned int i = b / 8;
|
||||||
unsigned int j = b % 8;
|
unsigned int j = b % 8;
|
||||||
|
@ -182,7 +182,7 @@ Hash parseHash16or32(HashType ht, const string & s)
|
||||||
/* base-32 representation */
|
/* base-32 representation */
|
||||||
hash = parseHash32(ht, s);
|
hash = parseHash32(ht, s);
|
||||||
else
|
else
|
||||||
throw BadHash(format("hash '%1%' has wrong length for hash type '%2%'")
|
throw BadHash(format("hash ‘%1%’ has wrong length for hash type ‘%2%’")
|
||||||
% s % printHashType(ht));
|
% s % printHashType(ht));
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -256,13 +256,13 @@ Hash hashFile(HashType ht, const Path & path)
|
||||||
start(ht, ctx);
|
start(ht, ctx);
|
||||||
|
|
||||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
||||||
if (!fd) throw SysError(format("opening file '%1%'") % path);
|
if (!fd) throw SysError(format("opening file ‘%1%’") % path);
|
||||||
|
|
||||||
unsigned char buf[8192];
|
unsigned char buf[8192];
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
while ((n = read(fd.get(), buf, sizeof(buf)))) {
|
while ((n = read(fd.get(), buf, sizeof(buf)))) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
if (n == -1) throw SysError(format("reading file '%1%'") % path);
|
if (n == -1) throw SysError(format("reading file ‘%1%’") % path);
|
||||||
update(ht, ctx, buf, n);
|
update(ht, ctx, buf, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ namespace nix {
|
||||||
conn->exec("select ...");
|
conn->exec("select ...");
|
||||||
}
|
}
|
||||||
|
|
||||||
Here, the Connection object referenced by 'conn' is automatically
|
Here, the Connection object referenced by ‘conn’ is automatically
|
||||||
returned to the pool when 'conn' goes out of scope.
|
returned to the pool when ‘conn’ goes out of scope.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <class R>
|
template <class R>
|
||||||
|
|
|
@ -50,12 +50,12 @@ struct Source
|
||||||
{
|
{
|
||||||
virtual ~Source() { }
|
virtual ~Source() { }
|
||||||
|
|
||||||
/* Store exactly 'len' bytes in the buffer pointed to by 'data'.
|
/* Store exactly ‘len’ bytes in the buffer pointed to by ‘data’.
|
||||||
It blocks until all the requested data is available, or throws
|
It blocks until all the requested data is available, or throws
|
||||||
an error if it is not going to be available. */
|
an error if it is not going to be available. */
|
||||||
void operator () (unsigned char * data, size_t len);
|
void operator () (unsigned char * data, size_t len);
|
||||||
|
|
||||||
/* Store up to 'len' in the buffer pointed to by 'data', and
|
/* Store up to ‘len’ in the buffer pointed to by ‘data’, and
|
||||||
return the number of bytes stored. If blocks until at least
|
return the number of bytes stored. If blocks until at least
|
||||||
one byte is available. */
|
one byte is available. */
|
||||||
virtual size_t read(unsigned char * data, size_t len) = 0;
|
virtual size_t read(unsigned char * data, size_t len) = 0;
|
||||||
|
|
|
@ -41,9 +41,9 @@ struct FormatOrString
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* A helper for formatting strings. 'fmt(format, a_0, ..., a_n)' is
|
/* A helper for formatting strings. ‘fmt(format, a_0, ..., a_n)’ is
|
||||||
equivalent to 'boost::format(format) % a_0 % ... %
|
equivalent to ‘boost::format(format) % a_0 % ... %
|
||||||
... a_n'. However, 'fmt(s)' is equivalent to 's' (so no %-expansion
|
... a_n’. However, ‘fmt(s)’ is equivalent to ‘s’ (so no %-expansion
|
||||||
takes place). */
|
takes place). */
|
||||||
|
|
||||||
inline void formatHelper(boost::format & f)
|
inline void formatHelper(boost::format & f)
|
||||||
|
|
|
@ -97,7 +97,7 @@ Path canonPath(const Path & path, bool resolveSymlinks)
|
||||||
string s;
|
string s;
|
||||||
|
|
||||||
if (path[0] != '/')
|
if (path[0] != '/')
|
||||||
throw Error(format("not an absolute path: '%1%'") % path);
|
throw Error(format("not an absolute path: ‘%1%’") % path);
|
||||||
|
|
||||||
string::const_iterator i = path.begin(), end = path.end();
|
string::const_iterator i = path.begin(), end = path.end();
|
||||||
string temp;
|
string temp;
|
||||||
|
@ -133,7 +133,7 @@ Path canonPath(const Path & path, bool resolveSymlinks)
|
||||||
the symlink target might contain new symlinks). */
|
the symlink target might contain new symlinks). */
|
||||||
if (resolveSymlinks && isLink(s)) {
|
if (resolveSymlinks && isLink(s)) {
|
||||||
if (++followCount >= maxFollow)
|
if (++followCount >= maxFollow)
|
||||||
throw Error(format("infinite symlink recursion in path '%1%'") % path);
|
throw Error(format("infinite symlink recursion in path ‘%1%’") % path);
|
||||||
temp = absPath(readLink(s), dirOf(s))
|
temp = absPath(readLink(s), dirOf(s))
|
||||||
+ string(i, end);
|
+ string(i, end);
|
||||||
i = temp.begin(); /* restart */
|
i = temp.begin(); /* restart */
|
||||||
|
@ -151,7 +151,7 @@ Path dirOf(const Path & path)
|
||||||
{
|
{
|
||||||
Path::size_type pos = path.rfind('/');
|
Path::size_type pos = path.rfind('/');
|
||||||
if (pos == string::npos)
|
if (pos == string::npos)
|
||||||
throw Error(format("invalid file name '%1%'") % path);
|
throw Error(format("invalid file name ‘%1%’") % path);
|
||||||
return pos == 0 ? "/" : Path(path, 0, pos);
|
return pos == 0 ? "/" : Path(path, 0, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ struct stat lstat(const Path & path)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting status of '%1%'") % path);
|
throw SysError(format("getting status of ‘%1%’") % path);
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,13 +210,13 @@ Path readLink(const Path & path)
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
struct stat st = lstat(path);
|
struct stat st = lstat(path);
|
||||||
if (!S_ISLNK(st.st_mode))
|
if (!S_ISLNK(st.st_mode))
|
||||||
throw Error(format("'%1%' is not a symlink") % path);
|
throw Error(format("‘%1%’ is not a symlink") % path);
|
||||||
char buf[st.st_size];
|
char buf[st.st_size];
|
||||||
ssize_t rlsize = readlink(path.c_str(), buf, st.st_size);
|
ssize_t rlsize = readlink(path.c_str(), buf, st.st_size);
|
||||||
if (rlsize == -1)
|
if (rlsize == -1)
|
||||||
throw SysError(format("reading symbolic link '%1%'") % path);
|
throw SysError(format("reading symbolic link ‘%1%’") % path);
|
||||||
else if (rlsize > st.st_size)
|
else if (rlsize > st.st_size)
|
||||||
throw Error(format("symbolic link '%1%' size overflow %2% > %3%")
|
throw Error(format("symbolic link ‘%1%’ size overflow %2% > %3%")
|
||||||
% path % rlsize % st.st_size);
|
% path % rlsize % st.st_size);
|
||||||
return string(buf, rlsize);
|
return string(buf, rlsize);
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ DirEntries readDirectory(const Path & path)
|
||||||
entries.reserve(64);
|
entries.reserve(64);
|
||||||
|
|
||||||
AutoCloseDir dir = opendir(path.c_str());
|
AutoCloseDir dir = opendir(path.c_str());
|
||||||
if (!dir) throw SysError(format("opening directory '%1%'") % path);
|
if (!dir) throw SysError(format("opening directory ‘%1%’") % path);
|
||||||
|
|
||||||
struct dirent * dirent;
|
struct dirent * dirent;
|
||||||
while (errno = 0, dirent = readdir(dir)) { /* sic */
|
while (errno = 0, dirent = readdir(dir)) { /* sic */
|
||||||
|
@ -250,7 +250,7 @@ DirEntries readDirectory(const Path & path)
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (errno) throw SysError(format("reading directory '%1%'") % path);
|
if (errno) throw SysError(format("reading directory ‘%1%’") % path);
|
||||||
|
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
@ -284,7 +284,7 @@ string readFile(const Path & path, bool drain)
|
||||||
{
|
{
|
||||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
||||||
if (!fd)
|
if (!fd)
|
||||||
throw SysError(format("opening file '%1%'") % path);
|
throw SysError(format("opening file ‘%1%’") % path);
|
||||||
return drain ? drainFD(fd.get()) : readFile(fd.get());
|
return drain ? drainFD(fd.get()) : readFile(fd.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ void writeFile(const Path & path, const string & s)
|
||||||
{
|
{
|
||||||
AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0666);
|
AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0666);
|
||||||
if (!fd)
|
if (!fd)
|
||||||
throw SysError(format("opening file '%1%'") % path);
|
throw SysError(format("opening file ‘%1%’") % path);
|
||||||
writeFull(fd.get(), s);
|
writeFull(fd.get(), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st) == -1) {
|
if (lstat(path.c_str(), &st) == -1) {
|
||||||
if (errno == ENOENT) return;
|
if (errno == ENOENT) return;
|
||||||
throw SysError(format("getting status of '%1%'") % path);
|
throw SysError(format("getting status of ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_ISDIR(st.st_mode) && st.st_nlink == 1)
|
if (!S_ISDIR(st.st_mode) && st.st_nlink == 1)
|
||||||
|
@ -343,7 +343,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
|
||||||
const auto PERM_MASK = S_IRUSR | S_IWUSR | S_IXUSR;
|
const auto PERM_MASK = S_IRUSR | S_IWUSR | S_IXUSR;
|
||||||
if ((st.st_mode & PERM_MASK) != PERM_MASK) {
|
if ((st.st_mode & PERM_MASK) != PERM_MASK) {
|
||||||
if (chmod(path.c_str(), st.st_mode | PERM_MASK) == -1)
|
if (chmod(path.c_str(), st.st_mode | PERM_MASK) == -1)
|
||||||
throw SysError(format("chmod '%1%'") % path);
|
throw SysError(format("chmod ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto & i : readDirectory(path))
|
for (auto & i : readDirectory(path))
|
||||||
|
@ -352,7 +352,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
|
||||||
|
|
||||||
if (remove(path.c_str()) == -1) {
|
if (remove(path.c_str()) == -1) {
|
||||||
if (errno == ENOENT) return;
|
if (errno == ENOENT) return;
|
||||||
throw SysError(format("cannot unlink '%1%'") % path);
|
throw SysError(format("cannot unlink ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ void deletePath(const Path & path)
|
||||||
|
|
||||||
void deletePath(const Path & path, unsigned long long & bytesFreed)
|
void deletePath(const Path & path, unsigned long long & bytesFreed)
|
||||||
{
|
{
|
||||||
Activity act(*logger, lvlDebug, format("recursively deleting path '%1%'") % path);
|
Activity act(*logger, lvlDebug, format("recursively deleting path ‘%1%’") % path);
|
||||||
bytesFreed = 0;
|
bytesFreed = 0;
|
||||||
_deletePath(path, bytesFreed);
|
_deletePath(path, bytesFreed);
|
||||||
}
|
}
|
||||||
|
@ -404,12 +404,12 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix,
|
||||||
"wheel", then "tar" will fail to unpack archives that
|
"wheel", then "tar" will fail to unpack archives that
|
||||||
have the setgid bit set on directories. */
|
have the setgid bit set on directories. */
|
||||||
if (chown(tmpDir.c_str(), (uid_t) -1, getegid()) != 0)
|
if (chown(tmpDir.c_str(), (uid_t) -1, getegid()) != 0)
|
||||||
throw SysError(format("setting group of directory '%1%'") % tmpDir);
|
throw SysError(format("setting group of directory ‘%1%’") % tmpDir);
|
||||||
#endif
|
#endif
|
||||||
return tmpDir;
|
return tmpDir;
|
||||||
}
|
}
|
||||||
if (errno != EEXIST)
|
if (errno != EEXIST)
|
||||||
throw SysError(format("creating directory '%1%'") % tmpDir);
|
throw SysError(format("creating directory ‘%1%’") % tmpDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,15 +435,15 @@ Paths createDirs(const Path & path)
|
||||||
if (lstat(path.c_str(), &st) == -1) {
|
if (lstat(path.c_str(), &st) == -1) {
|
||||||
created = createDirs(dirOf(path));
|
created = createDirs(dirOf(path));
|
||||||
if (mkdir(path.c_str(), 0777) == -1 && errno != EEXIST)
|
if (mkdir(path.c_str(), 0777) == -1 && errno != EEXIST)
|
||||||
throw SysError(format("creating directory '%1%'") % path);
|
throw SysError(format("creating directory ‘%1%’") % path);
|
||||||
st = lstat(path);
|
st = lstat(path);
|
||||||
created.push_back(path);
|
created.push_back(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISLNK(st.st_mode) && stat(path.c_str(), &st) == -1)
|
if (S_ISLNK(st.st_mode) && stat(path.c_str(), &st) == -1)
|
||||||
throw SysError(format("statting symlink '%1%'") % path);
|
throw SysError(format("statting symlink ‘%1%’") % path);
|
||||||
|
|
||||||
if (!S_ISDIR(st.st_mode)) throw Error(format("'%1%' is not a directory") % path);
|
if (!S_ISDIR(st.st_mode)) throw Error(format("‘%1%’ is not a directory") % path);
|
||||||
|
|
||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
@ -452,7 +452,7 @@ Paths createDirs(const Path & path)
|
||||||
void createSymlink(const Path & target, const Path & link)
|
void createSymlink(const Path & target, const Path & link)
|
||||||
{
|
{
|
||||||
if (symlink(target.c_str(), link.c_str()))
|
if (symlink(target.c_str(), link.c_str()))
|
||||||
throw SysError(format("creating symlink from '%1%' to '%2%'") % link % target);
|
throw SysError(format("creating symlink from ‘%1%’ to ‘%2%’") % link % target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -463,7 +463,7 @@ void replaceSymlink(const Path & target, const Path & link)
|
||||||
createSymlink(target, tmp);
|
createSymlink(target, tmp);
|
||||||
|
|
||||||
if (rename(tmp.c_str(), link.c_str()) != 0)
|
if (rename(tmp.c_str(), link.c_str()) != 0)
|
||||||
throw SysError(format("renaming '%1%' to '%2%'") % tmp % link);
|
throw SysError(format("renaming ‘%1%’ to ‘%2%’") % tmp % link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -542,7 +542,7 @@ AutoDelete::~AutoDelete()
|
||||||
deletePath(path);
|
deletePath(path);
|
||||||
else {
|
else {
|
||||||
if (remove(path.c_str()) == -1)
|
if (remove(path.c_str()) == -1)
|
||||||
throw SysError(format("cannot unlink '%1%'") % path);
|
throw SysError(format("cannot unlink ‘%1%’") % path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
@ -788,7 +788,7 @@ pid_t Pid::release()
|
||||||
|
|
||||||
void killUser(uid_t uid)
|
void killUser(uid_t uid)
|
||||||
{
|
{
|
||||||
debug(format("killing all processes running under uid '%1%'") % uid);
|
debug(format("killing all processes running under uid ‘%1%’") % uid);
|
||||||
|
|
||||||
assert(uid != 0); /* just to be safe... */
|
assert(uid != 0); /* just to be safe... */
|
||||||
|
|
||||||
|
@ -817,7 +817,7 @@ void killUser(uid_t uid)
|
||||||
#endif
|
#endif
|
||||||
if (errno == ESRCH) break; /* no more processes */
|
if (errno == ESRCH) break; /* no more processes */
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
throw SysError(format("cannot kill processes for uid '%1%'") % uid);
|
throw SysError(format("cannot kill processes for uid ‘%1%’") % uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
_exit(0);
|
_exit(0);
|
||||||
|
@ -825,7 +825,7 @@ void killUser(uid_t uid)
|
||||||
|
|
||||||
int status = pid.wait(true);
|
int status = pid.wait(true);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
throw Error(format("cannot kill processes for uid '%1%': %2%") % uid % statusToString(status));
|
throw Error(format("cannot kill processes for uid ‘%1%’: %2%") % uid % statusToString(status));
|
||||||
|
|
||||||
/* !!! We should really do some check to make sure that there are
|
/* !!! We should really do some check to make sure that there are
|
||||||
no processes left running under `uid', but there is no portable
|
no processes left running under `uid', but there is no portable
|
||||||
|
@ -919,7 +919,7 @@ string runProgram(Path program, bool searchPath, const Strings & args,
|
||||||
else
|
else
|
||||||
execv(program.c_str(), stringsToCharPtrs(args_).data());
|
execv(program.c_str(), stringsToCharPtrs(args_).data());
|
||||||
|
|
||||||
throw SysError(format("executing '%1%'") % program);
|
throw SysError(format("executing ‘%1%’") % program);
|
||||||
});
|
});
|
||||||
|
|
||||||
out.writeSide = -1;
|
out.writeSide = -1;
|
||||||
|
@ -936,7 +936,7 @@ string runProgram(Path program, bool searchPath, const Strings & args,
|
||||||
/* Wait for the child to finish. */
|
/* Wait for the child to finish. */
|
||||||
int status = pid.wait(true);
|
int status = pid.wait(true);
|
||||||
if (!statusOk(status))
|
if (!statusOk(status))
|
||||||
throw ExecError(status, format("program '%1%' %2%")
|
throw ExecError(status, format("program ‘%1%’ %2%")
|
||||||
% program % statusToString(status));
|
% program % statusToString(status));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -370,7 +370,7 @@ void ignoreException();
|
||||||
#define ANSI_RED "\e[31;1m"
|
#define ANSI_RED "\e[31;1m"
|
||||||
|
|
||||||
|
|
||||||
/* Filter out ANSI escape codes from the given string. If 'nixOnly' is
|
/* Filter out ANSI escape codes from the given string. If ‘nixOnly’ is
|
||||||
set, only filter escape codes generated by Nixpkgs' stdenv (used to
|
set, only filter escape codes generated by Nixpkgs' stdenv (used to
|
||||||
denote nesting etc.). */
|
denote nesting etc.). */
|
||||||
string filterANSIEscapes(const string & s, bool nixOnly = false);
|
string filterANSIEscapes(const string & s, bool nixOnly = false);
|
||||||
|
@ -391,15 +391,15 @@ string get(const T & map, const string & key, const string & def = "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Call 'failure' with the current exception as argument. If 'failure'
|
/* Call ‘failure’ with the current exception as argument. If ‘failure’
|
||||||
throws an exception, abort the program. */
|
throws an exception, abort the program. */
|
||||||
void callFailure(const std::function<void(std::exception_ptr exc)> & failure,
|
void callFailure(const std::function<void(std::exception_ptr exc)> & failure,
|
||||||
std::exception_ptr exc = std::current_exception());
|
std::exception_ptr exc = std::current_exception());
|
||||||
|
|
||||||
|
|
||||||
/* Evaluate the function 'f'. If it returns a value, call 'success'
|
/* Evaluate the function ‘f’. If it returns a value, call ‘success’
|
||||||
with that value as its argument. If it or 'success' throws an
|
with that value as its argument. If it or ‘success’ throws an
|
||||||
exception, call 'failure'. If 'failure' throws an exception, abort
|
exception, call ‘failure’. If ‘failure’ throws an exception, abort
|
||||||
the program. */
|
the program. */
|
||||||
template<class T>
|
template<class T>
|
||||||
void sync2async(
|
void sync2async(
|
||||||
|
@ -415,8 +415,8 @@ void sync2async(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Call the function 'success'. If it throws an exception, call
|
/* Call the function ‘success’. If it throws an exception, call
|
||||||
'failure'. If that throws an exception, abort the program. */
|
‘failure’. If that throws an exception, abort the program. */
|
||||||
template<class T>
|
template<class T>
|
||||||
void callSuccess(
|
void callSuccess(
|
||||||
const std::function<void(T)> & success,
|
const std::function<void(T)> & success,
|
||||||
|
|
|
@ -322,7 +322,7 @@ int main(int argc, char ** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packages && fromArgs) {
|
if (packages && fromArgs) {
|
||||||
throw UsageError("'-p' and '-E' are mutually exclusive");
|
throw UsageError("‘-p’ and ‘-E’ are mutually exclusive");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packages) {
|
if (packages) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ static void writeChannels()
|
||||||
{
|
{
|
||||||
auto channelsFD = AutoCloseFD{open(channelsList.c_str(), O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC, 0644)};
|
auto channelsFD = AutoCloseFD{open(channelsList.c_str(), O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC, 0644)};
|
||||||
if (!channelsFD)
|
if (!channelsFD)
|
||||||
throw SysError(format("opening '%1%' for writing") % channelsList);
|
throw SysError(format("opening ‘%1%’ for writing") % channelsList);
|
||||||
for (const auto & channel : channels)
|
for (const auto & channel : channels)
|
||||||
writeFull(channelsFD.get(), channel.second + " " + channel.first + "\n");
|
writeFull(channelsFD.get(), channel.second + " " + channel.first + "\n");
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,9 @@ static void writeChannels()
|
||||||
static void addChannel(const string & url, const string & name)
|
static void addChannel(const string & url, const string & name)
|
||||||
{
|
{
|
||||||
if (!regex_search(url, std::regex("^(file|http|https)://")))
|
if (!regex_search(url, std::regex("^(file|http|https)://")))
|
||||||
throw Error(format("invalid channel URL '%1%'") % url);
|
throw Error(format("invalid channel URL ‘%1%’") % url);
|
||||||
if (!regex_search(name, std::regex("^[a-zA-Z0-9_][a-zA-Z0-9_\\.-]*$")))
|
if (!regex_search(name, std::regex("^[a-zA-Z0-9_][a-zA-Z0-9_\\.-]*$")))
|
||||||
throw Error(format("invalid channel identifier '%1%'") % name);
|
throw Error(format("invalid channel identifier ‘%1%’") % name);
|
||||||
readChannels();
|
readChannels();
|
||||||
channels[name] = url;
|
channels[name] = url;
|
||||||
writeChannels();
|
writeChannels();
|
||||||
|
@ -224,7 +224,7 @@ int main(int argc, char ** argv)
|
||||||
throw UsageError("no command specified");
|
throw UsageError("no command specified");
|
||||||
case cAdd:
|
case cAdd:
|
||||||
if (args.size() < 1 || args.size() > 2)
|
if (args.size() < 1 || args.size() > 2)
|
||||||
throw UsageError("'--add' requires one or two arguments");
|
throw UsageError("‘--add’ requires one or two arguments");
|
||||||
{
|
{
|
||||||
auto url = args[0];
|
auto url = args[0];
|
||||||
auto name = string{};
|
auto name = string{};
|
||||||
|
@ -240,12 +240,12 @@ int main(int argc, char ** argv)
|
||||||
break;
|
break;
|
||||||
case cRemove:
|
case cRemove:
|
||||||
if (args.size() != 1)
|
if (args.size() != 1)
|
||||||
throw UsageError("'--remove' requires one argument");
|
throw UsageError("‘--remove’ requires one argument");
|
||||||
removeChannel(args[0]);
|
removeChannel(args[0]);
|
||||||
break;
|
break;
|
||||||
case cList:
|
case cList:
|
||||||
if (!args.empty())
|
if (!args.empty())
|
||||||
throw UsageError("'--list' expects no arguments");
|
throw UsageError("‘--list’ expects no arguments");
|
||||||
readChannels();
|
readChannels();
|
||||||
for (const auto & channel : channels)
|
for (const auto & channel : channels)
|
||||||
std::cout << channel.first << ' ' << channel.second << '\n';
|
std::cout << channel.first << ' ' << channel.second << '\n';
|
||||||
|
@ -255,7 +255,7 @@ int main(int argc, char ** argv)
|
||||||
break;
|
break;
|
||||||
case cRollback:
|
case cRollback:
|
||||||
if (args.size() > 1)
|
if (args.size() > 1)
|
||||||
throw UsageError("'--rollback' has at most one argument");
|
throw UsageError("‘--rollback’ has at most one argument");
|
||||||
auto envArgs = Strings{"--profile", profile};
|
auto envArgs = Strings{"--profile", profile};
|
||||||
if (args.size() == 1) {
|
if (args.size() == 1) {
|
||||||
envArgs.push_back("--switch-generation");
|
envArgs.push_back("--switch-generation");
|
||||||
|
|
|
@ -648,7 +648,7 @@ static void processConnection(bool trusted)
|
||||||
/* Prevent users from doing something very dangerous. */
|
/* Prevent users from doing something very dangerous. */
|
||||||
if (geteuid() == 0 &&
|
if (geteuid() == 0 &&
|
||||||
querySetting("build-users-group", "") == "")
|
querySetting("build-users-group", "") == "")
|
||||||
throw Error("if you run 'nix-daemon' as root, then you MUST set 'build-users-group'!");
|
throw Error("if you run ‘nix-daemon’ as root, then you MUST set ‘build-users-group’!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Open the store. */
|
/* Open the store. */
|
||||||
|
@ -829,7 +829,7 @@ static void daemonLoop(char * * argv)
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
addr.sun_family = AF_UNIX;
|
addr.sun_family = AF_UNIX;
|
||||||
if (socketPathRel.size() >= sizeof(addr.sun_path))
|
if (socketPathRel.size() >= sizeof(addr.sun_path))
|
||||||
throw Error(format("socket path '%1%' is too long") % socketPathRel);
|
throw Error(format("socket path ‘%1%’ is too long") % socketPathRel);
|
||||||
strcpy(addr.sun_path, socketPathRel.c_str());
|
strcpy(addr.sun_path, socketPathRel.c_str());
|
||||||
|
|
||||||
unlink(socketPath.c_str());
|
unlink(socketPath.c_str());
|
||||||
|
@ -841,13 +841,13 @@ static void daemonLoop(char * * argv)
|
||||||
int res = bind(fdSocket.get(), (struct sockaddr *) &addr, sizeof(addr));
|
int res = bind(fdSocket.get(), (struct sockaddr *) &addr, sizeof(addr));
|
||||||
umask(oldMode);
|
umask(oldMode);
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
throw SysError(format("cannot bind to socket '%1%'") % socketPath);
|
throw SysError(format("cannot bind to socket ‘%1%’") % socketPath);
|
||||||
|
|
||||||
if (chdir("/") == -1) /* back to the root */
|
if (chdir("/") == -1) /* back to the root */
|
||||||
throw SysError("cannot change current directory");
|
throw SysError("cannot change current directory");
|
||||||
|
|
||||||
if (listen(fdSocket.get(), 5) == -1)
|
if (listen(fdSocket.get(), 5) == -1)
|
||||||
throw SysError(format("cannot listen on socket '%1%'") % socketPath);
|
throw SysError(format("cannot listen on socket ‘%1%’") % socketPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
closeOnExec(fdSocket.get());
|
closeOnExec(fdSocket.get());
|
||||||
|
@ -886,7 +886,7 @@ static void daemonLoop(char * * argv)
|
||||||
trusted = true;
|
trusted = true;
|
||||||
|
|
||||||
if (!trusted && !matchUser(user, group, allowedUsers))
|
if (!trusted && !matchUser(user, group, allowedUsers))
|
||||||
throw Error(format("user '%1%' is not allowed to connect to the Nix daemon") % user);
|
throw Error(format("user ‘%1%’ is not allowed to connect to the Nix daemon") % user);
|
||||||
|
|
||||||
printInfo(format((string) "accepted connection from pid %1%, user %2%" + (trusted ? " (trusted)" : ""))
|
printInfo(format((string) "accepted connection from pid %1%, user %2%" + (trusted ? " (trusted)" : ""))
|
||||||
% (peer.pidKnown ? std::to_string(peer.pid) : "<unknown>")
|
% (peer.pidKnown ? std::to_string(peer.pid) : "<unknown>")
|
||||||
|
@ -961,7 +961,7 @@ int main(int argc, char * * argv)
|
||||||
|
|
||||||
auto socketDir = dirOf(socketPath);
|
auto socketDir = dirOf(socketPath);
|
||||||
if (chdir(socketDir.c_str()) == -1)
|
if (chdir(socketDir.c_str()) == -1)
|
||||||
throw SysError(format("changing to socket directory '%1%'") % socketDir);
|
throw SysError(format("changing to socket directory ‘%1%’") % socketDir);
|
||||||
|
|
||||||
auto socketName = baseNameOf(socketPath);
|
auto socketName = baseNameOf(socketPath);
|
||||||
auto addr = sockaddr_un{};
|
auto addr = sockaddr_un{};
|
||||||
|
|
|
@ -70,7 +70,7 @@ static string needArg(Strings::iterator & i,
|
||||||
Strings & args, const string & arg)
|
Strings & args, const string & arg)
|
||||||
{
|
{
|
||||||
if (i == args.end()) throw UsageError(
|
if (i == args.end()) throw UsageError(
|
||||||
format("'%1%' requires an argument") % arg);
|
format("‘%1%’ requires an argument") % arg);
|
||||||
return *i++;
|
return *i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ static void getAllExprs(EvalState & state,
|
||||||
if (hasSuffix(attrName, ".nix"))
|
if (hasSuffix(attrName, ".nix"))
|
||||||
attrName = string(attrName, 0, attrName.size() - 4);
|
attrName = string(attrName, 0, attrName.size() - 4);
|
||||||
if (attrs.find(attrName) != attrs.end()) {
|
if (attrs.find(attrName) != attrs.end()) {
|
||||||
printError(format("warning: name collision in input Nix expressions, skipping '%1%'") % path2);
|
printError(format("warning: name collision in input Nix expressions, skipping ‘%1%’") % path2);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
attrs.insert(attrName);
|
attrs.insert(attrName);
|
||||||
|
@ -133,7 +133,7 @@ static void getAllExprs(EvalState & state,
|
||||||
Value & vArg(*state.allocValue());
|
Value & vArg(*state.allocValue());
|
||||||
mkString(vArg, path2);
|
mkString(vArg, path2);
|
||||||
if (v.attrs->size() == v.attrs->capacity())
|
if (v.attrs->size() == v.attrs->capacity())
|
||||||
throw Error(format("too many Nix expressions in directory '%1%'") % path);
|
throw Error(format("too many Nix expressions in directory ‘%1%’") % path);
|
||||||
mkApp(*state.allocAttr(v, state.symbols.create(attrName)), vFun, vArg);
|
mkApp(*state.allocAttr(v, state.symbols.create(attrName)), vFun, vArg);
|
||||||
}
|
}
|
||||||
else if (S_ISDIR(st.st_mode))
|
else if (S_ISDIR(st.st_mode))
|
||||||
|
@ -148,7 +148,7 @@ static void loadSourceExpr(EvalState & state, const Path & path, Value & v)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(path.c_str(), &st) == -1)
|
if (stat(path.c_str(), &st) == -1)
|
||||||
throw SysError(format("getting information about '%1%'") % path);
|
throw SysError(format("getting information about ‘%1%’") % path);
|
||||||
|
|
||||||
if (isNixExpr(path, st)) {
|
if (isNixExpr(path, st)) {
|
||||||
state.evalFile(path, v);
|
state.evalFile(path, v);
|
||||||
|
@ -234,7 +234,7 @@ static void checkSelectorUse(DrvNames & selectors)
|
||||||
/* Check that all selectors have been used. */
|
/* Check that all selectors have been used. */
|
||||||
for (auto & i : selectors)
|
for (auto & i : selectors)
|
||||||
if (i.hits == 0 && i.fullName != "*")
|
if (i.hits == 0 && i.fullName != "*")
|
||||||
throw Error(format("selector '%1%' matches no derivations") % i.fullName);
|
throw Error(format("selector ‘%1%’ matches no derivations") % i.fullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -305,7 +305,7 @@ static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems,
|
||||||
for (auto & j : newest) {
|
for (auto & j : newest) {
|
||||||
if (multiple.find(j.second.first.name) != multiple.end())
|
if (multiple.find(j.second.first.name) != multiple.end())
|
||||||
printInfo(
|
printInfo(
|
||||||
format("warning: there are multiple derivations named '%1%'; using the first one")
|
format("warning: there are multiple derivations named ‘%1%’; using the first one")
|
||||||
% j.second.first.name);
|
% j.second.first.name);
|
||||||
matches.push_back(j.second);
|
matches.push_back(j.second);
|
||||||
}
|
}
|
||||||
|
@ -496,13 +496,13 @@ static void installDerivations(Globals & globals,
|
||||||
if (!globals.preserveInstalled &&
|
if (!globals.preserveInstalled &&
|
||||||
newNames.find(drvName.name) != newNames.end() &&
|
newNames.find(drvName.name) != newNames.end() &&
|
||||||
!keep(i))
|
!keep(i))
|
||||||
printInfo(format("replacing old '%1%'") % i.name);
|
printInfo(format("replacing old ‘%1%’") % i.name);
|
||||||
else
|
else
|
||||||
allElems.push_back(i);
|
allElems.push_back(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto & i : newElems)
|
for (auto & i : newElems)
|
||||||
printInfo(format("installing '%1%'") % i.name);
|
printInfo(format("installing ‘%1%’") % i.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
printMissing(*globals.state, newElems);
|
printMissing(*globals.state, newElems);
|
||||||
|
@ -524,7 +524,7 @@ static void opInstall(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
globals.preserveInstalled = true;
|
globals.preserveInstalled = true;
|
||||||
else if (arg == "--remove-all" || arg == "-r")
|
else if (arg == "--remove-all" || arg == "-r")
|
||||||
globals.removeAll = true;
|
globals.removeAll = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % arg);
|
else throw UsageError(format("unknown flag ‘%1%’") % arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
installDerivations(globals, opArgs, globals.profile);
|
installDerivations(globals, opArgs, globals.profile);
|
||||||
|
@ -605,13 +605,13 @@ static void upgradeDerivations(Globals & globals,
|
||||||
const char * action = compareVersions(drvName.version, bestVersion) <= 0
|
const char * action = compareVersions(drvName.version, bestVersion) <= 0
|
||||||
? "upgrading" : "downgrading";
|
? "upgrading" : "downgrading";
|
||||||
printInfo(
|
printInfo(
|
||||||
format("%1% '%2%' to '%3%'")
|
format("%1% ‘%2%’ to ‘%3%’")
|
||||||
% action % i.name % bestElem->name);
|
% action % i.name % bestElem->name);
|
||||||
newElems.push_back(*bestElem);
|
newElems.push_back(*bestElem);
|
||||||
} else newElems.push_back(i);
|
} else newElems.push_back(i);
|
||||||
|
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addPrefix(format("while trying to find an upgrade for '%1%':\n") % i.name);
|
e.addPrefix(format("while trying to find an upgrade for ‘%1%’:\n") % i.name);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -636,7 +636,7 @@ static void opUpgrade(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
else if (arg == "--leq") upgradeType = utLeq;
|
else if (arg == "--leq") upgradeType = utLeq;
|
||||||
else if (arg == "--eq") upgradeType = utEq;
|
else if (arg == "--eq") upgradeType = utEq;
|
||||||
else if (arg == "--always") upgradeType = utAlways;
|
else if (arg == "--always") upgradeType = utAlways;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % arg);
|
else throw UsageError(format("unknown flag ‘%1%’") % arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
upgradeDerivations(globals, opArgs, upgradeType);
|
upgradeDerivations(globals, opArgs, upgradeType);
|
||||||
|
@ -655,9 +655,9 @@ static void setMetaFlag(EvalState & state, DrvInfo & drv,
|
||||||
static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs)
|
static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (opFlags.size() > 0)
|
if (opFlags.size() > 0)
|
||||||
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
|
throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
|
||||||
if (opArgs.size() < 2)
|
if (opArgs.size() < 2)
|
||||||
throw UsageError("not enough arguments to '--set-flag'");
|
throw UsageError("not enough arguments to ‘--set-flag’");
|
||||||
|
|
||||||
Strings::iterator arg = opArgs.begin();
|
Strings::iterator arg = opArgs.begin();
|
||||||
string flagName = *arg++;
|
string flagName = *arg++;
|
||||||
|
@ -674,7 +674,7 @@ static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
DrvName drvName(i.name);
|
DrvName drvName(i.name);
|
||||||
for (auto & j : selectors)
|
for (auto & j : selectors)
|
||||||
if (j.matches(drvName)) {
|
if (j.matches(drvName)) {
|
||||||
printInfo(format("setting flag on '%1%'") % i.name);
|
printInfo(format("setting flag on ‘%1%’") % i.name);
|
||||||
j.hits++;
|
j.hits++;
|
||||||
setMetaFlag(*globals.state, i, flagName, flagValue);
|
setMetaFlag(*globals.state, i, flagName, flagValue);
|
||||||
break;
|
break;
|
||||||
|
@ -698,7 +698,7 @@ static void opSet(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
|
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
|
||||||
string arg = *i++;
|
string arg = *i++;
|
||||||
if (parseInstallSourceOptions(globals, i, opFlags, arg)) ;
|
if (parseInstallSourceOptions(globals, i, opFlags, arg)) ;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % arg);
|
else throw UsageError(format("unknown flag ‘%1%’") % arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrvInfos elems;
|
DrvInfos elems;
|
||||||
|
@ -748,7 +748,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
|
||||||
if ((isPath(j) && i.queryOutPath() == globals.state->store->followLinksToStorePath(j))
|
if ((isPath(j) && i.queryOutPath() == globals.state->store->followLinksToStorePath(j))
|
||||||
|| DrvName(j).matches(drvName))
|
|| DrvName(j).matches(drvName))
|
||||||
{
|
{
|
||||||
printInfo(format("uninstalling '%1%'") % i.name);
|
printInfo(format("uninstalling ‘%1%’") % i.name);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -766,7 +766,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
|
||||||
static void opUninstall(Globals & globals, Strings opFlags, Strings opArgs)
|
static void opUninstall(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (opFlags.size() > 0)
|
if (opFlags.size() > 0)
|
||||||
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
|
throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
|
||||||
uninstallDerivations(globals, opArgs, globals.profile);
|
uninstallDerivations(globals, opArgs, globals.profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -874,7 +874,7 @@ static void queryJSON(Globals & globals, vector<DrvInfo> & elems)
|
||||||
auto placeholder = metaObj.placeholder(j);
|
auto placeholder = metaObj.placeholder(j);
|
||||||
Value * v = i.queryMeta(j);
|
Value * v = i.queryMeta(j);
|
||||||
if (!v) {
|
if (!v) {
|
||||||
printError(format("derivation '%1%' has invalid meta attribute '%2%'") % i.name % j);
|
printError(format("derivation ‘%1%’ has invalid meta attribute ‘%2%’") % i.name % j);
|
||||||
placeholder.write(nullptr);
|
placeholder.write(nullptr);
|
||||||
} else {
|
} else {
|
||||||
PathSet context;
|
PathSet context;
|
||||||
|
@ -924,7 +924,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
else if (arg == "--attr" || arg == "-A")
|
else if (arg == "--attr" || arg == "-A")
|
||||||
attrPath = needArg(i, opFlags, arg);
|
attrPath = needArg(i, opFlags, arg);
|
||||||
else
|
else
|
||||||
throw UsageError(format("unknown flag '%1%'") % arg);
|
throw UsageError(format("unknown flag ‘%1%’") % arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -971,7 +971,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
try {
|
try {
|
||||||
paths.insert(i.queryOutPath());
|
paths.insert(i.queryOutPath());
|
||||||
} catch (AssertionError & e) {
|
} catch (AssertionError & e) {
|
||||||
printMsg(lvlTalkative, format("skipping derivation named '%1%' which gives an assertion failure") % i.name);
|
printMsg(lvlTalkative, format("skipping derivation named ‘%1%’ which gives an assertion failure") % i.name);
|
||||||
i.setFailed();
|
i.setFailed();
|
||||||
}
|
}
|
||||||
validPaths = globals.state->store->queryValidPaths(paths);
|
validPaths = globals.state->store->queryValidPaths(paths);
|
||||||
|
@ -997,7 +997,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
try {
|
try {
|
||||||
if (i.hasFailed()) continue;
|
if (i.hasFailed()) continue;
|
||||||
|
|
||||||
Activity act(*logger, lvlDebug, format("outputting query result '%1%'") % i.attrPath);
|
Activity act(*logger, lvlDebug, format("outputting query result ‘%1%’") % i.attrPath);
|
||||||
|
|
||||||
if (globals.prebuiltOnly &&
|
if (globals.prebuiltOnly &&
|
||||||
validPaths.find(i.queryOutPath()) == validPaths.end() &&
|
validPaths.find(i.queryOutPath()) == validPaths.end() &&
|
||||||
|
@ -1118,7 +1118,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
attrs2["name"] = j;
|
attrs2["name"] = j;
|
||||||
Value * v = i.queryMeta(j);
|
Value * v = i.queryMeta(j);
|
||||||
if (!v)
|
if (!v)
|
||||||
printError(format("derivation '%1%' has invalid meta attribute '%2%'") % i.name % j);
|
printError(format("derivation ‘%1%’ has invalid meta attribute ‘%2%’") % i.name % j);
|
||||||
else {
|
else {
|
||||||
if (v->type == tString) {
|
if (v->type == tString) {
|
||||||
attrs2["type"] = "string";
|
attrs2["type"] = "string";
|
||||||
|
@ -1169,9 +1169,9 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
cout.flush();
|
cout.flush();
|
||||||
|
|
||||||
} catch (AssertionError & e) {
|
} catch (AssertionError & e) {
|
||||||
printMsg(lvlTalkative, format("skipping derivation named '%1%' which gives an assertion failure") % i.name);
|
printMsg(lvlTalkative, format("skipping derivation named ‘%1%’ which gives an assertion failure") % i.name);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addPrefix(format("while querying the derivation named '%1%':\n") % i.name);
|
e.addPrefix(format("while querying the derivation named ‘%1%’:\n") % i.name);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1183,7 +1183,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
static void opSwitchProfile(Globals & globals, Strings opFlags, Strings opArgs)
|
static void opSwitchProfile(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (opFlags.size() > 0)
|
if (opFlags.size() > 0)
|
||||||
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
|
throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
|
||||||
if (opArgs.size() != 1)
|
if (opArgs.size() != 1)
|
||||||
throw UsageError(format("exactly one argument expected"));
|
throw UsageError(format("exactly one argument expected"));
|
||||||
|
|
||||||
|
@ -1231,7 +1231,7 @@ static void switchGeneration(Globals & globals, int dstGen)
|
||||||
static void opSwitchGeneration(Globals & globals, Strings opFlags, Strings opArgs)
|
static void opSwitchGeneration(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (opFlags.size() > 0)
|
if (opFlags.size() > 0)
|
||||||
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
|
throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
|
||||||
if (opArgs.size() != 1)
|
if (opArgs.size() != 1)
|
||||||
throw UsageError(format("exactly one argument expected"));
|
throw UsageError(format("exactly one argument expected"));
|
||||||
|
|
||||||
|
@ -1246,7 +1246,7 @@ static void opSwitchGeneration(Globals & globals, Strings opFlags, Strings opArg
|
||||||
static void opRollback(Globals & globals, Strings opFlags, Strings opArgs)
|
static void opRollback(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (opFlags.size() > 0)
|
if (opFlags.size() > 0)
|
||||||
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
|
throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
|
||||||
if (opArgs.size() != 0)
|
if (opArgs.size() != 0)
|
||||||
throw UsageError(format("no arguments expected"));
|
throw UsageError(format("no arguments expected"));
|
||||||
|
|
||||||
|
@ -1257,7 +1257,7 @@ static void opRollback(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
static void opListGenerations(Globals & globals, Strings opFlags, Strings opArgs)
|
static void opListGenerations(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (opFlags.size() > 0)
|
if (opFlags.size() > 0)
|
||||||
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
|
throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
|
||||||
if (opArgs.size() != 0)
|
if (opArgs.size() != 0)
|
||||||
throw UsageError(format("no arguments expected"));
|
throw UsageError(format("no arguments expected"));
|
||||||
|
|
||||||
|
@ -1284,7 +1284,7 @@ static void opListGenerations(Globals & globals, Strings opFlags, Strings opArgs
|
||||||
static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opArgs)
|
static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (opFlags.size() > 0)
|
if (opFlags.size() > 0)
|
||||||
throw UsageError(format("unknown flag '%1%'") % opFlags.front());
|
throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
|
||||||
|
|
||||||
if (opArgs.size() == 1 && opArgs.front() == "old") {
|
if (opArgs.size() == 1 && opArgs.front() == "old") {
|
||||||
deleteOldGenerations(globals.profile, globals.dryRun);
|
deleteOldGenerations(globals.profile, globals.dryRun);
|
||||||
|
@ -1295,7 +1295,7 @@ static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opAr
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
if (!string2Int(i, n))
|
if (!string2Int(i, n))
|
||||||
throw UsageError(format("invalid generation number '%1%'") % i);
|
throw UsageError(format("invalid generation number ‘%1%’") % i);
|
||||||
gens.insert(n);
|
gens.insert(n);
|
||||||
}
|
}
|
||||||
deleteGenerations(globals.profile, gens, globals.dryRun);
|
deleteGenerations(globals.profile, gens, globals.dryRun);
|
||||||
|
|
|
@ -139,7 +139,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
|
||||||
|
|
||||||
Path lockTokenCur = optimisticLockProfile(profile);
|
Path lockTokenCur = optimisticLockProfile(profile);
|
||||||
if (lockToken != lockTokenCur) {
|
if (lockToken != lockTokenCur) {
|
||||||
printError(format("profile '%1%' changed while we were busy; restarting") % profile);
|
printError(format("profile ‘%1%’ changed while we were busy; restarting") % profile);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ void processExpr(EvalState & state, const Strings & attrPaths,
|
||||||
/* What output do we want? */
|
/* What output do we want? */
|
||||||
string outputName = i.queryOutputName();
|
string outputName = i.queryOutputName();
|
||||||
if (outputName == "")
|
if (outputName == "")
|
||||||
throw Error(format("derivation '%1%' lacks an 'outputName' attribute ") % drvPath);
|
throw Error(format("derivation ‘%1%’ lacks an ‘outputName’ attribute ") % drvPath);
|
||||||
|
|
||||||
if (gcRoot == "")
|
if (gcRoot == "")
|
||||||
printGCWarning();
|
printGCWarning();
|
||||||
|
@ -171,7 +171,7 @@ int main(int argc, char * * argv)
|
||||||
if (findFile) {
|
if (findFile) {
|
||||||
for (auto & i : files) {
|
for (auto & i : files) {
|
||||||
Path p = state.findFile(i);
|
Path p = state.findFile(i);
|
||||||
if (p == "") throw Error(format("unable to find '%1%'") % i);
|
if (p == "") throw Error(format("unable to find ‘%1%’") % i);
|
||||||
std::cout << p << std::endl;
|
std::cout << p << std::endl;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
|
|
||||||
|
|
||||||
/* If 'uri' starts with 'mirror://', then resolve it using the list of
|
/* If ‘uri’ starts with ‘mirror://’, then resolve it using the list of
|
||||||
mirrors defined in Nixpkgs. */
|
mirrors defined in Nixpkgs. */
|
||||||
string resolveMirrorUri(EvalState & state, string uri)
|
string resolveMirrorUri(EvalState & state, string uri)
|
||||||
{
|
{
|
||||||
|
@ -29,11 +29,11 @@ string resolveMirrorUri(EvalState & state, string uri)
|
||||||
|
|
||||||
auto mirrorList = vMirrors.attrs->find(state.symbols.create(mirrorName));
|
auto mirrorList = vMirrors.attrs->find(state.symbols.create(mirrorName));
|
||||||
if (mirrorList == vMirrors.attrs->end())
|
if (mirrorList == vMirrors.attrs->end())
|
||||||
throw Error(format("unknown mirror name '%1%'") % mirrorName);
|
throw Error(format("unknown mirror name ‘%1%’") % mirrorName);
|
||||||
state.forceList(*mirrorList->value);
|
state.forceList(*mirrorList->value);
|
||||||
|
|
||||||
if (mirrorList->value->listSize() < 1)
|
if (mirrorList->value->listSize() < 1)
|
||||||
throw Error(format("mirror URI '%1%' did not expand to anything") % uri);
|
throw Error(format("mirror URI ‘%1%’ did not expand to anything") % uri);
|
||||||
|
|
||||||
string mirror = state.forceString(*mirrorList->value->listElems()[0]);
|
string mirror = state.forceString(*mirrorList->value->listElems()[0]);
|
||||||
return mirror + (hasSuffix(mirror, "/") ? "" : "/") + string(s, p + 1);
|
return mirror + (hasSuffix(mirror, "/") ? "" : "/") + string(s, p + 1);
|
||||||
|
@ -65,7 +65,7 @@ int main(int argc, char * * argv)
|
||||||
string s = getArg(*arg, arg, end);
|
string s = getArg(*arg, arg, end);
|
||||||
ht = parseHashType(s);
|
ht = parseHashType(s);
|
||||||
if (ht == htUnknown)
|
if (ht == htUnknown)
|
||||||
throw UsageError(format("unknown hash type '%1%'") % s);
|
throw UsageError(format("unknown hash type ‘%1%’") % s);
|
||||||
}
|
}
|
||||||
else if (*arg == "--print-path")
|
else if (*arg == "--print-path")
|
||||||
printPath = true;
|
printPath = true;
|
||||||
|
@ -113,10 +113,10 @@ int main(int argc, char * * argv)
|
||||||
/* Extract the URI. */
|
/* Extract the URI. */
|
||||||
auto attr = v.attrs->find(state.symbols.create("urls"));
|
auto attr = v.attrs->find(state.symbols.create("urls"));
|
||||||
if (attr == v.attrs->end())
|
if (attr == v.attrs->end())
|
||||||
throw Error("attribute set does not contain a 'urls' attribute");
|
throw Error("attribute set does not contain a ‘urls’ attribute");
|
||||||
state.forceList(*attr->value);
|
state.forceList(*attr->value);
|
||||||
if (attr->value->listSize() < 1)
|
if (attr->value->listSize() < 1)
|
||||||
throw Error("'urls' list is empty");
|
throw Error("‘urls’ list is empty");
|
||||||
uri = state.forceString(*attr->value->listElems()[0]);
|
uri = state.forceString(*attr->value->listElems()[0]);
|
||||||
|
|
||||||
/* Extract the hash mode. */
|
/* Extract the hash mode. */
|
||||||
|
@ -138,7 +138,7 @@ int main(int argc, char * * argv)
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
name = baseNameOf(uri);
|
name = baseNameOf(uri);
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
throw Error(format("cannot figure out file name for '%1%'") % uri);
|
throw Error(format("cannot figure out file name for ‘%1%’") % uri);
|
||||||
|
|
||||||
/* If an expected hash is given, the file may already exist in
|
/* If an expected hash is given, the file may already exist in
|
||||||
the store. */
|
the store. */
|
||||||
|
@ -189,7 +189,7 @@ int main(int argc, char * * argv)
|
||||||
hash = unpack ? hashPath(ht, tmpFile).first : hashString(ht, *result.data);
|
hash = unpack ? hashPath(ht, tmpFile).first : hashString(ht, *result.data);
|
||||||
|
|
||||||
if (expectedHash != Hash(ht) && expectedHash != hash)
|
if (expectedHash != Hash(ht) && expectedHash != hash)
|
||||||
throw Error(format("hash mismatch for '%1%'") % uri);
|
throw Error(format("hash mismatch for ‘%1%’") % uri);
|
||||||
|
|
||||||
/* Copy the file to the Nix store. FIXME: if RemoteStore
|
/* Copy the file to the Nix store. FIXME: if RemoteStore
|
||||||
implemented addToStoreFromDump() and downloadFile()
|
implemented addToStoreFromDump() and downloadFile()
|
||||||
|
@ -201,7 +201,7 @@ int main(int argc, char * * argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!printPath)
|
if (!printPath)
|
||||||
printInfo(format("path is '%1%'") % storePath);
|
printInfo(format("path is ‘%1%’") % storePath);
|
||||||
|
|
||||||
std::cout << printHash16or32(hash) << std::endl;
|
std::cout << printHash16or32(hash) << std::endl;
|
||||||
if (printPath)
|
if (printPath)
|
||||||
|
|
|
@ -77,7 +77,7 @@ void printClosure(const Path & nePath, const StoreExpr & fs)
|
||||||
|
|
||||||
ClosureElems::const_iterator elem = fs.closure.elems.find(path);
|
ClosureElems::const_iterator elem = fs.closure.elems.find(path);
|
||||||
if (elem == fs.closure.elems.end())
|
if (elem == fs.closure.elems.end())
|
||||||
throw Error(format("bad closure, missing path '%1%'") % path);
|
throw Error(format("bad closure, missing path ‘%1%’") % path);
|
||||||
|
|
||||||
for (StringSet::const_iterator i = elem->second.refs.begin();
|
for (StringSet::const_iterator i = elem->second.refs.begin();
|
||||||
i != elem->second.refs.end(); ++i)
|
i != elem->second.refs.end(); ++i)
|
||||||
|
|
|
@ -52,7 +52,7 @@ static Path useDeriver(Path path)
|
||||||
if (isDerivation(path)) return path;
|
if (isDerivation(path)) return path;
|
||||||
Path drvPath = store->queryPathInfo(path)->deriver;
|
Path drvPath = store->queryPathInfo(path)->deriver;
|
||||||
if (drvPath == "")
|
if (drvPath == "")
|
||||||
throw Error(format("deriver of path '%1%' is not known") % path);
|
throw Error(format("deriver of path ‘%1%’ is not known") % path);
|
||||||
return drvPath;
|
return drvPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ static PathSet realisePath(Path path, bool build = true)
|
||||||
for (auto & j : p.second) {
|
for (auto & j : p.second) {
|
||||||
DerivationOutputs::iterator i = drv.outputs.find(j);
|
DerivationOutputs::iterator i = drv.outputs.find(j);
|
||||||
if (i == drv.outputs.end())
|
if (i == drv.outputs.end())
|
||||||
throw Error(format("derivation '%1%' does not have an output named '%2%'") % p.first % j);
|
throw Error(format("derivation ‘%1%’ does not have an output named ‘%2%’") % p.first % j);
|
||||||
Path outPath = i->second.path;
|
Path outPath = i->second.path;
|
||||||
if (store2) {
|
if (store2) {
|
||||||
if (gcRoot == "")
|
if (gcRoot == "")
|
||||||
|
@ -96,7 +96,7 @@ static PathSet realisePath(Path path, bool build = true)
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (build) store->ensurePath(path);
|
if (build) store->ensurePath(path);
|
||||||
else if (!store->isValidPath(path)) throw Error(format("path '%1%' does not exist and cannot be created") % path);
|
else if (!store->isValidPath(path)) throw Error(format("path ‘%1%’ does not exist and cannot be created") % path);
|
||||||
if (store2) {
|
if (store2) {
|
||||||
if (gcRoot == "")
|
if (gcRoot == "")
|
||||||
printGCWarning();
|
printGCWarning();
|
||||||
|
@ -125,7 +125,7 @@ static void opRealise(Strings opFlags, Strings opArgs)
|
||||||
else if (i == "--check") buildMode = bmCheck;
|
else if (i == "--check") buildMode = bmCheck;
|
||||||
else if (i == "--hash") buildMode = bmHash;
|
else if (i == "--hash") buildMode = bmHash;
|
||||||
else if (i == "--ignore-unknown") ignoreUnknown = true;
|
else if (i == "--ignore-unknown") ignoreUnknown = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
Paths paths;
|
Paths paths;
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
|
@ -182,7 +182,7 @@ static void opAddFixed(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--recursive") recursive = true;
|
if (i == "--recursive") recursive = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
if (opArgs.empty())
|
if (opArgs.empty())
|
||||||
throw UsageError("first argument must be hash algorithm");
|
throw UsageError("first argument must be hash algorithm");
|
||||||
|
@ -202,10 +202,10 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
for (auto i : opFlags)
|
for (auto i : opFlags)
|
||||||
if (i == "--recursive") recursive = true;
|
if (i == "--recursive") recursive = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
if (opArgs.size() != 3)
|
if (opArgs.size() != 3)
|
||||||
throw UsageError(format("'--print-fixed-path' requires three arguments"));
|
throw UsageError(format("‘--print-fixed-path’ requires three arguments"));
|
||||||
|
|
||||||
Strings::iterator i = opArgs.begin();
|
Strings::iterator i = opArgs.begin();
|
||||||
HashType hashAlgo = parseHashType(*i++);
|
HashType hashAlgo = parseHashType(*i++);
|
||||||
|
@ -307,9 +307,9 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
else if (i == "--use-output" || i == "-u") useOutput = true;
|
else if (i == "--use-output" || i == "-u") useOutput = true;
|
||||||
else if (i == "--force-realise" || i == "--force-realize" || i == "-f") forceRealise = true;
|
else if (i == "--force-realise" || i == "--force-realize" || i == "-f") forceRealise = true;
|
||||||
else if (i == "--include-outputs") includeOutputs = true;
|
else if (i == "--include-outputs") includeOutputs = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
if (prev != qDefault && prev != query)
|
if (prev != qDefault && prev != query)
|
||||||
throw UsageError(format("query type '%1%' conflicts with earlier flag") % i);
|
throw UsageError(format("query type ‘%1%’ conflicts with earlier flag") % i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query == qDefault) query = qOutputs;
|
if (query == qDefault) query = qOutputs;
|
||||||
|
@ -367,7 +367,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
Derivation drv = store->derivationFromPath(path);
|
Derivation drv = store->derivationFromPath(path);
|
||||||
StringPairs::iterator j = drv.env.find(bindingName);
|
StringPairs::iterator j = drv.env.find(bindingName);
|
||||||
if (j == drv.env.end())
|
if (j == drv.env.end())
|
||||||
throw Error(format("derivation '%1%' has no environment binding named '%2%'")
|
throw Error(format("derivation ‘%1%’ has no environment binding named ‘%2%’")
|
||||||
% path % bindingName);
|
% path % bindingName);
|
||||||
cout << format("%1%\n") % j->second;
|
cout << format("%1%\n") % j->second;
|
||||||
}
|
}
|
||||||
|
@ -453,7 +453,7 @@ static string shellEscape(const string & s)
|
||||||
static void opPrintEnv(Strings opFlags, Strings opArgs)
|
static void opPrintEnv(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (!opFlags.empty()) throw UsageError("unknown flag");
|
if (!opFlags.empty()) throw UsageError("unknown flag");
|
||||||
if (opArgs.size() != 1) throw UsageError("'--print-env' requires one derivation store path");
|
if (opArgs.size() != 1) throw UsageError("‘--print-env’ requires one derivation store path");
|
||||||
|
|
||||||
Path drvPath = opArgs.front();
|
Path drvPath = opArgs.front();
|
||||||
Derivation drv = store->derivationFromPath(drvPath);
|
Derivation drv = store->derivationFromPath(drvPath);
|
||||||
|
@ -484,7 +484,7 @@ static void opReadLog(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
// FIXME: move getting logs into Store.
|
// FIXME: move getting logs into Store.
|
||||||
auto store2 = std::dynamic_pointer_cast<LocalFSStore>(store);
|
auto store2 = std::dynamic_pointer_cast<LocalFSStore>(store);
|
||||||
if (!store2) throw Error(format("store '%s' does not support reading logs") % store->getUri());
|
if (!store2) throw Error(format("store ‘%s’ does not support reading logs") % store->getUri());
|
||||||
|
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
Path path = useDeriver(store->followLinksToStorePath(i));
|
Path path = useDeriver(store->followLinksToStorePath(i));
|
||||||
|
@ -533,7 +533,7 @@ static void opReadLog(Strings opFlags, Strings opArgs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) throw Error(format("build log of derivation '%1%' is not available") % path);
|
if (!found) throw Error(format("build log of derivation ‘%1%’ is not available") % path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,7 +590,7 @@ static void opRegisterValidity(Strings opFlags, Strings opArgs)
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--reregister") reregister = true;
|
if (i == "--reregister") reregister = true;
|
||||||
else if (i == "--hash-given") hashGiven = true;
|
else if (i == "--hash-given") hashGiven = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
||||||
|
|
||||||
|
@ -604,7 +604,7 @@ static void opCheckValidity(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--print-invalid") printInvalid = true;
|
if (i == "--print-invalid") printInvalid = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
Path path = store->followLinksToStorePath(i);
|
Path path = store->followLinksToStorePath(i);
|
||||||
|
@ -612,7 +612,7 @@ static void opCheckValidity(Strings opFlags, Strings opArgs)
|
||||||
if (printInvalid)
|
if (printInvalid)
|
||||||
cout << format("%1%\n") % path;
|
cout << format("%1%\n") % path;
|
||||||
else
|
else
|
||||||
throw Error(format("path '%1%' is not valid") % path);
|
throw Error(format("path ‘%1%’ is not valid") % path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -636,7 +636,7 @@ static void opGC(Strings opFlags, Strings opArgs)
|
||||||
long long maxFreed = getIntArg<long long>(*i, i, opFlags.end(), true);
|
long long maxFreed = getIntArg<long long>(*i, i, opFlags.end(), true);
|
||||||
options.maxFreed = maxFreed >= 0 ? maxFreed : 0;
|
options.maxFreed = maxFreed >= 0 ? maxFreed : 0;
|
||||||
}
|
}
|
||||||
else throw UsageError(format("bad sub-operation '%1%' in GC") % *i);
|
else throw UsageError(format("bad sub-operation ‘%1%’ in GC") % *i);
|
||||||
|
|
||||||
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
||||||
|
|
||||||
|
@ -667,7 +667,7 @@ static void opDelete(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--ignore-liveness") options.ignoreLiveness = true;
|
if (i == "--ignore-liveness") options.ignoreLiveness = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
for (auto & i : opArgs)
|
for (auto & i : opArgs)
|
||||||
options.pathsToDelete.insert(store->followLinksToStorePath(i));
|
options.pathsToDelete.insert(store->followLinksToStorePath(i));
|
||||||
|
@ -706,7 +706,7 @@ static void opRestore(Strings opFlags, Strings opArgs)
|
||||||
static void opExport(Strings opFlags, Strings opArgs)
|
static void opExport(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
throw UsageError(format("unknown flag '%1%'") % i);
|
throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
FdSink sink(STDOUT_FILENO);
|
FdSink sink(STDOUT_FILENO);
|
||||||
store->exportPaths(opArgs, sink);
|
store->exportPaths(opArgs, sink);
|
||||||
|
@ -716,7 +716,7 @@ static void opExport(Strings opFlags, Strings opArgs)
|
||||||
static void opImport(Strings opFlags, Strings opArgs)
|
static void opImport(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
throw UsageError(format("unknown flag '%1%'") % i);
|
throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
||||||
|
|
||||||
|
@ -751,7 +751,7 @@ static void opVerify(Strings opFlags, Strings opArgs)
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--check-contents") checkContents = true;
|
if (i == "--check-contents") checkContents = true;
|
||||||
else if (i == "--repair") repair = true;
|
else if (i == "--repair") repair = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
if (store->verifyStore(checkContents, repair)) {
|
if (store->verifyStore(checkContents, repair)) {
|
||||||
printError("warning: not all errors were fixed");
|
printError("warning: not all errors were fixed");
|
||||||
|
@ -770,14 +770,14 @@ static void opVerifyPath(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
Path path = store->followLinksToStorePath(i);
|
Path path = store->followLinksToStorePath(i);
|
||||||
printMsg(lvlTalkative, format("checking path '%1%'...") % path);
|
printMsg(lvlTalkative, format("checking path ‘%1%’...") % path);
|
||||||
auto info = store->queryPathInfo(path);
|
auto info = store->queryPathInfo(path);
|
||||||
HashSink sink(info->narHash.type);
|
HashSink sink(info->narHash.type);
|
||||||
store->narFromPath(path, sink);
|
store->narFromPath(path, sink);
|
||||||
auto current = sink.finish();
|
auto current = sink.finish();
|
||||||
if (current.first != info->narHash) {
|
if (current.first != info->narHash) {
|
||||||
printError(
|
printError(
|
||||||
format("path '%1%' was modified! expected hash '%2%', got '%3%'")
|
format("path ‘%1%’ was modified! expected hash ‘%2%’, got ‘%3%’")
|
||||||
% path % printHash(info->narHash) % printHash(current.first));
|
% path % printHash(info->narHash) % printHash(current.first));
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
|
@ -816,7 +816,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
bool writeAllowed = false;
|
bool writeAllowed = false;
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--write") writeAllowed = true;
|
if (i == "--write") writeAllowed = true;
|
||||||
else throw UsageError(format("unknown flag '%1%'") % i);
|
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
||||||
|
|
||||||
|
@ -979,7 +979,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs)
|
static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
throw UsageError(format("unknown flag '%1%'") % i);
|
throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
if (opArgs.size() != 3) throw UsageError("three arguments expected");
|
if (opArgs.size() != 3) throw UsageError("three arguments expected");
|
||||||
auto i = opArgs.begin();
|
auto i = opArgs.begin();
|
||||||
|
|
|
@ -13,9 +13,9 @@ struct MixCat : virtual Args
|
||||||
{
|
{
|
||||||
auto st = accessor->stat(path);
|
auto st = accessor->stat(path);
|
||||||
if (st.type == FSAccessor::Type::tMissing)
|
if (st.type == FSAccessor::Type::tMissing)
|
||||||
throw Error(format("path '%1%' does not exist") % path);
|
throw Error(format("path ‘%1%’ does not exist") % path);
|
||||||
if (st.type != FSAccessor::Type::tRegular)
|
if (st.type != FSAccessor::Type::tRegular)
|
||||||
throw Error(format("path '%1%' is not a regular file") % path);
|
throw Error(format("path ‘%1%’ is not a regular file") % path);
|
||||||
|
|
||||||
std::cout << accessor->readFile(path);
|
std::cout << accessor->readFile(path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ MultiCommand::MultiCommand(const Commands & _commands)
|
||||||
assert(!command);
|
assert(!command);
|
||||||
auto i = commands.find(ss.front());
|
auto i = commands.find(ss.front());
|
||||||
if (i == commands.end())
|
if (i == commands.end())
|
||||||
throw UsageError(format("'%1%' is not a recognised command") % ss.front());
|
throw UsageError(format("‘%1%’ is not a recognised command") % ss.front());
|
||||||
command = i->second;
|
command = i->second;
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ void MultiCommand::printHelp(const string & programName, std::ostream & out)
|
||||||
printTable(out, table);
|
printTable(out, table);
|
||||||
|
|
||||||
out << "\n";
|
out << "\n";
|
||||||
out << "For full documentation, run 'man " << programName << "' or 'man " << programName << "-<COMMAND>'.\n";
|
out << "For full documentation, run ‘man " << programName << "’ or ‘man " << programName << "-<COMMAND>’.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MultiCommand::processFlag(Strings::iterator & pos, Strings::iterator end)
|
bool MultiCommand::processFlag(Strings::iterator & pos, Strings::iterator end)
|
||||||
|
@ -95,7 +95,7 @@ void StorePathsCommand::run(ref<Store> store)
|
||||||
{
|
{
|
||||||
if (all) {
|
if (all) {
|
||||||
if (storePaths.size())
|
if (storePaths.size())
|
||||||
throw UsageError("'--all' does not expect arguments");
|
throw UsageError("‘--all’ does not expect arguments");
|
||||||
for (auto & p : store->queryAllValidPaths())
|
for (auto & p : store->queryAllValidPaths())
|
||||||
storePaths.push_back(p);
|
storePaths.push_back(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ public:
|
||||||
typedef std::map<std::string, ref<Command>> Commands;
|
typedef std::map<std::string, ref<Command>> Commands;
|
||||||
|
|
||||||
/* An argument parser that supports multiple subcommands,
|
/* An argument parser that supports multiple subcommands,
|
||||||
i.e. '<command> <subcommand>'. */
|
i.e. ‘<command> <subcommand>’. */
|
||||||
class MultiCommand : virtual Args
|
class MultiCommand : virtual Args
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -41,7 +41,7 @@ struct CmdCopy : StorePathsCommand
|
||||||
void run(ref<Store> store, Paths storePaths) override
|
void run(ref<Store> store, Paths storePaths) override
|
||||||
{
|
{
|
||||||
if (srcUri.empty() && dstUri.empty())
|
if (srcUri.empty() && dstUri.empty())
|
||||||
throw UsageError("you must pass '--from' and/or '--to'");
|
throw UsageError("you must pass ‘--from’ and/or ‘--to’");
|
||||||
|
|
||||||
ref<Store> srcStore = srcUri.empty() ? store : openStore(srcUri);
|
ref<Store> srcStore = srcUri.empty() ? store : openStore(srcUri);
|
||||||
ref<Store> dstStore = dstUri.empty() ? store : openStore(dstUri);
|
ref<Store> dstStore = dstUri.empty() ? store : openStore(dstUri);
|
||||||
|
@ -63,7 +63,7 @@ struct CmdCopy : StorePathsCommand
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
if (!dstStore->isValidPath(storePath)) {
|
if (!dstStore->isValidPath(storePath)) {
|
||||||
Activity act(*logger, lvlInfo, format("copying '%s'...") % storePath);
|
Activity act(*logger, lvlInfo, format("copying ‘%s’...") % storePath);
|
||||||
|
|
||||||
copyStorePath(srcStore, dstStore, storePath);
|
copyStorePath(srcStore, dstStore, storePath);
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ static int compatNixHash(int argc, char * * argv)
|
||||||
string s = getArg(*arg, arg, end);
|
string s = getArg(*arg, arg, end);
|
||||||
ht = parseHashType(s);
|
ht = parseHashType(s);
|
||||||
if (ht == htUnknown)
|
if (ht == htUnknown)
|
||||||
throw UsageError(format("unknown hash type '%1%'") % s);
|
throw UsageError(format("unknown hash type ‘%1%’") % s);
|
||||||
}
|
}
|
||||||
else if (*arg == "--to-base16") op = opTo16;
|
else if (*arg == "--to-base16") op = opTo16;
|
||||||
else if (*arg == "--to-base32") op = opTo32;
|
else if (*arg == "--to-base32") op = opTo32;
|
||||||
|
|
|
@ -74,7 +74,7 @@ UserEnvElems MixInstallables::evalInstallables(ref<Store> store)
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
throw UsageError(format("don't know what to do with '%1%'") % installable);
|
throw UsageError(format("don't know what to do with ‘%1%’") % installable);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -38,9 +38,9 @@ struct MixInstallables : virtual Args
|
||||||
UserEnvElems evalInstallables(ref<Store> store);
|
UserEnvElems evalInstallables(ref<Store> store);
|
||||||
|
|
||||||
/* Return a value representing the Nix expression from which we
|
/* Return a value representing the Nix expression from which we
|
||||||
are installing. This is either the file specified by '--file',
|
are installing. This is either the file specified by ‘--file’,
|
||||||
or an attribute set constructed from $NIX_PATH, e.g. '{ nixpkgs
|
or an attribute set constructed from $NIX_PATH, e.g. ‘{ nixpkgs
|
||||||
= import ...; bla = import ...; }'. */
|
= import ...; bla = import ...; }’. */
|
||||||
Value * buildSourceExpr(EvalState & state);
|
Value * buildSourceExpr(EvalState & state);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -63,7 +63,7 @@ struct MixLs : virtual Args
|
||||||
|
|
||||||
auto st = accessor->stat(path);
|
auto st = accessor->stat(path);
|
||||||
if (st.type == FSAccessor::Type::tMissing)
|
if (st.type == FSAccessor::Type::tMissing)
|
||||||
throw Error(format("path '%1%' does not exist") % path);
|
throw Error(format("path ‘%1%’ does not exist") % path);
|
||||||
doPath(st, path,
|
doPath(st, path,
|
||||||
st.type == FSAccessor::Type::tDirectory ? "." : baseNameOf(path),
|
st.type == FSAccessor::Type::tDirectory ? "." : baseNameOf(path),
|
||||||
showDirectory);
|
showDirectory);
|
||||||
|
|
|
@ -71,15 +71,15 @@ struct CmdRun : StoreCommand, MixInstallables
|
||||||
createDirs(tmpDir + store->storeDir);
|
createDirs(tmpDir + store->storeDir);
|
||||||
|
|
||||||
if (mount(store2->realStoreDir.c_str(), (tmpDir + store->storeDir).c_str(), "", MS_BIND, 0) == -1)
|
if (mount(store2->realStoreDir.c_str(), (tmpDir + store->storeDir).c_str(), "", MS_BIND, 0) == -1)
|
||||||
throw SysError(format("mounting '%s' on '%s'") % store2->realStoreDir % store->storeDir);
|
throw SysError(format("mounting ‘%s’ on ‘%s’") % store2->realStoreDir % store->storeDir);
|
||||||
|
|
||||||
for (auto entry : readDirectory("/")) {
|
for (auto entry : readDirectory("/")) {
|
||||||
Path dst = tmpDir + "/" + entry.name;
|
Path dst = tmpDir + "/" + entry.name;
|
||||||
if (pathExists(dst)) continue;
|
if (pathExists(dst)) continue;
|
||||||
if (mkdir(dst.c_str(), 0700) == -1)
|
if (mkdir(dst.c_str(), 0700) == -1)
|
||||||
throw SysError(format("creating directory '%s'") % dst);
|
throw SysError(format("creating directory ‘%s’") % dst);
|
||||||
if (mount(("/" + entry.name).c_str(), dst.c_str(), "", MS_BIND | MS_REC, 0) == -1)
|
if (mount(("/" + entry.name).c_str(), dst.c_str(), "", MS_BIND | MS_REC, 0) == -1)
|
||||||
throw SysError(format("mounting '%s' on '%s'") % ("/" + entry.name) % dst);
|
throw SysError(format("mounting ‘%s’ on ‘%s’") % ("/" + entry.name) % dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
char * cwd = getcwd(0, 0);
|
char * cwd = getcwd(0, 0);
|
||||||
|
@ -87,19 +87,19 @@ struct CmdRun : StoreCommand, MixInstallables
|
||||||
Finally freeCwd([&]() { free(cwd); });
|
Finally freeCwd([&]() { free(cwd); });
|
||||||
|
|
||||||
if (chroot(tmpDir.c_str()) == -1)
|
if (chroot(tmpDir.c_str()) == -1)
|
||||||
throw SysError(format("chrooting into '%s'") % tmpDir);
|
throw SysError(format("chrooting into ‘%s’") % tmpDir);
|
||||||
|
|
||||||
if (chdir(cwd) == -1)
|
if (chdir(cwd) == -1)
|
||||||
throw SysError(format("chdir to '%s' in chroot") % cwd);
|
throw SysError(format("chdir to ‘%s’ in chroot") % cwd);
|
||||||
} else
|
} else
|
||||||
if (mount(store2->realStoreDir.c_str(), store->storeDir.c_str(), "", MS_BIND, 0) == -1)
|
if (mount(store2->realStoreDir.c_str(), store->storeDir.c_str(), "", MS_BIND, 0) == -1)
|
||||||
throw SysError(format("mounting '%s' on '%s'") % store2->realStoreDir % store->storeDir);
|
throw SysError(format("mounting ‘%s’ on ‘%s’") % store2->realStoreDir % store->storeDir);
|
||||||
|
|
||||||
writeFile("/proc/self/setgroups", "deny");
|
writeFile("/proc/self/setgroups", "deny");
|
||||||
writeFile("/proc/self/uid_map", (format("%d %d %d") % uid % uid % 1).str());
|
writeFile("/proc/self/uid_map", (format("%d %d %d") % uid % uid % 1).str());
|
||||||
writeFile("/proc/self/gid_map", (format("%d %d %d") % gid % gid % 1).str());
|
writeFile("/proc/self/gid_map", (format("%d %d %d") % gid % gid % 1).str());
|
||||||
#else
|
#else
|
||||||
throw Error(format("mounting the Nix store on '%s' is not supported on this platform") % store->storeDir);
|
throw Error(format("mounting the Nix store on ‘%s’ is not supported on this platform") % store->storeDir);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ struct CmdRun : StoreCommand, MixInstallables
|
||||||
setenv("PATH", concatStringsSep(":", unixPath).c_str(), 1);
|
setenv("PATH", concatStringsSep(":", unixPath).c_str(), 1);
|
||||||
|
|
||||||
if (execlp("bash", "bash", nullptr) == -1)
|
if (execlp("bash", "bash", nullptr) == -1)
|
||||||
throw SysError("unable to exec 'bash'");
|
throw SysError("unable to exec ‘bash’");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ struct CmdCopySigs : StorePathsCommand
|
||||||
void run(ref<Store> store, Paths storePaths) override
|
void run(ref<Store> store, Paths storePaths) override
|
||||||
{
|
{
|
||||||
if (substituterUris.empty())
|
if (substituterUris.empty())
|
||||||
throw UsageError("you must specify at least one substituter using '-s'");
|
throw UsageError("you must specify at least one substituter using ‘-s’");
|
||||||
|
|
||||||
// FIXME: factor out commonality with MixVerify.
|
// FIXME: factor out commonality with MixVerify.
|
||||||
std::vector<ref<Store>> substituters;
|
std::vector<ref<Store>> substituters;
|
||||||
|
@ -45,7 +45,7 @@ struct CmdCopySigs : StorePathsCommand
|
||||||
logger->setExpected(doneLabel, storePaths.size());
|
logger->setExpected(doneLabel, storePaths.size());
|
||||||
|
|
||||||
auto doPath = [&](const Path & storePath) {
|
auto doPath = [&](const Path & storePath) {
|
||||||
Activity act(*logger, lvlInfo, format("getting signatures for '%s'") % storePath);
|
Activity act(*logger, lvlInfo, format("getting signatures for ‘%s’") % storePath);
|
||||||
|
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ struct CmdSignPaths : StorePathsCommand
|
||||||
void run(ref<Store> store, Paths storePaths) override
|
void run(ref<Store> store, Paths storePaths) override
|
||||||
{
|
{
|
||||||
if (secretKeyFile.empty())
|
if (secretKeyFile.empty())
|
||||||
throw UsageError("you must specify a secret key file using '-k'");
|
throw UsageError("you must specify a secret key file using ‘-k’");
|
||||||
|
|
||||||
SecretKey secretKey(readFile(secretKeyFile));
|
SecretKey secretKey(readFile(secretKeyFile));
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct CmdVerify : StorePathsCommand
|
||||||
try {
|
try {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
Activity act(*logger, lvlInfo, format("checking '%s'") % storePath);
|
Activity act(*logger, lvlInfo, format("checking ‘%s’") % storePath);
|
||||||
|
|
||||||
auto info = store->queryPathInfo(storePath);
|
auto info = store->queryPathInfo(storePath);
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ struct CmdVerify : StorePathsCommand
|
||||||
logger->incProgress(corruptedLabel);
|
logger->incProgress(corruptedLabel);
|
||||||
corrupted = 1;
|
corrupted = 1;
|
||||||
printError(
|
printError(
|
||||||
format("path '%s' was modified! expected hash '%s', got '%s'")
|
format("path ‘%s’ was modified! expected hash ‘%s’, got ‘%s’")
|
||||||
% info->path % printHash(info->narHash) % printHash(hash.first));
|
% info->path % printHash(info->narHash) % printHash(hash.first));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ struct CmdVerify : StorePathsCommand
|
||||||
if (!good) {
|
if (!good) {
|
||||||
logger->incProgress(untrustedLabel);
|
logger->incProgress(untrustedLabel);
|
||||||
untrusted++;
|
untrusted++;
|
||||||
printError(format("path '%s' is untrusted") % info->path);
|
printError(format("path ‘%s’ is untrusted") % info->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,13 +62,13 @@ std::set<std::string> runResolver(const Path & filename) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mach64_offset == 0) {
|
if (mach64_offset == 0) {
|
||||||
printError(format("Could not find any mach64 blobs in file '%1%', continuing...") % filename);
|
printError(format("Could not find any mach64 blobs in file ‘%1%’, continuing...") % filename);
|
||||||
return std::set<string>();
|
return std::set<string>();
|
||||||
}
|
}
|
||||||
} else if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64) {
|
} else if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64) {
|
||||||
mach64_offset = 0;
|
mach64_offset = 0;
|
||||||
} else {
|
} else {
|
||||||
printError(format("Object file has unknown magic number '%1%', skipping it...") % magic);
|
printError(format("Object file has unknown magic number ‘%1%’, skipping it...") % magic);
|
||||||
return std::set<string>();
|
return std::set<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ std::set<std::string> runResolver(const Path & filename) {
|
||||||
bool isSymlink(const Path & path) {
|
bool isSymlink(const Path & path) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if(lstat(path.c_str(), &st))
|
if(lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
throw SysError(format("getting attributes of path ‘%1%’") % path);
|
||||||
|
|
||||||
return S_ISLNK(st.st_mode);
|
return S_ISLNK(st.st_mode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ clearCacheCache() {
|
||||||
|
|
||||||
startDaemon() {
|
startDaemon() {
|
||||||
# Start the daemon, wait for the socket to appear. !!!
|
# Start the daemon, wait for the socket to appear. !!!
|
||||||
# 'nix-daemon' should have an option to fork into the background.
|
# ‘nix-daemon’ should have an option to fork into the background.
|
||||||
rm -f $NIX_STATE_DIR/daemon-socket/socket
|
rm -f $NIX_STATE_DIR/daemon-socket/socket
|
||||||
nix-daemon &
|
nix-daemon &
|
||||||
for ((i = 0; i < 30; i++)); do
|
for ((i = 0; i < 30; i++)); do
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# The function 'range' comes from lib.nix and was added to the lexical
|
# The function ‘range’ comes from lib.nix and was added to the lexical
|
||||||
# scope by scopedImport.
|
# scope by scopedImport.
|
||||||
range 1 5 ++ import ./imported2.nix
|
range 1 5 ++ import ./imported2.nix
|
||||||
|
|
|
@ -3,7 +3,7 @@ source common.sh
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
# Test whether read-only evaluation works when referring to the
|
# Test whether read-only evaluation works when referring to the
|
||||||
# 'drvPath' attribute.
|
# ‘drvPath’ attribute.
|
||||||
echo "evaluating c..."
|
echo "evaluating c..."
|
||||||
#drvPath=$(nix-instantiate multiple-outputs.nix -A c --readonly-mode)
|
#drvPath=$(nix-instantiate multiple-outputs.nix -A c --readonly-mode)
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ drvPath=$(nix-instantiate multiple-outputs.nix -A c)
|
||||||
grep -q 'multiple-outputs-a.drv",\["first","second"\]' $drvPath
|
grep -q 'multiple-outputs-a.drv",\["first","second"\]' $drvPath
|
||||||
grep -q 'multiple-outputs-b.drv",\["out"\]' $drvPath
|
grep -q 'multiple-outputs-b.drv",\["out"\]' $drvPath
|
||||||
|
|
||||||
# While we're at it, test the 'unsafeDiscardOutputDependency' primop.
|
# While we're at it, test the ‘unsafeDiscardOutputDependency’ primop.
|
||||||
outPath=$(nix-build multiple-outputs.nix -A d --no-out-link)
|
outPath=$(nix-build multiple-outputs.nix -A d --no-out-link)
|
||||||
drvPath=$(cat $outPath/drv)
|
drvPath=$(cat $outPath/drv)
|
||||||
outPath=$(nix-store -q $drvPath)
|
outPath=$(nix-store -q $drvPath)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Test 'nix-copy-closure'.
|
# Test ‘nix-copy-closure’.
|
||||||
|
|
||||||
{ system, nix }:
|
{ system, nix }:
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
echo "'timeout' builder entering an infinite loop"
|
echo "‘timeout’ builder entering an infinite loop"
|
||||||
while true ; do echo -n .; done
|
while true ; do echo -n .; done
|
||||||
|
|
|
@ -5,7 +5,7 @@ source common.sh
|
||||||
failed=0
|
failed=0
|
||||||
messages="`nix-build -Q timeout.nix --timeout 2 2>&1 || failed=1`"
|
messages="`nix-build -Q timeout.nix --timeout 2 2>&1 || failed=1`"
|
||||||
if [ $failed -ne 0 ]; then
|
if [ $failed -ne 0 ]; then
|
||||||
echo "error: 'nix-store' succeeded; should have timed out"
|
echo "error: ‘nix-store’ succeeded; should have timed out"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ nix-env -q '*' | grep -q bar-0.1.1
|
||||||
|
|
||||||
# Test priorities: foo-0.1 has a lower priority than foo-1.0, so it
|
# Test priorities: foo-0.1 has a lower priority than foo-1.0, so it
|
||||||
# should be possible to install both without a collision. Also test
|
# should be possible to install both without a collision. Also test
|
||||||
# '--set-flag priority' to manually override the declared priorities.
|
# ‘--set-flag priority’ to manually override the declared priorities.
|
||||||
nix-env -e '*'
|
nix-env -e '*'
|
||||||
nix-env -i foo-0.1 foo-1.0
|
nix-env -i foo-0.1 foo-1.0
|
||||||
[ "$($profiles/test/bin/foo)" = "foo-1.0" ]
|
[ "$($profiles/test/bin/foo)" = "foo-1.0" ]
|
||||||
|
|
Loading…
Reference in a new issue