aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2015-10-07 17:31:50 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2015-10-07 17:31:50 +0200
commit21ecd106edff6d97a0241b75b3d07d81bdb5cdfe (patch)
treefac551e945ea3d0472fc6f437150db11e7709247
parentf08449ccbd2009b858aae18341aedf3d0829b91a (diff)
Show progress during downloads
-rw-r--r--src/libstore/download.cc54
-rw-r--r--src/nix-prefetch-url/nix-prefetch-url.cc1
2 files changed, 47 insertions, 8 deletions
diff --git a/src/libstore/download.cc b/src/libstore/download.cc
index 9bf3e13aa..727d9fc8b 100644
--- a/src/libstore/download.cc
+++ b/src/libstore/download.cc
@@ -6,8 +6,18 @@
#include <curl/curl.h>
+#include <iostream>
+
+
namespace nix {
+double getTime()
+{
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ return tv.tv_sec + (tv.tv_usec / 1000000.0);
+}
+
struct Curl
{
CURL * curl;
@@ -16,6 +26,10 @@ struct Curl
struct curl_slist * requestHeaders;
+ bool showProgress;
+ double prevProgressTime{0}, startTime{0};
+ unsigned int moveBack{1};
+
static size_t writeCallback(void * contents, size_t size, size_t nmemb, void * userp)
{
Curl & c(* (Curl *) userp);
@@ -56,11 +70,30 @@ struct Curl
return realSize;
}
- static int progressCallback(void * clientp, double dltotal, double dlnow, double ultotal, double ulnow)
+ int xferInfoCallback(curl_off_t dltotal, curl_off_t dlnow)
{
+ if (showProgress) {
+ double now = getTime();
+ if (prevProgressTime <= now - 1) {
+ string s = (format(" [%1$.0f/%2$.0f KiB, %3$.1f KiB/s]")
+ % (dlnow / 1024.0)
+ % (dltotal / 1024.0)
+ % (now == startTime ? 0 : dlnow / 1024.0 / (now - startTime))).str();
+ std::cerr << "\e[" << moveBack << "D" << s;
+ moveBack = s.size();
+ std::cerr.flush();
+ prevProgressTime = now;
+ }
+ }
return _isInterrupted;
}
+ static int xferInfoCallback_(void * userp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
+ {
+ Curl & c(* (Curl *) userp);
+ return c.xferInfoCallback(dltotal, dlnow);
+ }
+
Curl()
{
requestHeaders = 0;
@@ -79,8 +112,11 @@ struct Curl
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, headerCallback);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void *) &curl);
- curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progressCallback);
+ curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferInfoCallback_);
+ curl_easy_setopt(curl, CURLOPT_XFERINFODATA, (void *) &curl);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
+
+ showProgress = isatty(STDERR_FILENO);
}
~Curl()
@@ -107,7 +143,16 @@ struct Curl
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, requestHeaders);
+ if (showProgress) {
+ std::cerr << (format("downloading ‘%1%’... ") % url);
+ std::cerr.flush();
+ startTime = getTime();
+ }
+
CURLcode res = curl_easy_perform(curl);
+ if (showProgress)
+ //std::cerr << "\e[" << moveBack << "D\e[K\n";
+ std::cerr << "\n";
checkInterrupt();
if (res == CURLE_WRITE_ERROR && etag == expectedETag) return false;
if (res != CURLE_OK)
@@ -178,11 +223,6 @@ Path downloadFileCached(const string & url, bool unpack)
if (!skip) {
- if (storePath.empty())
- printMsg(lvlInfo, format("downloading ‘%1%’...") % url);
- else
- printMsg(lvlInfo, format("checking ‘%1%’...") % url);
-
try {
auto res = downloadFile(url, expectedETag);
diff --git a/src/nix-prefetch-url/nix-prefetch-url.cc b/src/nix-prefetch-url/nix-prefetch-url.cc
index 0a8166da4..12aa71572 100644
--- a/src/nix-prefetch-url/nix-prefetch-url.cc
+++ b/src/nix-prefetch-url/nix-prefetch-url.cc
@@ -158,7 +158,6 @@ int main(int argc, char * * argv)
auto actualUri = resolveMirrorUri(state, uri);
/* Download the file. */
- printMsg(lvlInfo, format("downloading ‘%1%’...") % actualUri);
auto result = downloadFile(actualUri);
AutoDelete tmpDir(createTempDir(), true);