Author: switt
Date: Sat Nov 6 01:20:42 2010
New Revision: 36148
URL: http://www.lyx.org/trac/changeset/36148
Log:
CVS implementation for buffer-info vcs-author, cvs-date and cvs-time
Modified:
lyx-devel/trunk/src/VCBackend.cpp
lyx-devel/trunk/src/VCBackend.h
Modified: lyx-devel/trunk/src/VCBackend.cpp
==============================================================================
--- lyx-devel/trunk/src/VCBackend.cpp Sat Nov 6 01:04:21 2010 (r36147)
+++ lyx-devel/trunk/src/VCBackend.cpp Sat Nov 6 01:20:42 2010 (r36148)
@@ -366,6 +366,7 @@
{
master_ = m;
file_ = f;
+ have_rev_info_ = false;
scanMaster();
}
@@ -478,6 +479,23 @@
}
+int CVS::doVCCommandWithOutput(string const & cmd, FileName const & path,
+ FileName const & output, bool reportError)
+{
+ string redirection = output.empty() ? "" : " > " +
quoteName(output.toFilesystemEncoding());
+ return doVCCommand(cmd + redirection, path, reportError);
+}
+
+
+int CVS::doVCCommandCallWithOutput(std::string const & cmd,
+ support::FileName const & path,
+ support::FileName const & output)
+{
+ string redirection = output.empty() ? "" : " > " +
quoteName(output.toFilesystemEncoding());
+ return doVCCommandCall(cmd + redirection, path);
+}
+
+
CVS::CvsStatus CVS::getStatus()
{
FileName tmpf = FileName::tempName("lyxvcout");
@@ -486,9 +504,8 @@
return StatusError;
}
- if (doVCCommand("cvs status " + getTarget(File)
- + " > " + quoteName(tmpf.toFilesystemEncoding()),
- FileName(owner_->filePath()))) {
+ if (doVCCommandCallWithOutput("cvs status " + getTarget(File),
+ FileName(owner_->filePath()), tmpf)) {
tmpf.removeFile();
return StatusError;
}
@@ -517,6 +534,51 @@
return status;
}
+void CVS::getRevisionInfo()
+{
+ if (have_rev_info_)
+ return;
+ have_rev_info_ = true;
+ FileName tmpf = FileName::tempName("lyxvcout");
+ if (tmpf.empty()) {
+ LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf);
+ return;
+ }
+
+ int rc = doVCCommandCallWithOutput("cvs log -r" + version_
+ + " " + getTarget(File),
+ FileName(owner_->filePath()), tmpf);
+ if (rc) {
+ tmpf.removeFile();
+ LYXERR(Debug::LYXVC, "cvs log failed with exit code " << rc);
+ return;
+ }
+
+ ifstream ifs(tmpf.toFilesystemEncoding().c_str());
+ static regex const reg("date: (.*) (.*) (.*); author: (.*); state:
(.*);(.*)");
+
+ while (ifs) {
+ string line;
+ getline(ifs, line);
+ LYXERR(Debug::LYXVC, line << "\n");
+ if (prefixIs(line, "date:")) {
+ smatch sm;
+ regex_match(line, sm, reg);
+ //sm[0]; // whole matched string
+ rev_date_cache_ = sm[1];
+ rev_time_cache_ = sm[2];
+ //sm[3]; // GMT offset
+ rev_author_cache_ = sm[4];
+ break;
+ }
+ }
+ tmpf.removeFile();
+ if (rev_author_cache_.empty())
+ LYXERR(Debug::LYXVC,
+ "Could not retrieve revision info for " << version_ <<
+ " of " << getTarget(File));
+}
+
void CVS::registrer(string const & msg)
{
@@ -528,9 +590,8 @@
void CVS::getDiff(OperationMode opmode, FileName const & tmpf)
{
- doVCCommand("cvs diff " + getTarget(opmode)
- + " > " + quoteName(tmpf.toFilesystemEncoding()),
- FileName(owner_->filePath()), false);
+ doVCCommandWithOutput("cvs diff " + getTarget(opmode),
+ FileName(owner_->filePath()), tmpf, false);
}
@@ -552,12 +613,9 @@
int CVS::update(OperationMode opmode, FileName const & tmpf)
{
- string const redirection = tmpf.empty() ? ""
- : " > " + quoteName(tmpf.toFilesystemEncoding());
-
- return doVCCommand("cvs -q update "
- + getTarget(opmode) + redirection,
- FileName(owner_->filePath()));
+ return doVCCommandWithOutput("cvs -q update "
+ + getTarget(opmode),
+ FileName(owner_->filePath()), tmpf, false);
}
@@ -650,12 +708,14 @@
int rc = update(File, tmpf);
string log;
string const res = scanLogFile(tmpf, log);
- if (!res.empty())
+ if (!res.empty()) {
frontend::Alert::error(_("Revision control error."),
bformat(_("Error when updating from repository.\n"
"You have to manually resolve the conflicts
NOW!\n'%1$s'.\n\n"
"After pressing OK, LyX will try to reopen the
resolved document."),
from_local8bit(res)));
+ rc = 0;
+ }
tmpf.erase();
return rc ? string() : log.empty() ? "CVS: Proceeded" : "CVS: " + log;
@@ -704,10 +764,23 @@
int rc = update(Directory, tmpf);
res += "Update log:\n" + tmpf.fileContents("UTF-8");
+ LYXERR(Debug::LYXVC, res);
+
+ string log;
+ string sres = scanLogFile(tmpf, log);
+ if (!sres.empty()) {
+ docstring const file = owner_->fileName().displayName(20);
+ frontend::Alert::error(_("Revision control error."),
+ bformat(_("Error when updating document %1$s from
repository.\n"
+ "You have to manually resolve the
conflicts NOW!\n'%2$s'.\n\n"
+ "After pressing OK, LyX will try to
reopen the resolved document."),
+ file, from_local8bit(sres)));
+ rc = 0;
+ }
+
tmpf.removeFile();
- LYXERR(Debug::LYXVC, res);
- return rc ? string() : "CVS: Proceeded" ;
+ return rc ? string() : log.empty() ? "CVS: Proceeded" : "CVS: " + log;
}
@@ -793,9 +866,9 @@
void CVS::getLog(FileName const & tmpf)
{
- doVCCommand("cvs log " + getTarget(File)
- + " > " + quoteName(tmpf.toFilesystemEncoding()),
- FileName(owner_->filePath()));
+ doVCCommandWithOutput("cvs log " + getTarget(File),
+ FileName(owner_->filePath()),
+ tmpf);
}
@@ -807,8 +880,20 @@
string CVS::revisionInfo(LyXVC::RevisionInfo const info)
{
- if (info == LyXVC::File)
- return version_;
+ if (!version_.empty()) {
+ getRevisionInfo();
+ switch (info) {
+ case LyXVC::File:
+ return version_;
+ case LyXVC::Author:
+ return rev_author_cache_;
+ case LyXVC::Date:
+ return rev_date_cache_;
+ case LyXVC::Time:
+ return rev_time_cache_;
+ default: ;
+ }
+ }
return string();
}
Modified: lyx-devel/trunk/src/VCBackend.h
==============================================================================
--- lyx-devel/trunk/src/VCBackend.h Sat Nov 6 01:04:21 2010 (r36147)
+++ lyx-devel/trunk/src/VCBackend.h Sat Nov 6 01:20:42 2010 (r36148)
@@ -261,6 +261,24 @@
// revision number from scanMaster
std::string version_;
+ /**
+ * doVCCommandWithOutput
+ * - call out to the version control utility
+ * - it is able to collect output in a file
+ * @param cmd the command to execute
+ * @param path the path from which to execute
+ * @param output the path where to store output
+ * @param reportError display of low level error message dialog
+ * @return exit status
+ */
+ int doVCCommandWithOutput(std::string const & cmd,
+ support::FileName const & path,
+ support::FileName const & output,
+ bool reportError = true);
+ static int doVCCommandCallWithOutput(std::string const & cmd,
+ support::FileName const & path,
+ support::FileName const & output);
+
/// return the quoted pathname if Directory or filename if File
virtual std::string const getTarget(OperationMode opmode) const;
/// collect the diff of file or directory against repository
@@ -280,6 +298,15 @@
virtual CvsStatus getStatus();
/// convert enum to string
virtual docstring toString(CvsStatus status) const;
+
+ /// cache the info values of current file revision
+ /// author, date and time of commit
+ std::string rev_author_cache_;
+ std::string rev_date_cache_;
+ std::string rev_time_cache_;
+ /// fills the cache values, returns true if successfull.
+ void getRevisionInfo();
+ bool have_rev_info_;
};