mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-27 22:03:39 -06:00
SVN Library -- first release + test app
git-svn-id: svn://ultimatepp.org/upp/trunk@299 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
2bf2eade17
commit
ad3ced97b7
7 changed files with 1492 additions and 0 deletions
869
bazaar/SvnLib/SvnLib.cpp
Normal file
869
bazaar/SvnLib/SvnLib.cpp
Normal file
|
|
@ -0,0 +1,869 @@
|
|||
#include <SysExec/SysExec.h>
|
||||
|
||||
#include "SvnLib.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Human-readable error messages
|
||||
const char *Svn::ErrorMessages[] =
|
||||
{
|
||||
"Svn : Ok",
|
||||
"Svn : Unknown Error",
|
||||
"Svn : Svn application not found",
|
||||
"Svn : Not a SVN repository",
|
||||
"Svn : Not connected to a repository",
|
||||
"Svn : File not found",
|
||||
"Svn : Path not found",
|
||||
"Svn : File exists",
|
||||
"Svn : Directory exists",
|
||||
"Svn : Path exists",
|
||||
"Svn : Directory is not empty",
|
||||
"Svn : Path is not a directory",
|
||||
"Svn : Can't remove directory. Read only?",
|
||||
"Svn : Can't write do directory. Read only?"
|
||||
"Svn : Path is not in active repository",
|
||||
"Svn : Invalid repository URL",
|
||||
"Svn : Bad XML found",
|
||||
"Svn : Bad login. Check username/password"
|
||||
|
||||
} ; // END Svn::ErrorMessages[]
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Human-readable status strings
|
||||
const char *Svn::StatusStrings[] =
|
||||
{
|
||||
"unknown",
|
||||
"added",
|
||||
"missing",
|
||||
"incomplete",
|
||||
"replaced",
|
||||
"modified",
|
||||
"merged",
|
||||
"conflicted",
|
||||
"obstructed",
|
||||
"ignored",
|
||||
"external",
|
||||
"unversioned"
|
||||
|
||||
}; // END Svn::StatusStrings
|
||||
|
||||
const int Svn::NumStatus = sizeof(StatusStrings) / sizeof(char *);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// from status string, gets status
|
||||
Svn::ItemStatus Svn::String2Status(String const &s)
|
||||
{
|
||||
for(int i = 0; i < NumStatus; i++)
|
||||
if(s == StatusStrings[i])
|
||||
return (ItemStatus)i;
|
||||
return unknown;
|
||||
|
||||
} // END Svn::String2Status()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// from status, gets human-readable string
|
||||
String Svn::Status2String(ItemStatus s)
|
||||
{
|
||||
if(s >= unknown && s <= unversioned)
|
||||
return StatusStrings[s];
|
||||
else
|
||||
return "BAD STATUS";
|
||||
|
||||
} // END Svn::Status2String()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// executes svn, passing cmdline as argument, gathering output in Output
|
||||
// in xml format (where available) if xml is true
|
||||
Svn::Errors Svn::ExecSvn(String const &SvnArgs, String &OutStr, String &ErrStr, bool xml)
|
||||
{
|
||||
// adjust args if we wants xml output
|
||||
String args = (xml ? "--xml " : "") + SvnArgs;
|
||||
|
||||
// adjust environment to get output in en_IN locale
|
||||
// otherwise it becomes difficult to understand command responses....
|
||||
VectorMap<String, String> env;
|
||||
env.Add("LC_MESSAGES", "en_IN");
|
||||
|
||||
// executes svn command
|
||||
bool result = SysExec("svn", args, env, OutStr, ErrStr);
|
||||
FLastCommandOutput = OutStr;
|
||||
FLastCommandError = ErrStr;
|
||||
|
||||
// if all ok, returns ok
|
||||
if(result && ErrStr == "")
|
||||
return SetError(Svn::Ok);
|
||||
|
||||
// catches spawning errors
|
||||
if(ErrStr.Find("Couldn't fork") >=0 || ErrStr.Find("Error spawning process") >=0)
|
||||
return SetError(NoSvnApp);
|
||||
|
||||
// catches svn command errors
|
||||
|
||||
// checks for ill-formed URLs
|
||||
if(ErrStr.Find("does not appear to be a URL") >= 0)
|
||||
return SetError(Svn::NotAnURL);
|
||||
|
||||
// ckecks if could write to folder
|
||||
if(ErrStr.Find("Can't create directory") >= 0)
|
||||
return SetError(Svn::CantWriteDirectory);
|
||||
|
||||
// checks wether we tried to operate on a non-svn folder
|
||||
if (ErrStr.Find("is not a working copy") >= 0)
|
||||
return SetError(Svn::NotARepo);
|
||||
|
||||
return SetError(Svn::UnknownError);
|
||||
|
||||
} // END Svn::ExecSvn()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// builds username/password string
|
||||
String Svn::BuildUserPassword(void)
|
||||
{
|
||||
if(FAnonymous)
|
||||
return " ";
|
||||
else
|
||||
return " --username " + FUserName + " --password " + FPassword + " ";
|
||||
|
||||
} // END Svn::BuildUserPassword()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// builds revision string
|
||||
String Svn::BuildRevision(String const &Revision)
|
||||
{
|
||||
if(Revision != "")
|
||||
return " --revision " + Revision + " ";
|
||||
else
|
||||
return " ";
|
||||
|
||||
} // END Svn::BuildRevision()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// checks wether a string is a remote URL or a local path
|
||||
bool Svn::IsUrl(String const &path)
|
||||
{
|
||||
if(
|
||||
path.Find("http://") >= 0 ||
|
||||
path.Find("https://") >= 0 ||
|
||||
path.Find("svn://") >= 0 ||
|
||||
path.Find("file://") >= 0
|
||||
)
|
||||
return true;
|
||||
return false;
|
||||
|
||||
} // END Svn::IsUrl()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// checks whether a path is inside local repository
|
||||
bool Svn::IsLocalPath(String const &path)
|
||||
{
|
||||
return (path.Find(FLocalPath) == 0);
|
||||
|
||||
} // END Svn::IsLocalPath()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// checks whether a path is inside remote repository
|
||||
bool Svn::IsRemotePath(String const &path)
|
||||
{
|
||||
return (path.Find(FRepositoryRoot) == 0);
|
||||
|
||||
} // END Svn::IsRemotePath()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// checks whether a path is inside repository, remote or local side
|
||||
bool Svn::IsRepositoryPath(String const &path)
|
||||
{
|
||||
return IsLocalPath(path) || IsRemotePath(path);
|
||||
|
||||
} // END Svn::IsRepositoryPath()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// initializer... used by constructor and on disconnection
|
||||
void Svn::Init(void)
|
||||
{
|
||||
// log-in stuffs
|
||||
FUserName = "";
|
||||
FPassword = "";
|
||||
FAnonymous = true;
|
||||
|
||||
// svn repository info stuffs
|
||||
FLocalPath = "";
|
||||
FRepositoryRoot = "";
|
||||
FRepositoryUUID = "";
|
||||
FCheckedRevisionAuthor = "";
|
||||
FCheckedRevision = 0;
|
||||
FCheckedRevisionDate = "";
|
||||
FHeadRevisionAuthor = "";
|
||||
FHeadRevision = 0;
|
||||
FHeadRevisionDate = "";
|
||||
|
||||
FLastError = Ok;
|
||||
FConnected = false;
|
||||
|
||||
FLastCommandOutput = "";
|
||||
FLastCommandError = "";
|
||||
|
||||
} // END Svn::Init()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor class Svn
|
||||
Svn::Svn()
|
||||
{
|
||||
Init();
|
||||
|
||||
} // END constructor class Svn
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// destructor class Svn
|
||||
Svn::~Svn()
|
||||
{
|
||||
|
||||
} // END destructor class Svn
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// checks wether a path is a svn
|
||||
bool Svn::IsSvn(String const &LocalPath)
|
||||
{
|
||||
String Out, Err;
|
||||
return( ExecSvn("info " + LocalPath, Out, Err) == Svn::Ok);
|
||||
|
||||
} // END Svn::IsSvn()
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// parses xml output of 'svn info' command
|
||||
Svn::Errors Svn::ParseInfo(String const &str, EntryInfo &info)
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlParser p(str);
|
||||
while (!p.IsTag() &&!p.End())
|
||||
p.Skip();
|
||||
p.PassTag("info");
|
||||
while (!p.End())
|
||||
{
|
||||
if (p.Tag("entry"))
|
||||
{
|
||||
info.kind = p["kind"];
|
||||
info.revision = atoi(p["revision"]);
|
||||
info.path = p["path"];
|
||||
while (!p.End())
|
||||
{
|
||||
if (p.Tag("url"))
|
||||
{
|
||||
info.url = p.ReadText();
|
||||
p.SkipEnd();
|
||||
}
|
||||
else if(p.Tag("repository"))
|
||||
{
|
||||
while(!p.End())
|
||||
{
|
||||
if(p.Tag("root"))
|
||||
{
|
||||
info.repositoryRoot = p.ReadText();
|
||||
p.SkipEnd();
|
||||
}
|
||||
else if(p.Tag("uuid"))
|
||||
{
|
||||
info.repositoryUUID = p.ReadText();
|
||||
p.SkipEnd();
|
||||
}
|
||||
else
|
||||
p.Skip();
|
||||
}
|
||||
}
|
||||
else if(p.Tag("commit"))
|
||||
{
|
||||
while(!p.End())
|
||||
{
|
||||
if(p.Tag("revision"))
|
||||
{
|
||||
info.commitRevision = atoi(p.ReadText());
|
||||
p.SkipEnd();
|
||||
}
|
||||
else if(p.Tag("author"))
|
||||
{
|
||||
info.commitAuthor = p.ReadText();
|
||||
p.SkipEnd();
|
||||
}
|
||||
else if(p.Tag("date"))
|
||||
{
|
||||
info.commitDate = p.ReadText();
|
||||
p.SkipEnd();
|
||||
}
|
||||
else
|
||||
p.Skip();
|
||||
}
|
||||
}
|
||||
else
|
||||
p.Skip();
|
||||
}
|
||||
}
|
||||
else
|
||||
p.Skip();
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
catch (XmlError)
|
||||
{
|
||||
return BadXml;
|
||||
}
|
||||
|
||||
} // END Svn::ParseInfo()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// parses xml output of 'svn log' command
|
||||
Svn::Errors Svn::ParseLog(String const &str, Array<LogInfo>&infoArray)
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlParser p(str);
|
||||
while (!p.IsTag() &&!p.End())
|
||||
p.Skip();
|
||||
p.PassTag("log");
|
||||
while (!p.End())
|
||||
{
|
||||
if (p.Tag("logentry"))
|
||||
{
|
||||
LogInfo &info = infoArray.Add();
|
||||
info.author = "";
|
||||
info.date = "";
|
||||
info.message = "";
|
||||
info.revision = atoi(p["revision"]);
|
||||
while (!p.End())
|
||||
{
|
||||
if (p.Tag("author"))
|
||||
{
|
||||
info.author = p.ReadText();
|
||||
p.SkipEnd();
|
||||
}
|
||||
else if(p.Tag("date"))
|
||||
{
|
||||
info.date = p.ReadText();
|
||||
p.SkipEnd();
|
||||
}
|
||||
else if(p.Tag("msg"))
|
||||
{
|
||||
info.message = p.ReadText();
|
||||
p.SkipEnd();
|
||||
}
|
||||
else
|
||||
p.Skip();
|
||||
}
|
||||
}
|
||||
else
|
||||
p.Skip();
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
catch (XmlError)
|
||||
{
|
||||
return BadXml;
|
||||
}
|
||||
|
||||
} // END Svn::ParseLog()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// parses xml output of 'svn status' command
|
||||
Svn::Errors Svn::ParseStatus(String const &str, Array<StatusInfo> &infoArray)
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlParser p(str);
|
||||
while (!p.IsTag() &&!p.End())
|
||||
p.Skip();
|
||||
p.PassTag("status");
|
||||
p.PassTag("target");
|
||||
while (!p.End())
|
||||
{
|
||||
if (p.Tag("entry"))
|
||||
{
|
||||
StatusInfo &info = infoArray.Add();
|
||||
info.path = "";
|
||||
info.props = "";
|
||||
info.status = unknown;
|
||||
info.revision = -1;
|
||||
info.commitRevision = -1;
|
||||
info.commitAuthor = "";
|
||||
info.commitDate = "";
|
||||
|
||||
info.path = p["path"];
|
||||
while (!p.End())
|
||||
{
|
||||
if (p.Tag("wc-status"))
|
||||
{
|
||||
info.props = p["props"];
|
||||
info.status = String2Status(p["item"]);
|
||||
info.revision = atoi(p["revision"]);
|
||||
p.SkipEnd();
|
||||
}
|
||||
else if(p.Tag("commit"))
|
||||
{
|
||||
info.commitRevision = atoi(p["revision"]);
|
||||
p.SkipEnd();
|
||||
}
|
||||
else if(p.Tag("author"))
|
||||
{
|
||||
info.commitAuthor = p.ReadText();
|
||||
p.SkipEnd();
|
||||
}
|
||||
else if(p.Tag("date"))
|
||||
{
|
||||
info.commitDate = p.ReadText();
|
||||
p.SkipEnd();
|
||||
}
|
||||
else
|
||||
p.Skip();
|
||||
}
|
||||
}
|
||||
else
|
||||
p.Skip();
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
catch (XmlError)
|
||||
{
|
||||
return BadXml;
|
||||
}
|
||||
|
||||
} // END Svn::ParseStatus()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// sets user authentication
|
||||
void Svn::SetUser(String const &UserName, String const &Password)
|
||||
{
|
||||
FUserName = UserName;
|
||||
FPassword = Password;
|
||||
FAnonymous = false;
|
||||
|
||||
} // END Svn::SetUser()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// sets user authentication
|
||||
void Svn::SetUser(void)
|
||||
{
|
||||
FUserName = "";
|
||||
FPassword = "";
|
||||
FAnonymous = true;
|
||||
|
||||
} // END Svn::SetUser()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// connects to the local copy
|
||||
Svn::Errors Svn::Connect(String const &LocalPath)
|
||||
{
|
||||
Svn::Errors result;
|
||||
String Out, Err;
|
||||
|
||||
// first, checks wether is a svn repo
|
||||
if(!IsSvn(LocalPath))
|
||||
return SetError(Svn::NotARepo);
|
||||
|
||||
// executes 'svn info' command -- gets current checked-in information
|
||||
result = ExecSvn("info " + BuildUserPassword() + LocalPath, Out, Err, true);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
// parses xml info output
|
||||
EntryInfo info;
|
||||
result = ParseInfo(Out, info);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
// stores repository info
|
||||
FLocalPath = LocalPath;
|
||||
FRepositoryRoot = info.repositoryRoot;
|
||||
FRepositoryUUID = info.repositoryUUID;
|
||||
FCheckedRevisionAuthor = info.commitAuthor;
|
||||
FCheckedRevision = info.revision;
|
||||
FCheckedRevisionDate = info.commitDate;
|
||||
|
||||
// executes 'svn info -r HEAD' command -- gets HEAD information
|
||||
result = ExecSvn("info -r HEAD " + BuildUserPassword() + LocalPath, Out, Err, true);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
// parses xml info output
|
||||
result = ParseInfo(Out, info);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
// stores repository info
|
||||
FHeadRevisionAuthor = info.commitAuthor;
|
||||
FHeadRevision = info.revision;
|
||||
FHeadRevisionDate = info.commitDate;
|
||||
|
||||
FConnected = true;
|
||||
FLastError = Ok;
|
||||
|
||||
return SetError(Svn::Ok);
|
||||
|
||||
} // END Svn::Connect()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// disconnects from local copy
|
||||
Svn::Errors Svn::Disconnect(void)
|
||||
{
|
||||
// if not connected, does nothing
|
||||
if(!FConnected)
|
||||
return SetError(Svn::NotConnected);
|
||||
|
||||
// reinitializes
|
||||
Init();
|
||||
|
||||
return Svn::Ok;
|
||||
|
||||
} // END Svn::Disconnect()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// checks out from server
|
||||
Svn::Errors Svn::Checkout(String const &Url, String const &LocalPath, String const &Revision)
|
||||
{
|
||||
String Out, Err;
|
||||
String Path;
|
||||
Svn::Errors result;
|
||||
|
||||
// adjust final path separator
|
||||
Path = LocalPath;
|
||||
if(Path[Path.GetLength()-1] != DIR_SEP)
|
||||
Path << DIR_SEP;
|
||||
|
||||
// fists, looks at localpath; if it does exist, it must be empty
|
||||
if(Upp::DirectoryExists(Path))
|
||||
{
|
||||
// checks if directory is empty
|
||||
Array<FileSystemInfo::FileInfo> fileInfo = StdFileSystemInfo().Find(Path + "*");
|
||||
bool found = false;
|
||||
for(int i = 0; i < fileInfo.GetCount(); i++)
|
||||
{
|
||||
if(fileInfo[i].filename != "." && fileInfo[i].filename != "..")
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
return SetError(DirectoryNotEmpty);
|
||||
|
||||
// removes the path
|
||||
if(!DirectoryDelete(Path))
|
||||
return SetError(CantRemoveDirectory);
|
||||
}
|
||||
|
||||
// well, now we can do the checkout
|
||||
result = ExecSvn("checkout -q --no-auth-cache --non-interactive" + BuildUserPassword() + BuildRevision(Revision) + Url + " " + Path, Out, Err, false);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
// checkout should be done, connect to checked out folder
|
||||
return SetError(Connect(Path));
|
||||
|
||||
} // END Svn::Checkout()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// updates current copy from server
|
||||
Svn::Errors Svn::Update(String const &Revision)
|
||||
{
|
||||
String Out, Err;
|
||||
Svn::Errors result;
|
||||
|
||||
// if not connected, does nothing
|
||||
if(!FConnected)
|
||||
return SetError(Svn::NotConnected);
|
||||
|
||||
// well, now we can do the update
|
||||
result = ExecSvn("update -q --no-auth-cache --non-interactive" + BuildUserPassword() + BuildRevision(Revision) + FLocalPath, Out, Err, false);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
// executes 'svn info' command -- gets current checked-in information
|
||||
result = ExecSvn("info " + BuildUserPassword() + FLocalPath, Out, Err, true);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
// parses xml info output
|
||||
EntryInfo info;
|
||||
result = ParseInfo(Out, info);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
// stores repository info
|
||||
FRepositoryRoot = info.repositoryRoot;
|
||||
FRepositoryUUID = info.repositoryUUID;
|
||||
FCheckedRevisionAuthor = info.commitAuthor;
|
||||
FCheckedRevision = info.revision;
|
||||
FCheckedRevisionDate = info.commitDate;
|
||||
|
||||
return SetError(Svn::Ok);
|
||||
|
||||
} // END Svn::Update()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// commits to server
|
||||
Svn::Errors Svn::Commit(String const &Message)
|
||||
{
|
||||
String Out, Err;
|
||||
Svn::Errors result;
|
||||
|
||||
// if not connected, does nothing
|
||||
if(!FConnected)
|
||||
return SetError(Svn::NotConnected);
|
||||
|
||||
// well, now we can do the commit
|
||||
result = ExecSvn("commit -q --no-auth-cache --non-interactive" + BuildUserPassword() + " -- message " + Message, Out, Err, false);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
return SetError(Svn::Ok);
|
||||
|
||||
} // END Svn::Commit()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// adds file(s) to current repository
|
||||
Svn::Errors Svn::Add(String const &FileName)
|
||||
{
|
||||
String Out, Err;
|
||||
Svn::Errors result;
|
||||
|
||||
// if not connected, does nothing
|
||||
if(!FConnected)
|
||||
return SetError(Svn::NotConnected);
|
||||
|
||||
// checks whether given file/directory exists
|
||||
if(!Upp::FileExists(FileName) && !Upp::DirectoryExists(FileName))
|
||||
return SetError(Svn::PathNotFound);
|
||||
|
||||
// checks whether given path is inside repository
|
||||
if(!IsLocalPath(FileName))
|
||||
return SetError(Svn::PathNotInRepo);
|
||||
|
||||
// now we can add file to repository
|
||||
result = ExecSvn("add -q " + FileName, Out, Err, false);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
return SetError(Svn::Ok);
|
||||
|
||||
} // END Svn::Add()
|
||||
|
||||
Svn::Errors Svn::Add(Array<String> const &FileNames)
|
||||
{
|
||||
String Out, Err;
|
||||
Svn::Errors result;
|
||||
|
||||
// if not connected, does nothing
|
||||
if(!FConnected)
|
||||
return SetError(Svn::NotConnected);
|
||||
|
||||
// checks if all furnished files/directories exists and are in local repository
|
||||
for(int i = 0; i < FileNames.GetCount(); i++)
|
||||
{
|
||||
if(!Upp::FileExists(FileNames[i]) && !Upp::DirectoryExists(FileNames[i]))
|
||||
return SetError(Svn::PathNotFound);
|
||||
|
||||
if(!IsLocalPath(FileNames[i]))
|
||||
return SetError(Svn::PathNotInRepo);
|
||||
}
|
||||
|
||||
// now we can add files to repository
|
||||
for(int i = 0; i < FileNames.GetCount(); i++)
|
||||
{
|
||||
result = ExecSvn("add -q " + FileNames[i], Out, Err, false);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
}
|
||||
return SetError(Svn::Ok);
|
||||
|
||||
} // END Svn::Add()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// removes file(s) from current repository
|
||||
Svn::Errors Svn::Delete(String const &FileName)
|
||||
{
|
||||
String Out, Err;
|
||||
Svn::Errors result;
|
||||
|
||||
// if not connected, does nothing
|
||||
if(!FConnected)
|
||||
return SetError(Svn::NotConnected);
|
||||
|
||||
// must NOT check if files exists, they can be deleted
|
||||
// from folder but be listed in repo
|
||||
|
||||
// checks whether given path is inside repository
|
||||
if(!IsLocalPath(FileName))
|
||||
return SetError(Svn::PathNotInRepo);
|
||||
|
||||
// now we can remove file to repository
|
||||
result = ExecSvn("delete -q " + FileName, Out, Err, false);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
return SetError(Svn::Ok);
|
||||
|
||||
} // END Svn::Delete()
|
||||
|
||||
Svn::Errors Svn::Delete(Array<String> const &FileNames)
|
||||
{
|
||||
String Out, Err;
|
||||
Svn::Errors result;
|
||||
|
||||
// if not connected, does nothing
|
||||
if(!FConnected)
|
||||
return SetError(Svn::NotConnected);
|
||||
|
||||
// must NOT check if files exists, they can be deleted
|
||||
// from folder but be listed in repo
|
||||
|
||||
// checks if all furnished files/directories are in local repository
|
||||
for(int i = 0; i < FileNames.GetCount(); i++)
|
||||
{
|
||||
if(!IsLocalPath(FileNames[i]))
|
||||
return SetError(Svn::PathNotInRepo);
|
||||
}
|
||||
|
||||
// now we can add files to repository
|
||||
for(int i = 0; i < FileNames.GetCount(); i++)
|
||||
{
|
||||
result = ExecSvn("delete -q " + FileNames[i], Out, Err, false);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
}
|
||||
return SetError(Svn::Ok);
|
||||
|
||||
} // END Svn::Delete()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// copy a file inside current repository
|
||||
Svn::Errors Svn::Copy(String const &Src, String const &Dest)
|
||||
{
|
||||
String Out, Err;
|
||||
Svn::Errors result;
|
||||
String AuthStr;
|
||||
|
||||
// if not connected, does nothing
|
||||
if(!FConnected)
|
||||
return SetError(Svn::NotConnected);
|
||||
|
||||
// first, checks that given paths are inside current repository
|
||||
if(!IsRepositoryPath(Src) || !IsRepositoryPath(Dest))
|
||||
return SetError(Svn::PathNotInRepo);
|
||||
|
||||
// if source path is local, checks if exists
|
||||
if(!IsUrl(Src) && !Upp::FileExists(Src) && !Upp::DirectoryExists(Src))
|
||||
return SetError(Svn::PathNotFound);
|
||||
|
||||
// dest path is local, it should not exist
|
||||
if(!IsUrl(Dest) && (Upp::FileExists(Dest) || Upp::DirectoryExists(Dest)))
|
||||
return SetError(Svn::PathExists);
|
||||
|
||||
// if source or dest are remote, may require authentication
|
||||
if(IsUrl(Src) || IsUrl(Dest))
|
||||
AuthStr = BuildUserPassword();
|
||||
else
|
||||
AuthStr = " ";
|
||||
|
||||
// now we can do the copy
|
||||
result = ExecSvn("copy -q " + AuthStr + Src + " " + Dest, Out, Err, false);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
return SetError(Svn::Ok);
|
||||
|
||||
} // END Svn::Copy()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// moves a file inside current repository
|
||||
Svn::Errors Svn::Move(String const &Src, String const &Dest)
|
||||
{
|
||||
String Out, Err;
|
||||
Svn::Errors result;
|
||||
String AuthStr;
|
||||
|
||||
// if not connected, does nothing
|
||||
if(!FConnected)
|
||||
return SetError(Svn::NotConnected);
|
||||
|
||||
// first, checks that given paths are inside current repository
|
||||
if(!IsRepositoryPath(Src) || !IsRepositoryPath(Dest))
|
||||
return SetError(Svn::PathNotInRepo);
|
||||
|
||||
// if source path is local, checks if exists
|
||||
if(!IsUrl(Src) && !Upp::FileExists(Src) && !Upp::DirectoryExists(Src))
|
||||
return SetError(Svn::PathNotFound);
|
||||
|
||||
// dest path is local, it should not exist
|
||||
if(!IsUrl(Dest) && (Upp::FileExists(Dest) || Upp::DirectoryExists(Dest)))
|
||||
return SetError(Svn::PathExists);
|
||||
|
||||
// if source or dest are remote, may require authentication
|
||||
if(IsUrl(Src) || IsUrl(Dest))
|
||||
AuthStr = BuildUserPassword();
|
||||
else
|
||||
AuthStr = " ";
|
||||
|
||||
// now we can do the move
|
||||
result = ExecSvn("move -q " + AuthStr + Src + " " + Dest, Out, Err, false);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
return SetError(Svn::Ok);
|
||||
|
||||
} // END Svn::Move()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// gets log from remote
|
||||
Svn::Errors Svn::GetLog(Array<Svn::LogInfo>&logArray)
|
||||
{
|
||||
String Out, Err;
|
||||
Svn::Errors result;
|
||||
|
||||
// if not connected, does nothing
|
||||
if(!FConnected)
|
||||
return SetError(Svn::NotConnected);
|
||||
|
||||
// executes 'svn log' command -- gets current checked-in information
|
||||
result = ExecSvn("log " + BuildUserPassword() + FLocalPath, Out, Err, true);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
// parses log into logArray
|
||||
return SetError(ParseLog(Out, logArray));
|
||||
|
||||
} // END Svn::GetLog()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// gets local repository status
|
||||
Svn::Errors Svn::GetStatus(Array<Svn::StatusInfo>&statusArray)
|
||||
{
|
||||
String Out, Err;
|
||||
Svn::Errors result;
|
||||
|
||||
// if not connected, does nothing
|
||||
if(!FConnected)
|
||||
return SetError(Svn::NotConnected);
|
||||
|
||||
// executes 'svn status' command -- gets current checked-in information
|
||||
result = ExecSvn("status " + FLocalPath, Out, Err, true);
|
||||
if(result != Svn::Ok)
|
||||
return SetError(result);
|
||||
|
||||
// parses log into logArray
|
||||
return SetError(ParseStatus(Out, statusArray));
|
||||
|
||||
} // END Svn::GetStatus()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// updates info from current repository
|
||||
Svn::Errors Svn::UpdateInfo(void)
|
||||
{
|
||||
|
||||
} // END Svn::UpdateInfo()
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
277
bazaar/SvnLib/SvnLib.h
Normal file
277
bazaar/SvnLib/SvnLib.h
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
#ifndef _SvnLib_h_
|
||||
#define _SvnLib_h_
|
||||
|
||||
#include <Core/Core.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// svn interface class
|
||||
// encapsulates svn operation using command line tool 'svn'
|
||||
class Svn
|
||||
{
|
||||
public:
|
||||
// types of svn nodes
|
||||
enum NodeTypes
|
||||
{
|
||||
SvnUnknown,
|
||||
SvnDir
|
||||
};
|
||||
|
||||
// errors returned by various svn functions
|
||||
enum Errors
|
||||
{
|
||||
Ok = 0,
|
||||
UnknownError,
|
||||
NoSvnApp,
|
||||
NotARepo,
|
||||
NotConnected,
|
||||
FileNotFound,
|
||||
PathNotFound,
|
||||
FileExists,
|
||||
DirectoryExists,
|
||||
PathExists,
|
||||
DirectoryNotEmpty,
|
||||
NotADirectory,
|
||||
CantRemoveDirectory,
|
||||
CantWriteDirectory,
|
||||
PathNotInRepo,
|
||||
NotAnURL,
|
||||
BadXml,
|
||||
BadLogin
|
||||
};
|
||||
|
||||
// Human-readable error messages
|
||||
static const char *ErrorMessages[];
|
||||
|
||||
// Item status
|
||||
enum ItemStatus
|
||||
{
|
||||
unknown,
|
||||
added,
|
||||
missing,
|
||||
incomplete,
|
||||
replaced,
|
||||
modified,
|
||||
merged,
|
||||
conflicted,
|
||||
obstructed,
|
||||
ignored,
|
||||
external,
|
||||
unversioned,
|
||||
|
||||
}; // END enum ItemStatus
|
||||
|
||||
// Human-readable status strings
|
||||
static const char *StatusStrings[];
|
||||
static const int NumStatus;
|
||||
|
||||
// from status string, gets status
|
||||
static ItemStatus String2Status(String const &s);
|
||||
|
||||
// from status, gets human-readable string
|
||||
static String Status2String(ItemStatus s);
|
||||
|
||||
// svn entry info
|
||||
struct EntryInfo
|
||||
{
|
||||
String kind;
|
||||
String path;
|
||||
long revision;
|
||||
String url;
|
||||
String repositoryRoot;
|
||||
String repositoryUUID;
|
||||
long commitRevision;
|
||||
String commitAuthor;
|
||||
String commitDate;
|
||||
|
||||
}; // END struct EntryInfo;
|
||||
|
||||
// svn log info
|
||||
struct LogInfo
|
||||
{
|
||||
long revision;
|
||||
String author;
|
||||
String message;
|
||||
String date;
|
||||
|
||||
}; // END struct LogInfo
|
||||
|
||||
// svn status info
|
||||
struct StatusInfo
|
||||
{
|
||||
String path;
|
||||
String props;
|
||||
ItemStatus status;
|
||||
long revision;
|
||||
long commitRevision;
|
||||
String commitAuthor;
|
||||
String commitDate;
|
||||
|
||||
}; // END struct StatusInfo
|
||||
|
||||
private:
|
||||
// log-in stuffs
|
||||
String FUserName;
|
||||
String FPassword;
|
||||
bool FAnonymous;
|
||||
|
||||
// svn repository info stuffs
|
||||
String FLocalPath;
|
||||
String FRepositoryRoot;
|
||||
String FRepositoryUUID;
|
||||
|
||||
String FCheckedRevisionAuthor;
|
||||
ulong FCheckedRevision;
|
||||
String FCheckedRevisionDate;
|
||||
|
||||
String FHeadRevisionAuthor;
|
||||
ulong FHeadRevision;
|
||||
String FHeadRevisionDate;
|
||||
|
||||
bool FConnected;
|
||||
Errors FLastError;
|
||||
|
||||
String FLastCommandOutput;
|
||||
String FLastCommandError;
|
||||
|
||||
// executes svn, passing cmdline as argument, gathering output in Output
|
||||
// in xml format (where available) if xml is true
|
||||
Svn::Errors ExecSvn(String const &CmdLine, String &OutStr, String &ErrStr, bool xml = false);
|
||||
|
||||
// parses output of 'svn info' command and gathers its output
|
||||
Errors ParseInfo(String const &str, EntryInfo &info);
|
||||
|
||||
// parses xml output of 'svn log' command
|
||||
Errors ParseLog(String const &str, Array<LogInfo> &info);
|
||||
|
||||
// parses xml output of 'svn status' command
|
||||
Errors ParseStatus(String const &str, Array<StatusInfo> &info);
|
||||
|
||||
// builds username/password string
|
||||
String BuildUserPassword(void);
|
||||
|
||||
// builds revision string
|
||||
String BuildRevision(String const &Revision);
|
||||
|
||||
// checks whether a string is a remote URL or a local path
|
||||
bool IsUrl(String const &path);
|
||||
|
||||
// checks whether a path is inside local repository
|
||||
bool IsLocalPath(String const &path);
|
||||
|
||||
// checks whether a path is inside remote repository
|
||||
bool IsRemotePath(String const &path);
|
||||
|
||||
// checks whether a path is inside repository, remote or local side
|
||||
bool IsRepositoryPath(String const &path);
|
||||
|
||||
// initializer... used by constructor and on disconnection
|
||||
void Init(void);
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
Svn();
|
||||
|
||||
// destructor
|
||||
~Svn();
|
||||
|
||||
// sets error condition
|
||||
Errors SetError(Errors e) { FLastError = e; return e; }
|
||||
|
||||
// checks wether a path is a svn
|
||||
bool IsSvn(String const &LocalPath);
|
||||
|
||||
// checks wether the repository is connected
|
||||
bool IsConnected(void) { return FConnected; }
|
||||
|
||||
// gets local path of repository
|
||||
String GetLocalPath() { return FLocalPath; }
|
||||
String GetRepositoryRoot() { return FRepositoryRoot; }
|
||||
String GetRepositoryUUID() { return FRepositoryUUID; }
|
||||
String GetCheckedRevisionAuthor() { return FCheckedRevisionAuthor; }
|
||||
ulong GetCheckedRevision() { return FCheckedRevision; }
|
||||
String GetCkeckedRevisionDate() { return FCheckedRevisionDate; }
|
||||
String GetHeadRevisionAuthor() { return FHeadRevisionAuthor; }
|
||||
ulong GetHeadRevision() { return FHeadRevision; }
|
||||
String GetHeadRevisionDate() { return FHeadRevisionDate; }
|
||||
|
||||
Errors GetLastError() { return FLastError; }
|
||||
String GetErrorMessage(Svn::Errors err) { return ErrorMessages[err]; }
|
||||
String GetErrorMessage(void) { return ErrorMessages[FLastError]; }
|
||||
|
||||
String GetLastCommandOutput() { return FLastCommandOutput; }
|
||||
String GetLastCommandError() { return FLastCommandError; }
|
||||
|
||||
// sets user authentication
|
||||
void SetUser(String const &UserName, String const &Password);
|
||||
void SetUser(void);
|
||||
|
||||
// connects to the local copy
|
||||
Errors Connect(String const &LocalPath);
|
||||
|
||||
// disconnects from local copy
|
||||
Errors Disconnect(void);
|
||||
|
||||
// checks out from server
|
||||
Errors Checkout(String const &Url, String const &LocalPath, String const &Revision = "");
|
||||
|
||||
// updates current copy from server
|
||||
Errors Update(String const &Revision = "");
|
||||
|
||||
// commits to server
|
||||
Errors Commit(String const &Message);
|
||||
|
||||
// adds file(s) to current repository
|
||||
Errors Add(String const &FileName);
|
||||
Errors Add(Array<String> const &FileNames);
|
||||
|
||||
// removes file(s) from current repository
|
||||
Errors Delete(String const &FileName);
|
||||
Errors Delete(Array<String> const &FileNames);
|
||||
|
||||
// copy a file inside current repository
|
||||
Errors Copy(String const &Src, String const &Dest);
|
||||
|
||||
// moves a file inside current repository
|
||||
Errors Move(String const &Src, String const &Dest);
|
||||
|
||||
// gets log from remote
|
||||
Errors GetLog(Array<Svn::LogInfo>&logArray);
|
||||
|
||||
// gets local repository status
|
||||
Errors GetStatus(Array<Svn::StatusInfo>&statusArray);
|
||||
|
||||
// updates info from current repository
|
||||
Errors UpdateInfo(void);
|
||||
|
||||
}; // END Class Svn
|
||||
|
||||
/*
|
||||
blame
|
||||
cat
|
||||
cleanup
|
||||
diff
|
||||
export
|
||||
import
|
||||
list
|
||||
lock
|
||||
log
|
||||
merge
|
||||
mkdir
|
||||
propdel (pdel, pd)
|
||||
propedit (pedit, pe)
|
||||
propget (pget, pg)
|
||||
proplist (plist, pl)
|
||||
propset (pset, ps)
|
||||
resolved
|
||||
revert
|
||||
status (stat, st)
|
||||
switch (sw)
|
||||
unlock
|
||||
*/
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
8
bazaar/SvnLib/SvnLib.upp
Normal file
8
bazaar/SvnLib/SvnLib.upp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
uses
|
||||
CtrlLib,
|
||||
SysExec;
|
||||
|
||||
file
|
||||
SvnLib.h,
|
||||
SvnLib.cpp;
|
||||
|
||||
44
bazaar/SvnTest/SvnTest.h
Normal file
44
bazaar/SvnTest/SvnTest.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef _SvnTest_SvnTest_h
|
||||
#define _SvnTest_SvnTest_h
|
||||
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
#include <SvnLib/SvnLib.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
#define LAYOUTFILE <SvnTest/SvnTest.lay>
|
||||
#include <CtrlCore/lay.h>
|
||||
|
||||
class SvnTest : public WithSvnTestLayout<TopWindow>
|
||||
{
|
||||
// test repository path and local path
|
||||
String DestPath;
|
||||
String RepositoryUrl;
|
||||
|
||||
// svn object
|
||||
Svn svn;
|
||||
|
||||
// button handlers
|
||||
void Checkout(void);
|
||||
void Connect(void);
|
||||
void Disconnect(void);
|
||||
void Modify(void);
|
||||
void GetLog(void);
|
||||
void GetStatus(void);
|
||||
void ListFiles(void);
|
||||
void WipeFolder(void);
|
||||
void Quit(void);
|
||||
|
||||
// error messagebox
|
||||
void ShowError(void);
|
||||
void ShowError(String const &msg);
|
||||
|
||||
public:
|
||||
typedef SvnTest CLASSNAME;
|
||||
|
||||
SvnTest();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
13
bazaar/SvnTest/SvnTest.lay
Normal file
13
bazaar/SvnTest/SvnTest.lay
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
LAYOUT(SvnTestLayout, 672, 396)
|
||||
ITEM(DocEdit, TextArea, SetFont(CourierZ(10)).WantFocus(false).SetEditable(false).HSizePosZ(4, 4).VSizePosZ(4, 32))
|
||||
ITEM(Button, CheckoutButton, SetLabel(t_("Checkout")).LeftPosZ(16, 56).BottomPosZ(9, 15))
|
||||
ITEM(Button, QuitButton, SetLabel(t_("Quit")).LeftPosZ(604, 56).BottomPosZ(9, 15))
|
||||
ITEM(Button, ModifyButton, SetLabel(t_("Modify files")).LeftPosZ(216, 64).TopPosZ(372, 15))
|
||||
ITEM(Button, DisconnectButton, SetLabel(t_("Disconnect")).HSizePosZ(144, 464).TopPosZ(372, 15))
|
||||
ITEM(Button, StatusButton, SetLabel(t_("Get status")).HSizePosZ(352, 264).TopPosZ(372, 15))
|
||||
ITEM(Button, ListButton, SetLabel(t_("List files")).LeftPosZ(416, 56).TopPosZ(372, 15))
|
||||
ITEM(Button, WipeButton, SetLabel(t_("Wipe test folder")).LeftPosZ(508, 84).TopPosZ(372, 15))
|
||||
ITEM(Button, LogButton, SetLabel(t_("Get log")).LeftPosZ(288, 56).TopPosZ(372, 15))
|
||||
ITEM(Button, ConnectButton, SetLabel(t_("Connect")).HSizePosZ(80, 536).TopPosZ(372, 15))
|
||||
END_LAYOUT
|
||||
|
||||
12
bazaar/SvnTest/SvnTest.upp
Normal file
12
bazaar/SvnTest/SvnTest.upp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
uses
|
||||
CtrlLib,
|
||||
SvnLib;
|
||||
|
||||
file
|
||||
SvnTest.h,
|
||||
main.cpp,
|
||||
SvnTest.lay;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI";
|
||||
|
||||
269
bazaar/SvnTest/main.cpp
Normal file
269
bazaar/SvnTest/main.cpp
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
#include "SvnTest.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
SvnTest::SvnTest()
|
||||
{
|
||||
// initializes repository and local copy locations
|
||||
DestPath = "/tmp/svn-test";
|
||||
RepositoryUrl = "https://upp.svn.sourceforge.net/svnroot/upp/trunk/linux_scripts";
|
||||
|
||||
// connects the layout
|
||||
CtrlLayout(*this, "Window title");
|
||||
|
||||
// sets up handlers
|
||||
CheckoutButton <<= THISBACK(Checkout);
|
||||
ConnectButton <<= THISBACK(Connect);
|
||||
DisconnectButton <<= THISBACK(Disconnect);
|
||||
ModifyButton <<= THISBACK(Modify);
|
||||
LogButton <<= THISBACK(GetLog);
|
||||
StatusButton <<= THISBACK(GetStatus);
|
||||
ListButton <<= THISBACK(ListFiles);
|
||||
WipeButton <<= THISBACK(WipeFolder);
|
||||
QuitButton <<= THISBACK(Quit);
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// handlers
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SvnTest::Checkout(void)
|
||||
{
|
||||
// clears text area
|
||||
TextArea.Clear();
|
||||
|
||||
// sets up a welcome message
|
||||
TextArea.Set(TextArea.Get() + "Checking out '" + RepositoryUrl + "' repository... please wait\n\n");
|
||||
TextArea.Sync();
|
||||
|
||||
// error if already connected
|
||||
if(svn.IsConnected())
|
||||
{
|
||||
ShowError("Already connected!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
// connects to repository
|
||||
if(svn.Checkout(RepositoryUrl, DestPath) == Svn::Ok)
|
||||
{
|
||||
StringStream s;
|
||||
s << "Local path : " << svn.GetLocalPath() << "\n";
|
||||
s << "Repository root : " << svn.GetRepositoryRoot() << "\n";
|
||||
s << "Checked in revision : " << AsString(svn.GetCheckedRevision()) << "\n";
|
||||
s << "Author : " << svn.GetCheckedRevisionAuthor() << "\n";
|
||||
s << "Head revision : " << svn.GetHeadRevision() << "\n";
|
||||
s << "Revision Author : " << svn.GetHeadRevisionAuthor() << "\n";
|
||||
TextArea.Set(TextArea.Get() + s);
|
||||
}
|
||||
else
|
||||
ShowError();
|
||||
|
||||
} // END SvnTest::Checkout()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SvnTest::Connect(void)
|
||||
{
|
||||
// clears text area
|
||||
TextArea.Clear();
|
||||
|
||||
// sets up a welcome message
|
||||
TextArea.Set(TextArea.Get() + "Connecting to local repository '" + DestPath + "' ... please wait\n\n");
|
||||
TextArea.Sync();
|
||||
|
||||
// error if already connected
|
||||
if(svn.IsConnected())
|
||||
{
|
||||
ShowError("Already connected!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
// connects to repository
|
||||
if(svn.Connect(DestPath) == Svn::Ok)
|
||||
{
|
||||
StringStream s;
|
||||
s << "Local path : " << svn.GetLocalPath() << "\n";
|
||||
s << "Repository root : " << svn.GetRepositoryRoot() << "\n";
|
||||
s << "Checked in revision : " << AsString(svn.GetCheckedRevision()) << "\n";
|
||||
s << "Author : " << svn.GetCheckedRevisionAuthor() << "\n";
|
||||
s << "Head revision : " << svn.GetHeadRevision() << "\n";
|
||||
s << "Revision Author : " << svn.GetHeadRevisionAuthor() << "\n";
|
||||
TextArea.Set(TextArea.Get() + s);
|
||||
}
|
||||
else
|
||||
ShowError();
|
||||
|
||||
} // END SvnTest::Connect()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SvnTest::Disconnect(void)
|
||||
{
|
||||
// clears text area
|
||||
TextArea.Clear();
|
||||
|
||||
// sets up a welcome message
|
||||
TextArea.Set(TextArea.Get() + "Disconnecting from local repository '" + DestPath + "' ... please wait\n\n");
|
||||
TextArea.Sync();
|
||||
|
||||
// disconnects from repository
|
||||
if(svn.Disconnect() == Svn::Ok)
|
||||
TextArea.Set(TextArea.Get() + "Success.\n");
|
||||
else
|
||||
ShowError();
|
||||
|
||||
} // END SvnTest::Disconnect()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SvnTest::Modify(void)
|
||||
{
|
||||
// changes readme file
|
||||
String s = LoadFile(DestPath + "/README") + "\nA dummy change";
|
||||
SaveFile(DestPath + "/README", s);
|
||||
|
||||
// removes dobeta file
|
||||
FileDelete(DestPath + "/dobeta");
|
||||
|
||||
// adds an unversioned file
|
||||
SaveFile(DestPath + "/UnversionedFile", s);
|
||||
|
||||
// adds a versioned file
|
||||
SaveFile(DestPath + "/VersionedFile", s);
|
||||
svn.Add(DestPath + "/VersionedFile");
|
||||
|
||||
} // END SvnTest::Modify()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SvnTest::GetLog(void)
|
||||
{
|
||||
// clears text area
|
||||
TextArea.Clear();
|
||||
|
||||
// sets up a welcome message
|
||||
TextArea.Set(TextArea.Get() + "Getting log from remote repository '" + RepositoryUrl + "' repository... please wait\n\n");
|
||||
TextArea.Sync();
|
||||
|
||||
// gets log from svn repository
|
||||
TextArea.Set(TextArea.Get() + " ----- LOG OUTPUT -----\n");
|
||||
Array<Svn::LogInfo>logArray;
|
||||
if(svn.GetLog(logArray) == Svn::Ok)
|
||||
{
|
||||
StringStream s;
|
||||
for(int i = 0; i< logArray.GetCount(); i++)
|
||||
{
|
||||
s << "Revision : " << logArray[i].revision << "\n";
|
||||
s << "Author : " << logArray[i].author << "\n";
|
||||
s << "Message : " << logArray[i].message << "\n";
|
||||
s << "Date : " << logArray[i].date << "\n";
|
||||
s << "-------------------------------------------------------------\n";
|
||||
}
|
||||
TextArea.Set(TextArea.Get() + s);
|
||||
}
|
||||
else
|
||||
ShowError();
|
||||
|
||||
} // END SvnTest::GetLog()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SvnTest::GetStatus(void)
|
||||
{
|
||||
// clears text area
|
||||
TextArea.Clear();
|
||||
|
||||
// sets up a welcome message
|
||||
TextArea.Set(TextArea.Get() + "Getting status from local repository '" + DestPath + "' ... please wait\n\n");
|
||||
TextArea.Sync();
|
||||
|
||||
// gets repository status
|
||||
TextArea.Set(TextArea.Get() + " ----- STATUS OUTPUT -----\n");
|
||||
Array<Svn::StatusInfo>statusArray;
|
||||
if(svn.GetStatus(statusArray) == Svn::Ok)
|
||||
{
|
||||
StringStream s;
|
||||
for(int i = 0; i< statusArray.GetCount(); i++)
|
||||
{
|
||||
s << "Path : " << statusArray[i].path << "\n";
|
||||
s << "Properties : " << statusArray[i].props << "\n";
|
||||
s << "Status : " << svn.Status2String(statusArray[i].status) << "\n";
|
||||
s << "Revision : " << statusArray[i].revision << "\n";
|
||||
s << "Commit Revision : " << statusArray[i].commitRevision << "\n";
|
||||
s << "Commit Author : " << statusArray[i].commitAuthor << "\n";
|
||||
s << "Commit Date : " << statusArray[i].commitDate << "\n";
|
||||
s << "-------------------------------------------------------------\n";
|
||||
}
|
||||
TextArea.Set(TextArea.Get() + s);
|
||||
}
|
||||
else
|
||||
ShowError();
|
||||
|
||||
} // END SvnTest::GetStatus()
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SvnTest::ListFiles(void)
|
||||
{
|
||||
// clears text area
|
||||
TextArea.Clear();
|
||||
|
||||
// sets up a welcome message
|
||||
TextArea.Set(TextArea.Get() + "List of files in test folder:\n\n");
|
||||
TextArea.Sync();
|
||||
|
||||
StringStream s;
|
||||
Array<FileSystemInfo::FileInfo> files = StdFileSystemInfo().Find(DestPath + "/*");
|
||||
for(int i = 0; i < files.GetCount(); i++)
|
||||
s << files[i].filename << "\n";
|
||||
TextArea.Set(TextArea.Get() + s);
|
||||
|
||||
|
||||
} // END SvnTest::ListFiles()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SvnTest::WipeFolder(void)
|
||||
{
|
||||
// clears text area
|
||||
TextArea.Clear();
|
||||
|
||||
// sets up a welcome message
|
||||
TextArea.Set(TextArea.Get() + "Wiping test folder '" + DestPath + "'.....\n\n");
|
||||
TextArea.Sync();
|
||||
|
||||
DeleteFolderDeep(DestPath);
|
||||
|
||||
TextArea.Set(TextArea.Get() + "Success.\n");
|
||||
|
||||
} // END SvnTest::WipeFolder()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SvnTest::Quit(void)
|
||||
{
|
||||
Break();
|
||||
|
||||
} // END SvnTest::Quit()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// error messagebox
|
||||
void SvnTest::ShowError(void)
|
||||
{
|
||||
StringStream s;
|
||||
s << "ERROR : " << svn.GetErrorMessage();
|
||||
TextArea.Set(TextArea.Get() + s + "\n");
|
||||
TextArea.Sync();
|
||||
PromptOK(String(s));
|
||||
|
||||
} // END SvnTest::ShowError()
|
||||
|
||||
void SvnTest::ShowError(String const &str)
|
||||
{
|
||||
StringStream s;
|
||||
s << "ERROR : " << str;
|
||||
TextArea.Set(TextArea.Get() + s + "\n");
|
||||
TextArea.Sync();
|
||||
PromptOK(String(s));
|
||||
|
||||
} // END SvnTest::ShowError()
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
SvnTest().Run();
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue