//
///////////////////////////////////////////////////////////////////
- Pathname HistoryLog::_fname(ZConfig::instance().historyLogFile());
- std::ofstream HistoryLog::_log;
- unsigned HistoryLog::_refcnt = 0;
- const char HistoryLog::_sep = '|';
+ Pathname HistoryLog::_fname(ZConfig::instance().historyLogFile());
+ std::ofstream HistoryLog::_log;
+ unsigned HistoryLog::_refcnt = 0;
+ const char HistoryLog::_sep = '|';
- ///////////////////////////////////////////////////////////////////
-
- HistoryLog::HistoryLog( const Pathname & rootdir )
- {
- refUp();
- if (!rootdir.empty() && rootdir.absolute())
- _fname = rootdir / ZConfig::instance().historyLogFile();
- }
+ ///////////////////////////////////////////////////////////////////
- void HistoryLog::openLog()
- {
- if ( !_fname.empty() )
- {
- _log.clear();
- _log.open( _fname.asString().c_str(), std::ios::out|std::ios::app );
- if( !_log )
- ERR << "Could not open logfile '" << _fname << "'" << endl;
- }
- }
+ HistoryLog::HistoryLog( const Pathname & rootdir )
+ {
+ refUp();
+ if (!rootdir.empty() && rootdir.absolute())
+ _fname = rootdir / ZConfig::instance().historyLogFile();
+ }
- void HistoryLog::closeLog()
+ void HistoryLog::openLog()
+ {
+ if ( !_fname.empty() )
{
_log.clear();
- _log.close();
- }
-
- void HistoryLog::refUp()
- {
- if ( !_refcnt )
- openLog();
- ++_refcnt;
- }
-
- void HistoryLog::refDown()
- {
- --_refcnt;
- if ( !_refcnt )
- closeLog();
+ _log.open( _fname.asString().c_str(), std::ios::out|std::ios::app );
+ if( !_log )
+ ERR << "Could not open logfile '" << _fname << "'" << endl;
}
+ }
+ void HistoryLog::closeLog()
+ {
+ _log.clear();
+ _log.close();
+ }
- void HistoryLog::setRoot( const Pathname & rootdir )
- {
- if (rootdir.empty() || !rootdir.absolute())
- return;
-
- if ( _refcnt )
- closeLog();
-
- _fname = rootdir / "/var/log/zypp/history";
- filesystem::assert_dir( _fname.dirname() );
- MIL << "installation log file " << _fname << endl;
+ void HistoryLog::refUp()
+ {
+ if ( !_refcnt )
+ openLog();
+ ++_refcnt;
+ }
- if ( _refcnt )
- openLog();
- }
+ void HistoryLog::refDown()
+ {
+ --_refcnt;
+ if ( !_refcnt )
+ closeLog();
+ }
- const Pathname & HistoryLog::fname()
- { return _fname; }
+ void HistoryLog::setRoot( const Pathname & rootdir )
+ {
+ if (rootdir.empty() || !rootdir.absolute())
+ return;
- /////////////////////////////////////////////////////////////////////////
+ if ( _refcnt )
+ closeLog();
- void HistoryLog::comment( const string & comment, bool timestamp )
- {
- if (comment.empty())
- return;
+ _fname = rootdir / "/var/log/zypp/history";
+ filesystem::assert_dir( _fname.dirname() );
+ MIL << "installation log file " << _fname << endl;
- _log << "# ";
- if ( timestamp )
- _log << ::timestamp() << " ";
+ if ( _refcnt )
+ openLog();
+ }
- const char * s = comment.c_str();
- const char * c = s;
- unsigned size = comment.size();
- // ignore the last newline
- if (comment[size-1] == '\n')
- --size;
+ const Pathname & HistoryLog::fname()
+ { return _fname; }
- for ( unsigned i = 0; i < size; ++i, ++c )
- if ( *c == '\n' )
- {
- _log << string( s, c + 1 - s ) << "# ";
- s = c + 1;
- }
+ /////////////////////////////////////////////////////////////////////////
- if ( s < c )
- _log << std::string( s, c-s );
+ void HistoryLog::comment( const string & comment, bool timestamp )
+ {
+ if (comment.empty())
+ return;
- _log << endl;
- }
+ _log << "# ";
+ if ( timestamp )
+ _log << ::timestamp() << " ";
- /////////////////////////////////////////////////////////////////////////
-
- void HistoryLog::install( const PoolItem & pi )
- {
- const Package::constPtr p = asKind<Package>(pi.resolvable());
- if (!p)
- return;
+ const char * s = comment.c_str();
+ const char * c = s;
+ unsigned size = comment.size();
- _log
- << timestamp() // 1 timestamp
- << _sep << HistoryActionID::INSTALL.asString(true) // 2 action
- << _sep << p->name() // 3 name
- << _sep << p->edition() // 4 evr
- << _sep << p->arch(); // 5 arch
-
- if (pi.status().isByUser())
- _log << _sep << userAtHostname(); // 6 reqested by
- //else if (pi.status().isByApplHigh() || pi.status().isByApplLow())
- // _log << _sep << "appl";
- else
- _log << _sep;
+ // ignore the last newline
+ if (comment[size-1] == '\n')
+ --size;
- _log
- << _sep << p->repoInfo().alias() // 7 repo alias
- << _sep << p->checksum().checksum(); // 8 checksum
+ for ( unsigned i = 0; i < size; ++i, ++c )
+ if ( *c == '\n' )
+ {
+ _log << string( s, c + 1 - s ) << "# ";
+ s = c + 1;
+ }
- _log << endl;
+ if ( s < c )
+ _log << std::string( s, c-s );
- //_log << pi << endl;
- }
+ _log << endl;
+ }
+ /////////////////////////////////////////////////////////////////////////
+
+ void HistoryLog::install( const PoolItem & pi )
+ {
+ const Package::constPtr p = asKind<Package>(pi.resolvable());
+ if (!p)
+ return;
+
+ _log
+ << timestamp() // 1 timestamp
+ << _sep << HistoryActionID::INSTALL.asString(true) // 2 action
+ << _sep << p->name() // 3 name
+ << _sep << p->edition() // 4 evr
+ << _sep << p->arch(); // 5 arch
+
+ if (pi.status().isByUser())
+ _log << _sep << userAtHostname(); // 6 reqested by
+ //else if (pi.status().isByApplHigh() || pi.status().isByApplLow())
+ // _log << _sep << "appl";
+ else
+ _log << _sep;
+
+ _log
+ << _sep << p->repoInfo().alias() // 7 repo alias
+ << _sep << p->checksum().checksum(); // 8 checksum
+
+ _log << endl;
+
+ //_log << pi << endl;
+ }
- void HistoryLog::remove( const PoolItem & pi )
- {
- const Package::constPtr p = asKind<Package>(pi.resolvable());
- if (!p)
- return;
- _log
- << timestamp() // 1 timestamp
- << _sep << HistoryActionID::REMOVE.asString(true) // 2 action
- << _sep << p->name() // 3 name
- << _sep << p->edition() // 4 evr
- << _sep << p->arch(); // 5 arch
+ void HistoryLog::remove( const PoolItem & pi )
+ {
+ const Package::constPtr p = asKind<Package>(pi.resolvable());
+ if (!p)
+ return;
+
+ _log
+ << timestamp() // 1 timestamp
+ << _sep << HistoryActionID::REMOVE.asString(true) // 2 action
+ << _sep << p->name() // 3 name
+ << _sep << p->edition() // 4 evr
+ << _sep << p->arch(); // 5 arch
+
+ if (pi.status().isByUser())
+ _log << _sep << userAtHostname(); // 6 reqested by
+ //else if (pi.status().isByApplHigh() || pi.status().isByApplLow())
+ // _log << _sep << "appl";
+ else
+ _log << _sep;
+
+ // we don't have checksum in rpm db
+ // << _sep << p->checksum().checksum(); // x checksum
+
+ _log << endl;
+
+ //_log << pi << endl;
+ }
- if (pi.status().isByUser())
- _log << _sep << userAtHostname(); // 6 reqested by
- //else if (pi.status().isByApplHigh() || pi.status().isByApplLow())
- // _log << _sep << "appl";
- else
- _log << _sep;
+ /////////////////////////////////////////////////////////////////////////
- // we don't have checksum in rpm db
- // << _sep << p->checksum().checksum(); // x checksum
+ void HistoryLog::addRepository(const RepoInfo & repo)
+ {
+ _log
+ << timestamp() // 1 timestamp
+ << _sep << HistoryActionID::REPO_ADD.asString(true) // 2 action
+ << _sep << repo.alias() // 3 alias
+ // what about the rest of the URLs??
+ << _sep << *repo.baseUrlsBegin() // 4 primary URL
+ << endl;
+ }
- _log << endl;
- //_log << pi << endl;
- }
+ void HistoryLog::removeRepository(const RepoInfo & repo)
+ {
+ _log
+ << timestamp() // 1 timestamp
+ << _sep << HistoryActionID::REPO_REMOVE.asString(true) // 2 action
+ << _sep << repo.alias() // 3 alias
+ << endl;
+ }
- /////////////////////////////////////////////////////////////////////////
- void HistoryLog::addRepository(const RepoInfo & repo)
+ void HistoryLog::modifyRepository(
+ const RepoInfo & oldrepo, const RepoInfo & newrepo)
+ {
+ if (oldrepo.alias() != newrepo.alias())
{
_log
- << timestamp() // 1 timestamp
- << _sep << HistoryActionID::REPO_ADD.asString(true) // 2 action
- << _sep << repo.alias() // 3 alias
- // what about the rest of the URLs??
- << _sep << *repo.baseUrlsBegin() // 4 primary URL
- << endl;
+ << timestamp() // 1 timestamp
+ << _sep << HistoryActionID::REPO_CHANGE_ALIAS.asString(true) // 2 action
+ << _sep << oldrepo.alias() // 3 old alias
+ << _sep << newrepo.alias(); // 4 new alias
}
-
-
- void HistoryLog::removeRepository(const RepoInfo & repo)
+
+ if (*oldrepo.baseUrlsBegin() != *newrepo.baseUrlsBegin())
{
_log
- << timestamp() // 1 timestamp
- << _sep << HistoryActionID::REPO_REMOVE.asString(true) // 2 action
- << _sep << repo.alias() // 3 alias
- << endl;
- }
-
-
- void HistoryLog::modifyRepository(
- const RepoInfo & oldrepo, const RepoInfo & newrepo)
- {
- if (oldrepo.alias() != newrepo.alias())
- {
- _log
- << timestamp() // 1 timestamp
- << _sep << HistoryActionID::REPO_CHANGE_ALIAS.asString(true) // 2 action
- << _sep << oldrepo.alias() // 3 old alias
- << _sep << newrepo.alias(); // 4 new alias
- }
-
- if (*oldrepo.baseUrlsBegin() != *newrepo.baseUrlsBegin())
- {
- _log
- << timestamp() // 1 timestamp
- << _sep << HistoryActionID::REPO_CHANGE_URL.asString(true) // 2 action
- << _sep << oldrepo.alias() // 3 old url
- << _sep << newrepo.alias(); // 4 new url
- }
+ << timestamp() // 1 timestamp
+ << _sep << HistoryActionID::REPO_CHANGE_URL.asString(true) // 2 action
+ << _sep << oldrepo.alias() // 3 old url
+ << _sep << newrepo.alias(); // 4 new url
}
+ }
- ///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
} // namespace zypp
class PoolItem;
class RepoInfo;
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : HistoryLog
+ //
+ /**
+ * Enumeration of known history actions.
+ *
+ * \ingroup g_EnumerationClass
+ */
struct HistoryActionID
{
static const HistoryActionID NONE;
/** \relates HistoryActionID */
std::ostream & operator << (std::ostream & str, const HistoryActionID & id);
-
- ///////////////////////////////////////////////////////////////////
- //
- // CLASS NAME : HistoryLog
+ ///////////////////////////////////////////////////////////////////
+
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : HistoryLog
+ /**
+ * Simple wrapper for progress log. Refcnt, filename and corresponding
+ * ofstream are static members. Logfile constructor raises, destructor
+ * lowers refcounter. On refcounter changing from 0->1, file is opened.
+ * Changing from 1->0 the file is closed. Thus Logfile objects should be
+ * local to those functions, writing the log, and must not be stored
+ * permanently.
+ *
+ * Usage:
+ * <code>
+ * some method ()
+ * {
+ * PoolItem pi;
+ * ...
+ * HistoryLog().install(pi);
+ * ...
+ * HistoryLog().comment(someMessage);
+ * }
+ * </code>
+ *
+ * \note Take care to set proper target root dir if needed. Either pass
+ * it via the constructor, or set it via setRoot(Pathname) method.
+ * The default location of the file is determined by
+ * \ref ZConfig::historyLogPath() which defaults to
+ * /var/log/zypp/history.
+ *
+ * \see http://en.opensuse.org/Libzypp/Package_History
+ */
+ class HistoryLog
+ {
+ HistoryLog( const HistoryLog & );
+ HistoryLog & operator=( const HistoryLog & );
+ private:
+ static std::ofstream _log;
+ static unsigned _refcnt;
+ static Pathname _fname;
+ static const char _sep;
+
+ static void openLog();
+ static void closeLog();
+ static void refUp();
+ static void refDown();
+
+ public:
/**
- * Simple wrapper for progress log. Refcnt, filename and corresponding
- * ofstream are static members. Logfile constructor raises, destructor
- * lowers refcounter. On refcounter changing from 0->1, file is opened.
- * Changing from 1->0 the file is closed. Thus Logfile objects should be
- * local to those functions, writing the log, and must not be stored
- * permanently.
+ * Constructor with an optional root directory.
*
- * Usage:
- * <code>
- * some method ()
- * {
- * PoolItem pi;
- * ...
- * HistoryLog().install(pi);
- * ...
- * HistoryLog().comment(someMessage);
- * }
- * </code>
+ * \param rootdir actual target root directory
+ */
+ HistoryLog( const Pathname & rootdir = Pathname() );
+ ~HistoryLog()
+ { refDown(); }
+
+ /**
+ * Set new root directory to the default history log file path.
+ *
+ * This path will be prepended to the default log file path. This should
+ * be done where there is a potential that the target root has changed.
*
- * \note Take care to set proper target root dir if needed. Either pass
- * it via the constructor, or set it via setRoot(Pathname) method.
- * The default location of the file is determined by
- * \ref ZConfig::historyLogPath() which defaults to
- * /var/log/zypp/history.
+ * \param root new root directory.
*/
- class HistoryLog
- {
- HistoryLog( const HistoryLog & );
- HistoryLog & operator=( const HistoryLog & );
- private:
- static std::ofstream _log;
- static unsigned _refcnt;
- static Pathname _fname;
- static const char _sep;
-
- static void openLog();
- static void closeLog();
- static void refUp();
- static void refDown();
-
- public:
- HistoryLog( const Pathname & rootdir = Pathname() );
- ~HistoryLog()
- { refDown(); }
-
- static void setRoot( const Pathname & root );
- static const Pathname & fname();
-
- void comment( const std::string & comment, bool timestamp = false );
- void install( const PoolItem & pi );
- void remove( const PoolItem & pi );
-
- void addRepository( const RepoInfo & repo );
- void removeRepository( const RepoInfo & repo );
- void modifyRepository( const RepoInfo & oldrepo, const RepoInfo & newrepo );
- };
- ///////////////////////////////////////////////////////////////////
+ static void setRoot( const Pathname & root );
+
+ /**
+ * Get the current log file path.
+ */
+ static const Pathname & fname();
+
+ /**
+ * Log a comment (even multiline).
+ *
+ * \param comment the comment
+ * \param timestamp whether to include a timestamp at the start of the comment
+ */
+ void comment( const std::string & comment, bool timestamp = false );
+
+ /**
+ * Log installation (or update) of a package.
+ */
+ void install( const PoolItem & pi );
+
+ /**
+ * Log removal of a package
+ */
+ void remove( const PoolItem & pi );
+
+ /**
+ * Log a newly added repository.
+ *
+ * \param repo info about the added repository
+ */
+ void addRepository( const RepoInfo & repo );
+
+ /**
+ * Log recently removed repository.
+ *
+ * \param repo info about the removed repository
+ */
+ void removeRepository( const RepoInfo & repo );
+
+ /**
+ * Log certain modifications to a repository.
+ *
+ * \param oldrepo info about the old repository
+ * \param newrepo info about the new repository
+ */
+ void modifyRepository( const RepoInfo & oldrepo, const RepoInfo & newrepo );
+ };
+ ///////////////////////////////////////////////////////////////////
} // namespace zypp