diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/download-from-binary-cache.pl.in | 632 | ||||
-rw-r--r-- | scripts/local.mk | 10 | ||||
-rwxr-xr-x | scripts/nix-channel.in | 228 | ||||
-rwxr-xr-x | scripts/nix-install-package.in | 127 | ||||
-rwxr-xr-x | scripts/nix-push.in | 296 | ||||
-rwxr-xr-x | scripts/resolve-system-dependencies.pl.in | 122 | ||||
-rwxr-xr-x | scripts/show-duplication.pl | 73 |
7 files changed, 0 insertions, 1488 deletions
diff --git a/scripts/download-from-binary-cache.pl.in b/scripts/download-from-binary-cache.pl.in deleted file mode 100644 index a4f858610aca..000000000000 --- a/scripts/download-from-binary-cache.pl.in +++ /dev/null @@ -1,632 +0,0 @@ -#! @perl@ -w @perlFlags@ - -use utf8; -use DBI; -use DBD::SQLite; -use File::Basename; -use IO::Select; -use Nix::Config; -use Nix::Store; -use Nix::Utils; -use Nix::Manifest; -use WWW::Curl::Easy; -use WWW::Curl::Multi; -use strict; - -STDERR->autoflush(1); -binmode STDERR, ":encoding(utf8)"; - -Nix::Config::readConfig; - -my @caches; -my $gotCaches = 0; - -my $maxParallelRequests = int($Nix::Config::config{"binary-caches-parallel-connections"} // 25); -$maxParallelRequests = 1 if $maxParallelRequests < 1; - -my $ttlNegative = 24 * 3600; # when to purge negative lookups from the database -my $ttlNegativeUse = 3600; # how long negative lookups are valid for non-"have" lookups -my $didExpiration = 0; - -my $showAfter = 5; # show that we're waiting for a request after this many seconds - -my $debug = ($Nix::Config::config{"debug-subst"} // "") eq 1 || ($Nix::Config::config{"untrusted-debug-subst"} // "") eq 1; - -my $cacheFileURLs = ($ENV{"_NIX_CACHE_FILE_URLS"} // "") eq 1; # for testing - -my ($dbh, $queryCache, $insertNAR, $queryNAR, $insertNARExistence, $queryNARExistence, $expireNARExistence); - -my $curlm = WWW::Curl::Multi->new; -my $activeRequests = 0; -my $curlIdCount = 1; -my %requests; -my %scheduled; -my $caBundle = $ENV{"SSL_CERT_FILE"} // $ENV{"CURL_CA_BUNDLE"} // $ENV{"OPENSSL_X509_CERT_FILE"}; -$caBundle = "/etc/ssl/certs/ca-bundle.crt" if !$caBundle && -f "/etc/ssl/certs/ca-bundle.crt"; -$caBundle = "/etc/ssl/certs/ca-certificates.crt" if !$caBundle && -f "/etc/ssl/certs/ca-certificates.crt"; - -my $userName = getpwuid($<) || $ENV{"USER"} or die "cannot figure out user name"; - -my $userAgent = "Nix/$Nix::Config::version"; - -sub isTrue { - my ($x) = @_; - return $x eq "true" || $x eq "1"; -} - -# FIXME: this should be cache URLs required to have valid signatures, -# or "*" to require signatures on all binary caches. -# FIXME: should binary caches using a key in -# ‘binary-cache-public-keys’ be trusted by default? -my $requireSignedBinaryCaches = ($Nix::Config::config{"signed-binary-caches"} // "0") ne "0"; - -my $curlConnectTimeout = int( - $Nix::Config::config{"untrusted-connect-timeout"} // - $Nix::Config::config{"connect-timeout"} // - $ENV{"NIX_CONNECT_TIMEOUT"} // 0); - - -sub addRequest { - my ($storePath, $url, $head) = @_; - - my $curl = WWW::Curl::Easy->new; - my $curlId = $curlIdCount++; - $requests{$curlId} = { storePath => $storePath, url => $url, handle => $curl, content => "", type => $head ? "HEAD" : "GET" - , shown => 0, started => time() }; - - $curl->setopt(CURLOPT_PRIVATE, $curlId); - $curl->setopt(CURLOPT_URL, $url); - open (my $fh, ">", \$requests{$curlId}->{content}); - $curl->setopt(CURLOPT_WRITEDATA, $fh); - $curl->setopt(CURLOPT_FOLLOWLOCATION, 1); - $curl->setopt(CURLOPT_CAINFO, $caBundle) if defined $caBundle; - - unless (isTrue($Nix::Config::config{"verify-https-binary-caches"} // "1")) { - $curl->setopt(CURLOPT_SSL_VERIFYPEER, 0); - $curl->setopt(CURLOPT_SSL_VERIFYHOST, 0); - } - - $curl->setopt(CURLOPT_USERAGENT, $userAgent); - $curl->setopt(CURLOPT_NOBODY, 1) if $head; - $curl->setopt(CURLOPT_FAILONERROR, 1); - $curl->setopt(CURLOPT_CONNECTTIMEOUT, $curlConnectTimeout); - $curl->setopt(CURLOPT_TIMEOUT, 20 * 60); - - if ($activeRequests >= $maxParallelRequests) { - $scheduled{$curlId} = 1; - } else { - $curlm->add_handle($curl); - $activeRequests++; - } - - return $requests{$curlId}; -} - - -sub processRequests { - while ($activeRequests) { - my ($rfds, $wfds, $efds) = $curlm->fdset(); - #print STDERR "R = @{$rfds}, W = @{$wfds}, E = @{$efds}\n"; - - # Sleep until we can read or write some data. - if (scalar @{$rfds} + scalar @{$wfds} + scalar @{$efds} > 0) { - IO::Select->select(IO::Select->new(@{$rfds}), IO::Select->new(@{$wfds}), IO::Select->new(@{$efds}), 1.0); - } - - if ($curlm->perform() != $activeRequests) { - while (my ($id, $result) = $curlm->info_read) { - if ($id) { - my $request = $requests{$id} or die; - my $handle = $request->{handle}; - $request->{result} = $result; - $request->{httpStatus} = $handle->getinfo(CURLINFO_RESPONSE_CODE); - - print STDERR "$request->{type} on $request->{url} [$request->{result}, $request->{httpStatus}]\n" if $debug; - - $activeRequests--; - delete $request->{handle}; - - if (scalar(keys %scheduled) > 0) { - my $id2 = (keys %scheduled)[0]; - $curlm->add_handle($requests{$id2}->{handle}); - $activeRequests++; - delete $scheduled{$id2}; - } - } - } - } - - my $time = time(); - while (my ($key, $request) = each %requests) { - next unless defined $request->{handle}; - next if $request->{shown}; - if ($time > $request->{started} + $showAfter) { - print STDERR "still waiting for ‘$request->{url}’ after $showAfter seconds...\n"; - $request->{shown} = 1; - } - } - } -} - - -sub initCache { - my $dbPath = "$Nix::Config::stateDir/binary-cache-v3.sqlite"; - - unlink "$Nix::Config::stateDir/binary-cache-v1.sqlite"; - unlink "$Nix::Config::stateDir/binary-cache-v2.sqlite"; - - # Open/create the database. - $dbh = DBI->connect("dbi:SQLite:dbname=$dbPath", "", "") - or die "cannot open database ‘$dbPath’"; - $dbh->{RaiseError} = 1; - $dbh->{PrintError} = 0; - - $dbh->sqlite_busy_timeout(60 * 60 * 1000); - - $dbh->do("pragma synchronous = off"); # we can always reproduce the cache - $dbh->do("pragma journal_mode = truncate"); - - # Initialise the database schema, if necessary. - $dbh->do(<<EOF); - create table if not exists BinaryCaches ( - id integer primary key autoincrement not null, - url text unique not null, - timestamp integer not null, - storeDir text not null, - wantMassQuery integer not null, - priority integer not null - ); -EOF - - $dbh->do(<<EOF); - create table if not exists NARs ( - cache integer not null, - storePath text not null, - url text not null, - compression text not null, - fileHash text, - fileSize integer, - narHash text, - narSize integer, - refs text, - deriver text, - signedBy text, - timestamp integer not null, - primary key (cache, storePath), - foreign key (cache) references BinaryCaches(id) on delete cascade - ); -EOF - - $dbh->do(<<EOF); - create table if not exists NARExistence ( - cache integer not null, - storePath text not null, - exist integer not null, - timestamp integer not null, - primary key (cache, storePath), - foreign key (cache) references BinaryCaches(id) on delete cascade - ); -EOF - - $dbh->do("create index if not exists NARExistenceByExistTimestamp on NARExistence (exist, timestamp)"); - - $queryCache = $dbh->prepare("select id, storeDir, wantMassQuery, priority from BinaryCaches where url = ?") or die; - - $insertNAR = $dbh->prepare( - "insert or replace into NARs(cache, storePath, url, compression, fileHash, fileSize, narHash, " . - "narSize, refs, deriver, signedBy, timestamp) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") or die; - - $queryNAR = $dbh->prepare("select * from NARs where cache = ? and storePath = ?") or die; - - $insertNARExistence = $dbh->prepare( - "insert or replace into NARExistence(cache, storePath, exist, timestamp) values (?, ?, ?, ?)") or die; - - $queryNARExistence = $dbh->prepare("select exist, timestamp from NARExistence where cache = ? and storePath = ?") or die; - - $expireNARExistence = $dbh->prepare("delete from NARExistence where exist = ? and timestamp < ?") or die; -} - - -sub getAvailableCaches { - return if $gotCaches; - $gotCaches = 1; - - sub strToList { - my ($s) = @_; - return map { s/\/+$//; $_ } split(/ /, $s); - } - - my @urls = strToList($Nix::Config::config{"binary-caches"} // - ($Nix::Config::storeDir eq "/nix/store" ? "https://cache.nixos.org" : "")); - - my $urlsFiles = $Nix::Config::config{"binary-cache-files"} - // "$Nix::Config::stateDir/profiles/per-user/$userName/channels/binary-caches/*"; - foreach my $urlFile (glob $urlsFiles) { - next unless -f $urlFile; - open FILE, "<$urlFile" or die "cannot open ‘$urlFile’\n"; - my $url = <FILE>; chomp $url; - close FILE; - push @urls, strToList($url); - } - - push @urls, strToList($Nix::Config::config{"extra-binary-caches"} // ""); - - # Allow Nix daemon users to override the binary caches to a subset - # of those listed in the config file. Note that ‘untrusted-*’ - # denotes options passed by the client. - my @trustedUrls = uniq(@urls, strToList($Nix::Config::config{"trusted-binary-caches"} // "")); - - if (defined $Nix::Config::config{"untrusted-binary-caches"}) { - my @untrustedUrls = strToList $Nix::Config::config{"untrusted-binary-caches"}; - @urls = (); - foreach my $url (@untrustedUrls) { - die "binary cache ‘$url’ is not trusted (please add it to ‘trusted-binary-caches’ in $Nix::Config::confDir/nix.conf)\n" - unless scalar(grep { $url eq $_ } @trustedUrls) > 0; - push @urls, $url; - } - } - - my @untrustedUrls = strToList $Nix::Config::config{"untrusted-extra-binary-caches"} // ""; - foreach my $url (@untrustedUrls) { - unless (scalar(grep { $url eq $_ } @trustedUrls) > 0) { - warn "binary cache ‘$url’ is not trusted (please add it to ‘trusted-binary-caches’ in $Nix::Config::confDir/nix.conf)\n"; - next; - } - push @urls, $url; - } - - foreach my $url (uniq @urls) { - - # FIXME: not atomic. - $queryCache->execute($url); - my $res = $queryCache->fetchrow_hashref(); - if (defined $res) { - next if $res->{storeDir} ne $Nix::Config::storeDir; - push @caches, { id => $res->{id}, url => $url, wantMassQuery => $res->{wantMassQuery}, priority => $res->{priority} }; - next; - } - - # Get the cache info file. - my $request = addRequest(undef, $url . "/nix-cache-info"); - processRequests; - - if ($request->{result} != 0) { - print STDERR "could not download ‘$request->{url}’ (" . - ($request->{result} != 0 ? "Curl error $request->{result}" : "HTTP status $request->{httpStatus}") . ")\n"; - next; - } - - my $storeDir = "/nix/store"; - my $wantMassQuery = 0; - my $priority = 50; - foreach my $line (split "\n", $request->{content}) { - unless ($line =~ /^(.*): (.*)$/) { - print STDERR "bad cache info file ‘$request->{url}’\n"; - return undef; - } - if ($1 eq "StoreDir") { $storeDir = $2; } - elsif ($1 eq "WantMassQuery") { $wantMassQuery = int($2); } - elsif ($1 eq "Priority") { $priority = int($2); } - } - - $dbh->do("insert or replace into BinaryCaches(url, timestamp, storeDir, wantMassQuery, priority) values (?, ?, ?, ?, ?)", - {}, $url, time(), $storeDir, $wantMassQuery, $priority); - $queryCache->execute($url); - $res = $queryCache->fetchrow_hashref() or die; - next if $storeDir ne $Nix::Config::storeDir; - push @caches, { id => $res->{id}, url => $url, wantMassQuery => $wantMassQuery, priority => $priority }; - } - - @caches = sort { $a->{priority} <=> $b->{priority} } @caches; - - expireNegative(); -} - - -sub shouldCache { - my ($url) = @_; - return $cacheFileURLs || $url !~ /^file:/; -} - - -sub processNARInfo { - my ($storePath, $cache, $request) = @_; - - if ($request->{result} != 0) { - if ($request->{result} != 37 && $request->{httpStatus} != 404 && $request->{httpStatus} != 403) { - print STDERR "could not download ‘$request->{url}’ (" . - ($request->{result} != 0 ? "Curl error $request->{result}" : "HTTP status $request->{httpStatus}") . ")\n"; - } else { - $insertNARExistence->execute($cache->{id}, basename($storePath), 0, time()) - if shouldCache $request->{url}; - } - return undef; - } - - my $narInfo = parseNARInfo($storePath, $request->{content}, $requireSignedBinaryCaches, $request->{url}); - return undef unless defined $narInfo; - - die if $requireSignedBinaryCaches && !defined $narInfo->{signedBy}; - - # Cache the result. - $insertNAR->execute( - $cache->{id}, basename($storePath), $narInfo->{url}, $narInfo->{compression}, - $narInfo->{fileHash}, $narInfo->{fileSize}, $narInfo->{narHash}, $narInfo->{narSize}, - join(" ", @{$narInfo->{refs}}), $narInfo->{deriver}, $narInfo->{signedBy}, time()) - if shouldCache $request->{url}; - - return $narInfo; -} - - -sub getCachedInfoFrom { - my ($storePath, $cache) = @_; - - $queryNAR->execute($cache->{id}, basename($storePath)); - my $res = $queryNAR->fetchrow_hashref(); - return undef unless defined $res; - - # We may previously have cached this info when signature checking - # was disabled. In that case, ignore the cached info. - return undef if $requireSignedBinaryCaches && !defined $res->{signedBy}; - - return - { url => $res->{url} - , compression => $res->{compression} - , fileHash => $res->{fileHash} - , fileSize => $res->{fileSize} - , narHash => $res->{narHash} - , narSize => $res->{narSize} - , refs => [ split " ", $res->{refs} ] - , deriver => $res->{deriver} - , signedBy => $res->{signedBy} - } if defined $res; -} - - -sub negativeHit { - my ($storePath, $cache) = @_; - $queryNARExistence->execute($cache->{id}, basename($storePath)); - my $res = $queryNARExistence->fetchrow_hashref(); - return defined $res && $res->{exist} == 0 && time() - $res->{timestamp} < $ttlNegativeUse; -} - - -sub positiveHit { - my ($storePath, $cache) = @_; - return 1 if defined getCachedInfoFrom($storePath, $cache); - $queryNARExistence->execute($cache->{id}, basename($storePath)); - my $res = $queryNARExistence->fetchrow_hashref(); - return defined $res && $res->{exist} == 1; -} - - -sub expireNegative { - return if $didExpiration; - $didExpiration = 1; - my $time = time(); - # Round up to the next multiple of the TTL to ensure that we do - # expiration only once per time interval. E.g. if $ttlNegative == - # 3600, we expire entries at most once per hour. This is - # presumably faster than expiring a few entries per request (and - # thus doing a transaction). - my $limit = (int($time / $ttlNegative) - 1) * $ttlNegative; - $expireNARExistence->execute($limit, 0); - print STDERR "expired ", $expireNARExistence->rows, " negative entries\n" if $debug; -} - - -sub printInfo { - my ($storePath, $info) = @_; - print "$storePath\n"; - print $info->{deriver} ? "$Nix::Config::storeDir/$info->{deriver}" : "", "\n"; - print scalar @{$info->{refs}}, "\n"; - print "$Nix::Config::storeDir/$_\n" foreach @{$info->{refs}}; - print $info->{fileSize} || 0, "\n"; - print $info->{narSize} || 0, "\n"; -} - - -sub infoUrl { - my ($binaryCacheUrl, $storePath) = @_; - my $pathHash = substr(basename($storePath), 0, 32); - my $infoUrl = "$binaryCacheUrl/$pathHash.narinfo"; -} - - -sub printInfoParallel { - my @paths = @_; - - # First print all paths for which we have cached info. - my @left; - foreach my $storePath (@paths) { - my $found = 0; - foreach my $cache (@caches) { - my $info = getCachedInfoFrom($storePath, $cache); - if (defined $info) { - printInfo($storePath, $info); - $found = 1; - last; - } - } - push @left, $storePath if !$found; - } - - return if scalar @left == 0; - - foreach my $cache (@caches) { - - my @left2; - %requests = (); - foreach my $storePath (@left) { - if (negativeHit($storePath, $cache)) { - push @left2, $storePath; - next; - } - addRequest($storePath, infoUrl($cache->{url}, $storePath)); - } - - processRequests; - - foreach my $request (values %requests) { - my $info = processNARInfo($request->{storePath}, $cache, $request); - if (defined $info) { - printInfo($request->{storePath}, $info); - } else { - push @left2, $request->{storePath}; - } - } - - @left = @left2; - } -} - - -sub printSubstitutablePaths { - my @paths = @_; - - # First look for paths that have cached info. - my @left; - foreach my $storePath (@paths) { - my $found = 0; - foreach my $cache (@caches) { - next unless $cache->{wantMassQuery}; - if (positiveHit($storePath, $cache)) { - print "$storePath\n"; - $found = 1; - last; - } - } - push @left, $storePath if !$found; - } - - return if scalar @left == 0; - - # For remaining paths, do HEAD requests. - foreach my $cache (@caches) { - next unless $cache->{wantMassQuery}; - my @left2; - %requests = (); - foreach my $storePath (@left) { - if (negativeHit($storePath, $cache)) { - push @left2, $storePath; - next; - } - addRequest($storePath, infoUrl($cache->{url}, $storePath), 1); - } - - processRequests; - - foreach my $request (values %requests) { - if ($request->{result} != 0) { - if ($request->{result} != 37 && $request->{httpStatus} != 404 && $request->{httpStatus} != 403) { - print STDERR "could not check ‘$request->{url}’ (" . - ($request->{result} != 0 ? "Curl error $request->{result}" : "HTTP status $request->{httpStatus}") . ")\n"; - } else { - $insertNARExistence->execute($cache->{id}, basename($request->{storePath}), 0, time()) - if shouldCache $request->{url}; - } - push @left2, $request->{storePath}; - } else { - $insertNARExistence->execute($cache->{id}, basename($request->{storePath}), 1, time()) - if shouldCache $request->{url}; - print "$request->{storePath}\n"; - } - } - - @left = @left2; - } -} - - -sub downloadBinary { - my ($storePath, $destPath) = @_; - - foreach my $cache (@caches) { - my $info = getCachedInfoFrom($storePath, $cache); - - unless (defined $info) { - next if negativeHit($storePath, $cache); - my $request = addRequest($storePath, infoUrl($cache->{url}, $storePath)); - processRequests; - $info = processNARInfo($storePath, $cache, $request); - } - - next unless defined $info; - - my $decompressor; - if ($info->{compression} eq "bzip2") { $decompressor = "| $Nix::Config::bzip2 -d"; } - elsif ($info->{compression} eq "xz") { $decompressor = "| $Nix::Config::xz -d"; } - elsif ($info->{compression} eq "none") { $decompressor = ""; } - else { - print STDERR "unknown compression method ‘$info->{compression}’\n"; - next; - } - my $url = "$cache->{url}/$info->{url}"; # FIXME: handle non-relative URLs - die if $requireSignedBinaryCaches && !defined $info->{signedBy}; - print STDERR "\n*** Downloading ‘$url’ ", ($requireSignedBinaryCaches ? "(signed by ‘$info->{signedBy}’) " : ""), "to ‘$storePath’...\n"; - checkURL $url; - if (system("$Nix::Config::curl --fail --location --connect-timeout $curlConnectTimeout -A '$userAgent' '$url' $decompressor | $Nix::Config::binDir/nix-store --restore $destPath") != 0) { - warn "download of ‘$url’ failed" . ($! ? ": $!" : "") . "\n"; - next; - } - - # Tell Nix about the expected hash so it can verify it. - die unless defined $info->{narHash} && $info->{narHash} ne ""; - print "$info->{narHash}\n"; - - print STDERR "\n"; - return; - } - - print STDERR "could not download ‘$storePath’ from any binary cache\n"; - exit 1; -} - - -# Bail out right away if binary caches are disabled. -exit 0 if - ($Nix::Config::config{"use-binary-caches"} // "true") eq "false" || - ($Nix::Config::config{"untrusted-use-binary-caches"} // "true") eq "false"; -print "\n"; -flush STDOUT; - -initCache(); - - -if ($ARGV[0] eq "--query") { - - while (<STDIN>) { - getAvailableCaches; - chomp; - my ($cmd, @args) = split " ", $_; - - if ($cmd eq "have") { - print STDERR "checking binary caches for existence of @args\n" if $debug; - printSubstitutablePaths(@args); - print "\n"; - } - - elsif ($cmd eq "info") { - print STDERR "checking binary caches for info on @args\n" if $debug; - printInfoParallel(@args); - print "\n"; - } - - else { die "unknown command ‘$cmd’"; } - - flush STDOUT; - } - -} - -elsif ($ARGV[0] eq "--substitute") { - my $storePath = $ARGV[1] or die; - my $destPath = $ARGV[2] or die; - getAvailableCaches; - downloadBinary($storePath, $destPath); -} - -else { - die; -} diff --git a/scripts/local.mk b/scripts/local.mk index 142188ad5f47..ee8ae6845dc1 100644 --- a/scripts/local.mk +++ b/scripts/local.mk @@ -1,8 +1,5 @@ nix_bin_scripts := \ - $(d)/nix-channel \ $(d)/nix-copy-closure \ - $(d)/nix-install-package \ - $(d)/nix-push bin-scripts += $(nix_bin_scripts) @@ -12,18 +9,11 @@ nix_noinst_scripts := \ $(d)/nix-profile.sh \ $(d)/nix-reduce-build -ifeq ($(OS), Darwin) - nix_noinst_scripts += $(d)/resolve-system-dependencies.pl -endif - noinst-scripts += $(nix_noinst_scripts) profiledir = $(sysconfdir)/profile.d $(eval $(call install-file-as, $(d)/nix-profile.sh, $(profiledir)/nix.sh, 0644)) $(eval $(call install-program-in, $(d)/build-remote.pl, $(libexecdir)/nix)) -ifeq ($(OS), Darwin) - $(eval $(call install-program-in, $(d)/resolve-system-dependencies.pl, $(libexecdir)/nix)) -endif clean-files += $(nix_bin_scripts) $(nix_noinst_scripts) diff --git a/scripts/nix-channel.in b/scripts/nix-channel.in deleted file mode 100755 index 65084ff1f34a..000000000000 --- a/scripts/nix-channel.in +++ /dev/null @@ -1,228 +0,0 @@ -#! @perl@ -w @perlFlags@ - -use utf8; -use strict; -use File::Basename; -use File::Path qw(mkpath); -use Nix::Config; -use Nix::Manifest; -use File::Temp qw(tempdir); - -binmode STDERR, ":encoding(utf8)"; - -Nix::Config::readConfig; - - -# Turn on caching in nix-prefetch-url. -my $channelCache = "$Nix::Config::stateDir/channel-cache"; -mkdir $channelCache, 0755 unless -e $channelCache; -$ENV{'NIX_DOWNLOAD_CACHE'} = $channelCache if -W $channelCache; - -# Figure out the name of the `.nix-channels' file to use. -my $home = $ENV{"HOME"} or die '$HOME not set\n'; -my $channelsList = "$home/.nix-channels"; -my $nixDefExpr = "$home/.nix-defexpr"; - -# Figure out the name of the channels profile. -my $userName = getpwuid($<) || $ENV{"USER"} or die "cannot figure out user name"; -my $profile = "$Nix::Config::stateDir/profiles/per-user/$userName/channels"; -mkpath(dirname $profile, 0, 0755); - -my %channels; - - -# Reads the list of channels. -sub readChannels { - return if (!-f $channelsList); - open CHANNELS, "<$channelsList" or die "cannot open ‘$channelsList’: $!"; - while (<CHANNELS>) { - chomp; - next if /^\s*\#/; - my ($url, $name) = split ' ', $_; - $url =~ s/\/*$//; # remove trailing slashes - $name = basename $url unless defined $name; - $channels{$name} = $url; - } - close CHANNELS; -} - - -# Writes the list of channels. -sub writeChannels { - open CHANNELS, ">$channelsList" or die "cannot open ‘$channelsList’: $!"; - foreach my $name (keys %channels) { - print CHANNELS "$channels{$name} $name\n"; - } - close CHANNELS; -} - - -# Adds a channel. -sub addChannel { - my ($url, $name) = @_; - die "invalid channel URL ‘$url’" unless $url =~ /^(file|http|https):\/\//; - die "invalid channel identifier ‘$name’" unless $name =~ /^[a-zA-Z0-9_][a-zA-Z0-9_\-\.]*$/; - readChannels; - $channels{$name} = $url; - writeChannels; -} - - -# Remove a channel. -sub removeChannel { - my ($name) = @_; - readChannels; - my $url = $channels{$name}; - delete $channels{$name}; - writeChannels; - - system("$Nix::Config::binDir/nix-env --profile '$profile' -e '$name'") == 0 - or die "cannot remove channel ‘$name’\n"; -} - - -# Fetch Nix expressions and binary cache URLs from the subscribed channels. -sub update { - my @channelNames = @_; - - readChannels; - - # Download each channel. - my $exprs = ""; - foreach my $name (keys %channels) { - next if scalar @channelNames > 0 && ! grep { $_ eq $name } @{channelNames}; - - my $url = $channels{$name}; - - # We want to download the url to a file to see if it's a tarball while also checking if we - # got redirected in the process, so that we can grab the various parts of a nix channel - # definition from a consistent location if the redirect changes mid-download. - my $tmpdir = tempdir( CLEANUP => 1 ); - my $filename; - ($url, $filename) = `cd $tmpdir && $Nix::Config::curl --silent --write-out '%{url_effective}\n%{filename_effective}' -L '$url' -O`; - chomp $url; - die "$0: unable to check ‘$url’\n" if $? != 0; - - # If the URL contains a version number, append it to the name - # attribute (so that "nix-env -q" on the channels profile - # shows something useful). - my $cname = $name; - $cname .= $1 if basename($url) =~ /(-\d.*)$/; - - my $path; - my $ret = -1; - if (-e "$tmpdir/$filename" && $filename =~ /\.tar\.(gz|bz2|xz)$/) { - # Get our temporary download into the store. - (my $hash, $path) = `PRINT_PATH=1 QUIET=1 $Nix::Config::binDir/nix-prefetch-url 'file://$tmpdir/$filename'`; - chomp $path; - - # Try unpacking the expressions to see if they'll be valid for us to process later. - # Like anything in nix, this will cache the result so we don't do it again outside of the loop below. - $ret = system("$Nix::Config::binDir/nix-build --no-out-link -E 'import <nix/unpack-channel.nix> " . - "{ name = \"$cname\"; channelName = \"$name\"; src = builtins.storePath \"$path\"; }'"); - } - - # The URL doesn't unpack directly, so let's try treating it like a full channel folder with files in it - my $extraAttrs = ""; - if ($ret != 0) { - # Check if the channel advertises a binary cache. - my $binaryCacheURL = `$Nix::Config::curl --silent '$url'/binary-cache-url`; - $extraAttrs .= "binaryCacheURL = \"$binaryCacheURL\"; " - if $? == 0 && $binaryCacheURL ne ""; - - # Download the channel tarball. - my $fullURL = "$url/nixexprs.tar.xz"; - system("$Nix::Config::curl --fail --silent --head '$fullURL' > /dev/null") == 0 or - $fullURL = "$url/nixexprs.tar.bz2"; - print STDERR "downloading Nix expressions from ‘$fullURL’...\n"; - (my $hash, $path) = `PRINT_PATH=1 QUIET=1 $Nix::Config::binDir/nix-prefetch-url '$fullURL'`; - die "cannot fetch ‘$fullURL’\n" if $? != 0; - chomp $path; - } - - # Regardless of where it came from, add the expression representing this channel to accumulated expression - $exprs .= "'f: f { name = \"$cname\"; channelName = \"$name\"; src = builtins.storePath \"$path\"; $extraAttrs }' "; - } - - # Unpack the channel tarballs into the Nix store and install them - # into the channels profile. - print STDERR "unpacking channels...\n"; - system("$Nix::Config::binDir/nix-env --profile '$profile' " . - "-f '<nix/unpack-channel.nix>' -i -E $exprs --quiet") == 0 - or die "cannot unpack the channels"; - - # Make the channels appear in nix-env. - unlink $nixDefExpr if -l $nixDefExpr; # old-skool ~/.nix-defexpr - mkdir $nixDefExpr or die "cannot create directory ‘$nixDefExpr’" if !-e $nixDefExpr; - my $channelLink = "$nixDefExpr/channels"; - unlink $channelLink; # !!! not atomic - symlink($profile, $channelLink) or die "cannot symlink ‘$channelLink’ to ‘$profile’"; -} - - -die "$0: argument expected\n" if scalar @ARGV == 0; - - -while (scalar @ARGV) { - my $arg = shift @ARGV; - - if ($arg eq "--add") { - die "$0: ‘--add’ requires one or two arguments\n" if scalar @ARGV < 1 || scalar @ARGV > 2; - my $url = shift @ARGV; - my $name = shift @ARGV; - unless (defined $name) { - $name = basename $url; - $name =~ s/-unstable//; - $name =~ s/-stable//; - } - addChannel($url, $name); - last; - } - - if ($arg eq "--remove") { - die "$0: ‘--remove’ requires one argument\n" if scalar @ARGV != 1; - removeChannel(shift @ARGV); - last; - } - - if ($arg eq "--list") { - die "$0: ‘--list’ requires one argument\n" if scalar @ARGV != 0; - readChannels; - foreach my $name (keys %channels) { - print "$name $channels{$name}\n"; - } - last; - } - - elsif ($arg eq "--update") { - update(@ARGV); - last; - } - - elsif ($arg eq "--rollback") { - die "$0: ‘--rollback’ has at most one argument\n" if scalar @ARGV > 1; - my $generation = shift @ARGV; - my @args = ("$Nix::Config::binDir/nix-env", "--profile", $profile); - if (defined $generation) { - die "invalid channel generation number ‘$generation’" unless $generation =~ /^[0-9]+$/; - push @args, "--switch-generation", $generation; - } else { - push @args, "--rollback"; - } - system(@args) == 0 or exit 1; - last; - } - - elsif ($arg eq "--help") { - exec "man nix-channel" or die; - } - - elsif ($arg eq "--version") { - print "nix-channel (Nix) $Nix::Config::version\n"; - exit 0; - } - - else { - die "unknown argument ‘$arg’; try ‘--help’\n"; - } -} diff --git a/scripts/nix-install-package.in b/scripts/nix-install-package.in deleted file mode 100755 index ba349774af54..000000000000 --- a/scripts/nix-install-package.in +++ /dev/null @@ -1,127 +0,0 @@ -#! @perl@ -w @perlFlags@ - -use utf8; -use strict; -use Nix::Config; -use Nix::Utils; - -binmode STDERR, ":encoding(utf8)"; - - -# Parse the command line arguments. -my @args = @ARGV; - -my $source; -my $fromURL = 0; -my @extraNixEnvArgs = (); -my $interactive = 1; -my $op = "--install"; - -while (scalar @args) { - my $arg = shift @args; - if ($arg eq "--help") { - exec "man nix-install-package" or die; - } - elsif ($arg eq "--url") { - $fromURL = 1; - } - elsif ($arg eq "--profile" || $arg eq "-p") { - my $profile = shift @args; - die "$0: ‘--profile’ requires an argument\n" if !defined $profile; - push @extraNixEnvArgs, "-p", $profile; - } - elsif ($arg eq "--set") { - $op = "--set"; - } - elsif ($arg eq "--non-interactive") { - $interactive = 0; - } - else { - $source = $arg; - } -} - -die "$0: please specify a .nixpkg file or URL\n" unless defined $source; - - -# Re-execute in a terminal, if necessary, so that if we're executed -# from a web browser, the user gets to see us. -if ($interactive && !defined $ENV{"NIX_HAVE_TERMINAL"}) { - $ENV{"NIX_HAVE_TERMINAL"} = "1"; - $ENV{"LD_LIBRARY_PATH"} = ""; - foreach my $term ("xterm", "konsole", "gnome-terminal", "xterm") { - exec($term, "-e", "$Nix::Config::binDir/nix-install-package", @ARGV); - } - die "cannot execute ‘xterm’"; -} - - -my $tmpDir = mkTempDir("nix-install-package"); - - -sub barf { - my $msg = shift; - print "\nInstallation failed: $msg\n"; - <STDIN> if $interactive; - exit 1; -} - - -# Download the package description, if necessary. -my $pkgFile = $source; -if ($fromURL) { - $pkgFile = "$tmpDir/tmp.nixpkg"; - system("@curl@", "-L", "--silent", $source, "-o", $pkgFile) == 0 - or barf "curl failed: $?"; -} - - -# Read and parse the package file. -open PKGFILE, "<$pkgFile" or barf "cannot open ‘$pkgFile’: $!"; -my $contents = <PKGFILE>; -close PKGFILE; - -my $nameRE = "(?: [A-Za-z0-9\+\-\.\_\?\=]+ )"; # see checkStoreName() -my $systemRE = "(?: [A-Za-z0-9\+\-\_]+ )"; -my $pathRE = "(?: \/ [\/A-Za-z0-9\+\-\.\_\?\=]* )"; - -# Note: $pathRE doesn't check that whether we're looking at a valid -# store path. We'll let nix-env do that. - -$contents =~ - / ^ \s* (\S+) \s+ (\S+) \s+ ($nameRE) \s+ ($systemRE) \s+ ($pathRE) \s+ ($pathRE) ( \s+ ($Nix::Utils::urlRE) )? /x - or barf "invalid package contents"; -my $version = $1; -my $manifestURL = $2; -my $drvName = $3; -my $system = $4; -my $drvPath = $5; -my $outPath = $6; -my $binaryCacheURL = $8; - -barf "invalid package version ‘$version’" unless $version eq "NIXPKG1"; - - -if ($interactive) { - # Ask confirmation. - print "Do you want to install ‘$drvName’ (Y/N)? "; - my $reply = <STDIN>; - chomp $reply; - exit if $reply ne "y" && $reply ne "Y"; -} - - -die "$0: package does not supply a binary cache\n" unless defined $binaryCacheURL; - -push @extraNixEnvArgs, "--option", "extra-binary-caches", $binaryCacheURL; - - -print "\nInstalling package...\n"; -system("$Nix::Config::binDir/nix-env", $op, $outPath, "--force-name", $drvName, @extraNixEnvArgs) == 0 - or barf "nix-env failed: $?"; - - -if ($interactive) { - print "\nInstallation succeeded! Press Enter to continue.\n"; - <STDIN>; -} diff --git a/scripts/nix-push.in b/scripts/nix-push.in deleted file mode 100755 index 54456ac9512e..000000000000 --- a/scripts/nix-push.in +++ /dev/null @@ -1,296 +0,0 @@ -#! @perl@ -w @perlFlags@ - -use utf8; -use strict; -use File::Basename; -use File::Path qw(mkpath); -use File::stat; -use File::Copy; -use MIME::Base64; -use Nix::Config; -use Nix::Store; -use Nix::Manifest; -use Nix::Utils; - -binmode STDERR, ":encoding(utf8)"; - -my $tmpDir = mkTempDir("nix-push"); - -my $nixExpr = "$tmpDir/create-nars.nix"; - - -# Parse the command line. -my $compressionType = "xz"; -my $force = 0; -my $destDir; -my $writeManifest = 0; -my $manifestPath; -my $archivesURL; -my $link = 0; -my $secretKeyFile; -my @roots; -my @buildArgs; - -for (my $n = 0; $n < scalar @ARGV; $n++) { - my $arg = $ARGV[$n]; - - if ($arg eq "--help") { - exec "man nix-push" or die; - } elsif ($arg eq "--bzip2") { - $compressionType = "bzip2"; - } elsif ($arg eq "--none") { - $compressionType = "none"; - } elsif ($arg eq "--force") { - $force = 1; - } elsif ($arg eq "--dest") { - $n++; - die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV; - $destDir = $ARGV[$n]; - mkpath($destDir, 0, 0755); - } elsif ($arg eq "--manifest") { - $writeManifest = 1; - } elsif ($arg eq "--manifest-path") { - $n++; - die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV; - $manifestPath = $ARGV[$n]; - $writeManifest = 1; - mkpath(dirname($manifestPath), 0, 0755); - } elsif ($arg eq "--url-prefix") { - $n++; - die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV; - $archivesURL = $ARGV[$n]; - } elsif ($arg eq "--link") { - $link = 1; - } elsif ($arg eq "--key-file") { - $n++; - die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV; - $secretKeyFile = $ARGV[$n]; - } elsif ($arg eq "--max-jobs" || $arg eq "-j") { - $n++; - die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV; - push @buildArgs, ($arg, $ARGV[$n]); - } elsif (substr($arg, 0, 1) eq "-") { - die "$0: unknown flag ‘$arg’\n"; - } else { - push @roots, $arg; - } -} - -die "$0: please specify a destination directory\n" if !defined $destDir; - -$archivesURL = "file://$destDir" unless defined $archivesURL; - - -# From the given store paths, determine the set of requisite store -# paths, i.e, the paths required to realise them. -my %storePaths; - -foreach my $path (@roots) { - # Get all paths referenced by the normalisation of the given - # Nix expression. - my $pid = open(READ, - "$Nix::Config::binDir/nix-store --query --requisites --force-realise " . - "--include-outputs '$path'|") or die; - - while (<READ>) { - chomp; - die "bad: $_" unless /^\//; - $storePaths{$_} = ""; - } - - close READ or die "nix-store failed: $?"; -} - -my @storePaths = keys %storePaths; - - -# Don't create archives for files that are already in the binary cache. -my @storePaths2; -my %narFiles; -foreach my $storePath (@storePaths) { - my $pathHash = substr(basename($storePath), 0, 32); - my $narInfoFile = "$destDir/$pathHash.narinfo"; - if (!$force && -e $narInfoFile) { - my $narInfo = parseNARInfo($storePath, readFile($narInfoFile), 0, $narInfoFile) or die "cannot read ‘$narInfoFile’\n"; - my $narFile = "$destDir/$narInfo->{url}"; - if (-e $narFile) { - print STDERR "skipping existing $storePath\n"; - # Add the NAR info to $narFiles if we're writing a - # manifest. - $narFiles{$storePath} = [ - { url => ("$archivesURL/" . basename $narInfo->{url}) - , hash => $narInfo->{fileHash} - , size => $narInfo->{fileSize} - , compressionType => $narInfo->{compression} - , narHash => $narInfo->{narHash} - , narSize => $narInfo->{narSize} - , references => join(" ", map { "$Nix::Config::storeDir/$_" } @{$narInfo->{refs}}) - , deriver => $narInfo->{deriver} ? "$Nix::Config::storeDir/$narInfo->{deriver}" : undef - } - ] if $writeManifest; - next; - } - } - push @storePaths2, $storePath; -} - - -# Create a list of Nix derivations that turn each path into a Nix -# archive. -open NIX, ">$nixExpr"; -print NIX "["; - -foreach my $storePath (@storePaths2) { - die unless ($storePath =~ /\/[0-9a-z]{32}[^\"\\\$]*$/); - - # Construct a Nix expression that creates a Nix archive. - my $nixexpr = - "(import <nix/nar.nix> " . - "{ storePath = builtins.storePath \"$storePath\"; hashAlgo = \"sha256\"; compressionType = \"$compressionType\"; }) "; - - print NIX $nixexpr; -} - -print NIX "]"; -close NIX; - - -# Build the Nix expression. -print STDERR "building compressed archives...\n"; -my @narPaths; -my $pid = open(READ, "-|", "$Nix::Config::binDir/nix-build", $nixExpr, "-o", "$tmpDir/result", @buildArgs) - or die "cannot run nix-build"; -while (<READ>) { - chomp; - die unless /^\//; - push @narPaths, $_; -} -close READ or die "nix-build failed: $?"; - - -# Write the cache info file. -my $cacheInfoFile = "$destDir/nix-cache-info"; -if (! -e $cacheInfoFile) { - open FILE, ">$cacheInfoFile" or die "cannot create $cacheInfoFile: $!"; - print FILE "StoreDir: $Nix::Config::storeDir\n"; - print FILE "WantMassQuery: 0\n"; # by default, don't hit this cache for "nix-env -qas" - close FILE; -} - - -# Copy the archives and the corresponding NAR info files. -print STDERR "copying archives...\n"; - -my $totalNarSize = 0; -my $totalCompressedSize = 0; - -for (my $n = 0; $n < scalar @storePaths2; $n++) { - my $storePath = $storePaths2[$n]; - my $narDir = $narPaths[$n]; - my $baseName = basename $storePath; - - # Get info about the store path. - my ($deriver, $narHash, $time, $narSize, $refs) = queryPathInfo($storePath, 1); - - # In some exceptional cases (such as VM tests that use the Nix - # store of the host), the database doesn't contain the hash. So - # compute it. - if ($narHash =~ /^sha256:0*$/) { - my $nar = "$tmpDir/nar"; - system("$Nix::Config::binDir/nix-store --dump $storePath > $nar") == 0 - or die "cannot dump $storePath\n"; - $narHash = `$Nix::Config::binDir/nix-hash --type sha256 --base32 --flat $nar`; - die "cannot hash ‘$nar’" if $? != 0; - chomp $narHash; - $narHash = "sha256:$narHash"; - $narSize = stat("$nar")->size; - unlink $nar or die; - } - - $totalNarSize += $narSize; - - # Get info about the compressed NAR. - open HASH, "$narDir/nar-compressed-hash" or die "cannot open nar-compressed-hash"; - my $compressedHash = <HASH>; - chomp $compressedHash; - $compressedHash =~ /^[0-9a-z]+$/ or die "invalid hash"; - close HASH; - - my $narName = "$compressedHash.nar" . ($compressionType eq "xz" ? ".xz" : $compressionType eq "bzip2" ? ".bz2" : ""); - - my $narFile = "$narDir/$narName"; - (-f $narFile) or die "NAR file for $storePath not found"; - - my $compressedSize = stat($narFile)->size; - $totalCompressedSize += $compressedSize; - - printf STDERR "%s [%.2f MiB, %.1f%%]\n", $storePath, - $compressedSize / (1024 * 1024), $compressedSize / $narSize * 100; - - # Copy the compressed NAR. - my $dst = "$destDir/$narName"; - if (! -f $dst) { - my $tmp = "$destDir/.tmp.$$.$narName"; - if ($link) { - link($narFile, $tmp) or die "cannot link $tmp to $narFile: $!\n"; - } else { - copy($narFile, $tmp) or die "cannot copy $narFile to $tmp: $!\n"; - } - rename($tmp, $dst) or die "cannot rename $tmp to $dst: $!\n"; - } - - # Write the info file. - my $info; - $info .= "StorePath: $storePath\n"; - $info .= "URL: $narName\n"; - $info .= "Compression: $compressionType\n"; - $info .= "FileHash: sha256:$compressedHash\n"; - $info .= "FileSize: $compressedSize\n"; - $info .= "NarHash: $narHash\n"; - $info .= "NarSize: $narSize\n"; - $info .= "References: " . join(" ", map { basename $_ } @{$refs}) . "\n"; - if (defined $deriver) { - $info .= "Deriver: " . basename $deriver . "\n"; - if (isValidPath($deriver)) { - my $drv = derivationFromPath($deriver); - $info .= "System: $drv->{platform}\n"; - } - } - - if (defined $secretKeyFile) { - my $secretKey = readFile $secretKeyFile; - my $fingerprint = fingerprintPath($storePath, $narHash, $narSize, $refs); - my $sig = signString($secretKey, $fingerprint); - $info .= "Sig: $sig\n"; - } - - my $pathHash = substr(basename($storePath), 0, 32); - - $dst = "$destDir/$pathHash.narinfo"; - if ($force || ! -f $dst) { - my $tmp = "$destDir/.tmp.$$.$pathHash.narinfo"; - open INFO, ">$tmp" or die; - print INFO "$info" or die; - close INFO or die; - rename($tmp, $dst) or die "cannot rename $tmp to $dst: $!\n"; - } - - $narFiles{$storePath} = [ - { url => "$archivesURL/$narName" - , hash => "sha256:$compressedHash" - , size => $compressedSize - , compressionType => $compressionType - , narHash => "$narHash" - , narSize => $narSize - , references => join(" ", @{$refs}) - , deriver => $deriver - } - ] if $writeManifest; -} - -printf STDERR "total compressed size %.2f MiB, %.1f%%\n", - $totalCompressedSize / (1024 * 1024), $totalCompressedSize / ($totalNarSize || 1) * 100; - - -# Optionally write a manifest. -writeManifest($manifestPath // "$destDir/MANIFEST", \%narFiles, \()) if $writeManifest; diff --git a/scripts/resolve-system-dependencies.pl.in b/scripts/resolve-system-dependencies.pl.in deleted file mode 100755 index a20f0dc020fe..000000000000 --- a/scripts/resolve-system-dependencies.pl.in +++ /dev/null @@ -1,122 +0,0 @@ -#! @perl@ -w @perlFlags@ - -use utf8; -use strict; -use warnings; -use Cwd qw(realpath); -use Errno; -use File::Basename qw(dirname); -use File::Path qw(make_path); -use File::Spec::Functions qw(catfile); -use List::Util qw(reduce); -use IPC::Open3; -use Nix::Config; -use Nix::Store qw(derivationFromPath); -use POSIX qw(uname); -use Storable qw(lock_retrieve lock_store); - -my ($sysname, undef, $version, undef, $machine) = uname; -$sysname =~ /Darwin/ or die "This tool is only meant to be used on Darwin systems."; - -my $cache = "$Nix::Config::stateDir/dependency-maps/$machine-$sysname-$version.map"; - -make_path dirname($cache); - -our $DEPS; -eval { - $DEPS = lock_retrieve($cache); -}; - -if($!{ENOENT}) { - lock_store {}, $cache; - $DEPS = {}; -} elsif($@) { - die "Unable to obtain a lock on dependency-map file $cache: $@"; -} - -sub mkset(@) { - my %set; - @set{@_} = (); - \%set -} - -sub union($$) { - my ($set1, $set2) = @_; - my %new = (%$set1, %$set2); - \%new -} - -sub cache_filepath($) { - my $fp = shift; - $fp =~ s/-/--/g; - $fp =~ s/\//-/g; - $fp =~ s/^-//g; - catfile $cache, $fp -} - -sub resolve_tree { - sub resolve_tree_inner { - my ($lib, $TREE) = @_; - return if (defined $TREE->{$lib}); - $TREE->{$lib} = mkset(@{cache_get($lib)}); - foreach my $dep (keys %{$TREE->{$lib}}) { - resolve_tree_inner($dep, $TREE); - } - values %$TREE - } - - reduce { union($a, $b) } {}, resolve_tree_inner(@_) -} - -sub cache_get { - my $key = shift; - if (defined $DEPS->{$key}) { - $DEPS->{$key} - } else { - cache_insert($key); - cache_get($key) - } -} - -sub cache_insert($) { - my $key = shift; - print STDERR "Finding dependencies for $key...\n"; - my @deps = find_deps($key); - $DEPS->{$key} = \@deps; -} - -sub find_deps($) { - my $lib = shift; - my($chld_in, $chld_out, $chld_err); - my $pid = open3($chld_in, $chld_out, $chld_err, "@otool@", "-L", "-arch", "x86_64", $lib); - waitpid($pid, 0); - my $line = readline $chld_out; - if($? == 0 and $line !~ /not an object file/) { - my @libs; - while(<$chld_out>) { - my $dep = (split /\s+/)[1]; - push @libs, $dep unless $dep eq $lib or $dep =~ /\@rpath/; - } - @libs - } elsif (-l $lib) { - (realpath($lib)) - } else { - () - } -} - -if (defined $ARGV[0]) { - my $deps = derivationFromPath($ARGV[0])->{"env"}->{"__impureHostDeps"}; - if (defined $deps) { - my @files = split(/\s+/, $deps); - my $depcache = {}; - my $depset = reduce { union($a, $b) } (map { resolve_tree($_, $depcache) } @files); - print "extra-chroot-dirs\n"; - print join("\n", keys %$depset); - print "\n"; - } - lock_store($DEPS, $cache); -} else { - print STDERR "Usage: $0 path/to/derivation.drv\n"; - exit 1 -} diff --git a/scripts/show-duplication.pl b/scripts/show-duplication.pl deleted file mode 100755 index 0604c6696c7a..000000000000 --- a/scripts/show-duplication.pl +++ /dev/null @@ -1,73 +0,0 @@ -#! /usr/bin/perl -w - -if (scalar @ARGV != 1) { - print "syntax: show-duplication.pl PATH\n"; - exit 1; -} - -my $root = $ARGV[0]; - - -my $nameRE = "(?:(?:[A-Za-z0-9\+\_]|(?:-[^0-9]))+)"; -my $versionRE = "(?:[A-Za-z0-9\.\-]+)"; - - -my %pkgInstances; - - -my $pid = open(PATHS, "-|") || exec "nix-store", "-qR", $root; -while (<PATHS>) { - chomp; - /^.*\/[0-9a-z]*-(.*)$/; - my $nameVersion = $1; - $nameVersion =~ /^($nameRE)(-($versionRE))?$/; - $name = $1; - $version = $3; - $version = "(unnumbered)" unless defined $version; -# print "$nameVersion $name $version\n"; - push @{$pkgInstances{$name}}, {version => $version, path => $_}; -} -close PATHS or exit 1; - - -sub pathSize { - my $path = shift; - my @st = lstat $path or die; - - my $size = $st[7]; - - if (-d $path) { - opendir DIR, $path or die; - foreach my $name (readdir DIR) { - next if $name eq "." || $name eq ".."; - $size += pathSize("$path/$name"); - } - } - - return $size; -} - - -my $totalPaths = 0; -my $totalSize = 0, $totalWaste = 0; - -foreach my $name (sort {scalar @{$pkgInstances{$b}} <=> scalar @{$pkgInstances{$a}}} (keys %pkgInstances)) { - print "$name ", scalar @{$pkgInstances{$name}}, "\n"; - my $allSize = 0; - foreach my $x (sort {$a->{version} cmp $b->{version}} @{$pkgInstances{$name}}) { - $totalPaths++; - my $size = pathSize $x->{path}; - $allSize += $size; - print " $x->{version} $size\n"; - } - my $avgSize = int($allSize / scalar @{$pkgInstances{$name}}); - my $waste = $allSize - $avgSize; - $totalSize += $allSize; - $totalWaste += $waste; - print " average $avgSize, waste $waste\n"; -} - - -my $avgDupl = $totalPaths / scalar (keys %pkgInstances); -my $wasteFactor = ($totalWaste / $totalSize) * 100; -print "average package duplication $avgDupl, total size $totalSize, total waste $totalWaste, $wasteFactor% wasted\n"; |