Bug 135795 - Subversion 1.4 support for catalog manager.
Summary: Subversion 1.4 support for catalog manager.
Status: RESOLVED FIXED
Alias: None
Product: kbabel
Classification: Miscellaneous
Component: CatalogManager (show other bugs)
Version: unspecified
Platform: Mandriva RPMs Linux
: NOR normal (vote)
Target Milestone: ---
Assignee: Stanislav Visnovsky
URL:
Keywords:
: 137310 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-10-17 11:03 UTC by Franklin Weng
Modified: 2006-12-19 09:37 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Franklin Weng 2006-10-17 11:03:54 UTC
Version:            (using KDE KDE 3.5.5)
Installed from:    Mandriva RPMs

Recently when I used catalogmanager to do my KDE-API translations, I found that the CVS/SVN status message became "Error in Working Copy".
Every file in SVN had such message.

So I run catalogmanager from command line, which gave me the following messages:

############### catalog manager error messages ################
kbabel: Unknown key: X-Generator
catalogmanager: Cannot parse .svn/entries file for /home/franklin/kde/translate/stable/zh_TW/messages/kdegames/kreversi.po
catalogmanager: Line: 1 Column: 1 Error: error occurred while parsing element

###############################################################

It reported error and line 1 and column 1!
Then I found that in the kbabel/catalogmanager/libsvn/svnhandler.cpp line 144 (in svn branches/KDE/3.5/, revision 596317, just checked out), when it called doc.setContent() it got errors, because all the .svn/entries files' format were different!

The .svn/entries file was a XML document before, and its format is like:

################### .svn/entries file before ################
<?xml version="1.0" encoding="utf-8"?>
<wc-entries
   xmlns="svn:">
<entry
   committed-rev="595943"
   name=""
   committed-date="2006-10-16T08:28:37.321233Z"
   url="https://shyue@svn.kde.org/home/kde/branches/stable/l10n/zh_TW"
   last-author="shyue"
   kind="dir"
   uuid="283d02a7-25f6-0310-bc7c-ecb5cbfe19da"
   prop-time="2006-06-19T02:58:43.000000Z"
   revision="596213"/>
<entry
   name="messages"
   kind="dir"/>
<entry
   name="docs"
   kind="dir"/>
<entry
   name="docmessages"
   kind="dir"/>
</wc-entries>
##########################################################

However I found that now the .svn/entries file's format becomes:

################ .svn/entries today ###################
8

dir
596317
svn://anonsvn.kde.org/home/kde/branches/KDE/3.5/kdesdk/kbabel/catalogmanager/lib
svn
svn://anonsvn.kde.org/home/kde



2006-01-25T11:22:54.803909Z
502231
goutte
has-props

svn:special svn:externals svn:needs-lock

########################################################

So the doc.setContent() reports errors.

Why is the .svn/entries format different?  Is that my own problem, or the catalogmanager should be fixed to parse the new entries file format?
Comment 1 Bram Schoenmakers 2006-10-17 13:50:18 UTC
I assume you're using Subversion 1.4 then, since in SVN 1.4 the work copy format has been changed. Catalogmanager is developed against Subversion 1.3 and needs to be updated to handle this new work copy format.

I changed the summary field of this bug report.
Comment 2 Hasso Tepper 2006-12-15 21:50:10 UTC
I made quick patch to solve the problem. See http://lists.kde.org/?l=kde-i18n-doc&m=116621541906423&w=2 for details.
Comment 3 Hasso Tepper 2006-12-18 14:15:27 UTC
*** Bug 137310 has been marked as a duplicate of this bug. ***
Comment 4 Hasso Tepper 2006-12-19 09:37:12 UTC
SVN commit 614865 by hasso:

As I got no objections and some users even tested it (I really appreciate
this), I hope I'll not be killed because of committing this - subversion
1.4 support for catalogmanager.

BUG:135795
CCMAIL:kde-i18n-doc@kde.org
CCMAIL:kbabel@kde.org
CCMAIL:kde-et@linux.ee



 M  +104 -5    svnhandler.cpp  
 M  +23 -0     svnhandler.h  


--- branches/KDE/3.5/kdesdk/kbabel/catalogmanager/libsvn/svnhandler.cpp #614864:614865
@@ -50,10 +50,10 @@
 #include <kmessagebox.h>
 #include <ktempfile.h>
 #include <kdebug.h>
+#include <kprocess.h>
 // project specific include files
 #include "svnhandler.h"
 
-
 SVNHandler::SVNHandler( const QString& poBaseDir, const QString& potBaseDir )
 {
   setPOBaseDir( poBaseDir );
@@ -126,19 +126,83 @@
 
   QFileInfo info( fn );
 
-  // check if '.svn/entries' exists and can be read
+  // check if '.svn/entries' exists.
   QFile entries( info.dir( true ).path( ) + "/.svn/entries" );
 
   if ( !entries.exists() )
     return NOT_IN_SVN;
-  
-  if ( !entries.open( IO_ReadOnly ) )
-    return ERROR_IN_WC;  // we already know that it is a repository
 
+  KProcess proc;
+  SVNOutputCollector out( &proc );
+
+  proc << "svn" << "status" << "-v" << "--xml" << info.absFilePath();
+
+  if( !proc.start( KProcess::Block, KProcess::Stdout ) )
+    return ERROR_IN_WC;
+
   QDomDocument doc;
   QString errorMsg;
   int errorLine, errorCol;
+  QDomNodeList nodelist;
+  QDomNode node;
+  QDomElement entry, wcStatus;
 
+  // Parse the output.
+  if ( !doc.setContent( out.output(), &errorMsg, &errorLine, &errorCol ) ) {
+    kdDebug(8109) << "Cannot parse \"svn status -v --xml\" output for"
+        << filename << endl << "Line: " << errorLine << " Column: "
+        << errorCol << " Error: " << errorMsg << endl;
+    goto no_status_xml;
+  }
+
+  // There should be only one "entry" element. If it doesn't exist, path
+  // isn't repo path at all.
+  nodelist = doc.elementsByTagName("entry");
+  if (nodelist.count() < 1)
+    return NOT_IN_SVN;
+
+  entry = nodelist.item(0).toElement();
+
+  // Shouldn't fail, but just in case there is some weird error.
+  if ( entry.attributeNode("path").value() != info.absFilePath() )
+    return ERROR_IN_WC;
+
+  for ( node = entry.firstChild(); !node.isNull(); node = node.nextSibling() ) {
+    if ( !node.isElement() )
+      continue;
+    if (node.toElement().tagName() == "wc-status")
+      break;
+  }
+
+  if ( node.isNull() )
+    return ERROR_IN_WC;
+
+  wcStatus = node.toElement();
+
+  if ( wcStatus.attributeNode("item").value() == "normal" )
+    return UP_TO_DATE;
+  if ( wcStatus.attributeNode("item").value() == "modified" )
+    return LOCALLY_MODIFIED;
+  if ( wcStatus.attributeNode("item").value() == "conflicted" )
+    return CONFLICT;
+  if ( wcStatus.attributeNode("item").value() == "unversioned" )
+    return NOT_IN_SVN;
+  // TODO Ignored entry should have separate return value probably.
+  if ( wcStatus.attributeNode("item").value() == "ignored" )
+    return NOT_IN_SVN;
+  if ( wcStatus.attributeNode("item").value() == "added" )
+    return LOCALLY_ADDED;
+  if ( wcStatus.attributeNode("item").value() == "deleted" )
+    return LOCALLY_REMOVED;
+  // TODO What to do with "missing", "incomplete", "replaced", "merged",
+  // "obstructed", "external"? Can these appear at all in our case?
+
+  return ERROR_IN_WC;
+
+no_status_xml:
+  if ( !entries.open( IO_ReadOnly ) )
+    return ERROR_IN_WC;  // we already know that it is a repository
+
   // Parse the entries file
   if ( !doc.setContent( &entries, &errorMsg, &errorLine, &errorCol ) ) {
     kdDebug() << "Cannot parse .svn/entries file for " << filename << endl
@@ -439,7 +503,42 @@
   return status == LOCALLY_MODIFIED || status == NOT_IN_SVN;
 }
 
+SVNOutputCollector::SVNOutputCollector( KProcess* p )
+  : m_process(0)
+{
+  setProcess( p );
+}
 
+void SVNOutputCollector::setProcess( KProcess* p )
+{
+  if( m_process )
+    m_process->disconnect( this );
+
+  m_process = p;
+  if( p ) {
+    connect( p, SIGNAL(receivedStdout(KProcess*, char*, int)),
+             this, SLOT(slotGatherStdout(KProcess*, char*, int)) );
+    connect( p, SIGNAL(receivedStderr(KProcess*, char*, int)),
+             this, SLOT(slotGatherStderr(KProcess*, char*, int)) );
+  }
+
+  m_gatheredOutput.truncate( 0 );
+  m_stderrOutput.truncate( 0 );
+  m_stdoutOutput.truncate( 0 );
+}
+
+void SVNOutputCollector::slotGatherStderr( KProcess*, char* data, int len )
+{
+  m_gatheredOutput.append( QString::fromLocal8Bit( data, len ) );
+  m_stderrOutput.append( QString::fromLocal8Bit( data, len ) );
+}
+
+void SVNOutputCollector::slotGatherStdout( KProcess*, char* data, int len )
+{
+  m_gatheredOutput.append( QString::fromLocal8Bit( data, len ) );
+  m_stdoutOutput.append( QString::fromLocal8Bit( data, len ) );
+}
+
 #include "svnhandler.moc"
 
 // kate: space-indent on; indent-width 2; replace-tabs on;
--- branches/KDE/3.5/kdesdk/kbabel/catalogmanager/libsvn/svnhandler.h #614864:614865
@@ -112,4 +112,27 @@
     QMap<QString,QString> map;
 };
 
+class SVNOutputCollector: public QObject
+{
+  Q_OBJECT
+
+ public:
+  SVNOutputCollector( KProcess* );
+  void setProcess( KProcess* );
+
+  const QString& output() const { return m_gatheredOutput; }
+  const QString& stderr() const { return m_stderrOutput; }
+  const QString& stdout() const { return m_stdoutOutput; }
+
+ private slots:
+  void slotGatherStderr( KProcess*, char*, int );
+  void slotGatherStdout( KProcess*, char*, int );
+
+ private:
+  QString m_gatheredOutput;
+  QString m_stderrOutput;
+  QString m_stdoutOutput;
+  KProcess* m_process;
+};
+
 #endif // SVNHANDLER_H