summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vogt <mvo@debian.org>2013-10-11 19:27:23 +0200
committerMichael Vogt <mvo@debian.org>2013-10-11 19:27:23 +0200
commit31f97d7b862ccf3de93b30a15f24d76e806031a3 (patch)
treebe7d38556a459169f083becb8ade1627520a5c5b
parent3921580c0b7ab67abb6eb5374af94d8951c525fe (diff)
first iteration of install progress refactor
-rw-r--r--apt-pkg/deb/dpkgpm.cc111
-rw-r--r--apt-pkg/deb/dpkgpm.h1
-rw-r--r--apt-pkg/iprogress.cc111
-rw-r--r--apt-pkg/iprogress.h59
-rw-r--r--apt-pkg/makefile4
-rw-r--r--apt-pkg/packagemanager.h1
6 files changed, 194 insertions, 93 deletions
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index b4d812d26..cd4f5c31e 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -19,6 +19,7 @@
#include <apt-pkg/fileutl.h>
#include <apt-pkg/cachefile.h>
#include <apt-pkg/packagemanager.h>
+#include <apt-pkg/iprogress.h>
#include <unistd.h>
#include <stdlib.h>
@@ -54,16 +55,21 @@ class pkgDPkgPMPrivate
public:
pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0),
term_out(NULL), history_out(NULL),
- last_reported_progress(0.0), nr_terminal_rows(0),
- fancy_progress_output(false)
+ last_reported_progress(0.0)
{
dpkgbuf[0] = '\0';
- if(_config->FindB("Dpkg::Progress-Fancy", false) == true)
- {
- fancy_progress_output = true;
- _config->Set("DpkgPM::Progress", true);
- }
+ if(_config->FindB("DpkgPM::Progress-Fancy", false) == true)
+ progress = new APT::Progress::PackageManagerFancy();
+ else if (_config->FindB("DpkgPM::Progress", false) == true)
+ progress = new APT::Progress::PackageManagerText();
+ else
+ progress = new APT::Progress::PackageManager();
}
+ ~pkgDPkgPMPrivate()
+ {
+ delete progress;
+ }
+
bool stdin_is_dev_null;
// the buffer we use for the dpkg status-fd reading
char dpkgbuf[1024];
@@ -73,8 +79,7 @@ public:
string dpkg_error;
float last_reported_progress;
- int nr_terminal_rows;
- bool fancy_progress_output;
+ APT::Progress::PackageManager *progress;
};
namespace
@@ -644,8 +649,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
<< ":" << (PackagesDone/float(PackagesTotal)*100.0)
<< ":" << s
<< endl;
- if(_config->FindB("DPkgPM::Progress", false) == true)
- SendTerminalProgress(PackagesDone/float(PackagesTotal)*100.0);
+ d->progress->StatusChanged(pkg, PackagesDone, PackagesTotal);
if(OutStatusFd > 0)
FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size());
@@ -889,52 +893,6 @@ bool pkgDPkgPM::CloseLog()
return true;
}
/*}}}*/
-// DPkgPM::SendTerminalProgress /*{{{*/
-// ---------------------------------------------------------------------
-/* Send progress info to the terminal
- */
-void pkgDPkgPM::SendTerminalProgress(float percentage)
-{
- int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1);
-
- if(percentage < (d->last_reported_progress + reporting_steps))
- return;
-
- std::string progress_str;
- strprintf(progress_str, "Progress: [%3i%%]", (int)percentage);
- if (d->fancy_progress_output)
- {
- int row = d->nr_terminal_rows;
-
- static string save_cursor = "\033[s";
- static string restore_cursor = "\033[u";
-
- static string set_bg_color = "\033[42m"; // green
- static string set_fg_color = "\033[30m"; // black
-
- static string restore_bg = "\033[49m";
- static string restore_fg = "\033[39m";
-
- std::cout << save_cursor
- // move cursor position to last row
- << "\033[" << row << ";0f"
- << set_bg_color
- << set_fg_color
- << progress_str
- << restore_cursor
- << restore_bg
- << restore_fg;
- }
- else
- {
- std::cout << progress_str << "\r\n";
- }
- std::flush(std::cout);
-
- d->last_reported_progress = percentage;
-}
- /*}}}*/
-/*{{{*/
// This implements a racy version of pselect for those architectures
// that don't have a working implementation.
// FIXME: Probably can be removed on Lenny+1
@@ -956,27 +914,6 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds,
}
/*}}}*/
-void pkgDPkgPM::SetupTerminalScrollArea(int nr_rows)
-{
- if(!d->fancy_progress_output)
- return;
-
- // scroll down a bit to avoid visual glitch when the screen
- // area shrinks by one row
- std::cout << "\n";
-
- // save cursor
- std::cout << "\033[s";
-
- // set scroll region (this will place the cursor in the top left)
- std::cout << "\033[1;" << nr_rows - 1 << "r";
-
- // restore cursor but ensure its inside the scrolling area
- std::cout << "\033[u";
- static const char *move_cursor_up = "\033[1A";
- std::cout << move_cursor_up;
- std::flush(std::cout);
-}
// DPkgPM::Go - Run the sequence /*{{{*/
// ---------------------------------------------------------------------
@@ -1334,8 +1271,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
_error->PushToStack();
if (tcgetattr(STDOUT_FILENO, &tt) == 0)
{
- ioctl(1, TIOCGWINSZ, (char *)&win);
- d->nr_terminal_rows = win.ws_row;
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win);
if (openpty(&master, &slave, NULL, &tt, &win) < 0)
{
_error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
@@ -1415,7 +1351,6 @@ bool pkgDPkgPM::Go(int OutStatusFd)
if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0)
_exit(100);
}
- SetupTerminalScrollArea(d->nr_terminal_rows);
/* No Job Control Stop Env is a magic dpkg var that prevents it
from using sigstop */
@@ -1424,6 +1359,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
cerr << "Could not exec dpkg!" << endl;
_exit(100);
}
+ d->progress->Started();
// apply ionice
if (_config->FindB("DPkg::UseIoNice", false) == true)
@@ -1510,14 +1446,8 @@ bool pkgDPkgPM::Go(int OutStatusFd)
signal(SIGHUP,old_SIGHUP);
- // reset scroll area
- SetupTerminalScrollArea(d->nr_terminal_rows + 1);
- if(d->fancy_progress_output)
- {
- // override the progress line (sledgehammer)
- static const char* clear_screen_below_cursor = "\033[J";
- std::cout << clear_screen_below_cursor;
- }
+ // tell the progress
+ d->progress->Finished();
if(master >= 0)
{
@@ -1556,8 +1486,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
CloseLog();
// dpkg is done at this point
- if(_config->FindB("DPkgPM::Progress", false) == true)
- SendTerminalProgress(100);
+ d->progress->StatusChanged("", PackagesDone, PackagesTotal);
if (pkgPackageManager::SigINTStop)
_error->Warning(_("Operation was interrupted before it could finish"));
diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h
index 3b8d36623..53e352d4e 100644
--- a/apt-pkg/deb/dpkgpm.h
+++ b/apt-pkg/deb/dpkgpm.h
@@ -23,6 +23,7 @@ using std::map;
class pkgDPkgPMPrivate;
+
class pkgDPkgPM : public pkgPackageManager
{
private:
diff --git a/apt-pkg/iprogress.cc b/apt-pkg/iprogress.cc
new file mode 100644
index 000000000..4de8c0492
--- /dev/null
+++ b/apt-pkg/iprogress.cc
@@ -0,0 +1,111 @@
+#include <apt-pkg/iprogress.h>
+#include <apt-pkg/strutl.h>
+
+#include <termios.h>
+#include <sys/ioctl.h>
+
+namespace APT {
+namespace Progress {
+
+static void SetupTerminalScrollArea(int nr_rows)
+{
+ // scroll down a bit to avoid visual glitch when the screen
+ // area shrinks by one row
+ std::cout << "\n";
+
+ // save cursor
+ std::cout << "\033[s";
+
+ // set scroll region (this will place the cursor in the top left)
+ std::cout << "\033[1;" << nr_rows - 1 << "r";
+
+ // restore cursor but ensure its inside the scrolling area
+ std::cout << "\033[u";
+ static const char *move_cursor_up = "\033[1A";
+ std::cout << move_cursor_up;
+ std::flush(std::cout);
+}
+
+PackageManagerFancy::PackageManagerFancy()
+ : nr_terminal_rows(-1)
+{
+ struct winsize win;
+ if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) == 0)
+ {
+ nr_terminal_rows = win.ws_row;
+ }
+}
+
+void PackageManagerFancy::Started()
+{
+ SetupTerminalScrollArea(nr_terminal_rows);
+}
+
+void PackageManagerFancy::Finished()
+{
+ SetupTerminalScrollArea(nr_terminal_rows + 1);
+
+ // override the progress line (sledgehammer)
+ static const char* clear_screen_below_cursor = "\033[J";
+ std::cout << clear_screen_below_cursor;
+}
+
+void PackageManagerFancy::StatusChanged(std::string PackageName,
+ unsigned int StepsDone,
+ unsigned int TotalSteps)
+{
+ int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1);
+ float percentage = StepsDone/(float)TotalSteps * 100.0;
+
+ if(percentage < (last_reported_progress + reporting_steps))
+ return;
+
+ std::string progress_str;
+ strprintf(progress_str, "Progress: [%3i%%]", (int)percentage);
+
+ int row = nr_terminal_rows;
+
+ static string save_cursor = "\033[s";
+ static string restore_cursor = "\033[u";
+
+ static string set_bg_color = "\033[42m"; // green
+ static string set_fg_color = "\033[30m"; // black
+
+ static string restore_bg = "\033[49m";
+ static string restore_fg = "\033[39m";
+
+ std::cout << save_cursor
+ // move cursor position to last row
+ << "\033[" << row << ";0f"
+ << set_bg_color
+ << set_fg_color
+ << progress_str
+ << restore_cursor
+ << restore_bg
+ << restore_fg;
+ std::flush(std::cout);
+ last_reported_progress = percentage;
+}
+
+void PackageManagerText::StatusChanged(std::string PackageName,
+ unsigned int StepsDone,
+ unsigned int TotalSteps)
+{
+ int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1);
+ float percentage = StepsDone/(float)TotalSteps * 100.0;
+
+ if(percentage < (last_reported_progress + reporting_steps))
+ return;
+
+ std::string progress_str;
+ strprintf(progress_str, "Progress: [%3i%%]", (int)percentage);
+
+ std::cout << progress_str << "\r\n";
+ std::flush(std::cout);
+
+ last_reported_progress = percentage;
+}
+
+
+}; // namespace progress
+}; // namespace apt
diff --git a/apt-pkg/iprogress.h b/apt-pkg/iprogress.h
new file mode 100644
index 000000000..14fc89bff
--- /dev/null
+++ b/apt-pkg/iprogress.h
@@ -0,0 +1,59 @@
+#ifndef PKGLIB_IPROGRESS_H
+#define PKGLIB_IPROGRSS_H
+
+
+#include <apt-pkg/packagemanager.h>
+
+namespace APT {
+namespace Progress {
+
+
+ class PackageManager
+ {
+ private:
+ /** \brief dpointer placeholder */
+ void *d;
+
+ public:
+ virtual ~PackageManager() {};
+
+ virtual void Started() {};
+ virtual void Finished() {};
+
+ virtual void StatusChanged(std::string PackageName,
+ unsigned int StepsDone,
+ unsigned int TotalSteps) {};
+ };
+
+ class PackageManagerFancy : public PackageManager
+ {
+ protected:
+ int last_reported_progress;
+ int nr_terminal_rows;
+ public:
+ PackageManagerFancy();
+ virtual void Started();
+ virtual void Finished();
+ virtual void StatusChanged(std::string PackageName,
+ unsigned int StepsDone,
+ unsigned int TotalSteps);
+ };
+
+ class PackageManagerText : public PackageManager
+ {
+ protected:
+ int last_reported_progress;
+
+ public:
+ PackageManagerText() : last_reported_progress(0) {};
+ virtual void StatusChanged(std::string PackageName,
+ unsigned int StepsDone,
+ unsigned int TotalSteps);
+
+ };
+
+
+}; // namespace Progress
+}; // namespace APT
+
+#endif
diff --git a/apt-pkg/makefile b/apt-pkg/makefile
index 59729faf5..e69b5ce7f 100644
--- a/apt-pkg/makefile
+++ b/apt-pkg/makefile
@@ -43,7 +43,7 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \
srcrecords.cc cachefile.cc versionmatch.cc policy.cc \
pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \
indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \
- aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc
+ aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc iprogress.cc
HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \
orderlist.h sourcelist.h packagemanager.h tagfile.h \
init.h pkgcache.h version.h progress.h pkgrecords.h \
@@ -51,7 +51,7 @@ HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \
clean.h srcrecords.h cachefile.h versionmatch.h policy.h \
pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \
vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \
- cachefilter.h cacheset.h edsp.h
+ cachefilter.h cacheset.h edsp.h iprogress.h
# Source code for the debian specific components
# In theory the deb headers do not need to be exported..
diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h
index 1a6a9f01c..4956e816f 100644
--- a/apt-pkg/packagemanager.h
+++ b/apt-pkg/packagemanager.h
@@ -39,6 +39,7 @@ class pkgDepCache;
class pkgSourceList;
class pkgOrderList;
class pkgRecords;
+
class pkgPackageManager : protected pkgCache::Namespace
{
public: