Merged svn-support into master.

This commit is contained in:
WrinklyNinja
2013-07-31 21:13:59 +01:00
parent ffe911e7d6
commit 33feedef86
2 changed files with 99 additions and 39 deletions
+98 -38
View File
@@ -37,7 +37,7 @@
# include "windows.h"
# include "shlobj.h"
#endif
#define BUFSIZE 4096
#define BUFSIZE 4096
using namespace std;
@@ -51,14 +51,14 @@ namespace boss {
SECURITY_ATTRIBUTES saAttr;
PROCESS_INFORMATION piProcInfo;
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
CHAR chBuf[BUFSIZE];
DWORD dwRead;
DWORD exitCode;
//Init attributes.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
@@ -75,7 +75,7 @@ namespace boss {
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = consoleWrite;
siStartInfo.hStdOutput = consoleWrite;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
@@ -85,15 +85,15 @@ namespace boss {
wchar_t * cmdLine = new wchar_t[utf16Len];
MultiByteToWideChar(CP_UTF8, 0, command.c_str(), -1, cmdLine, utf16Len);
bool result = CreateProcess(NULL,
cmdLine, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
bool result = CreateProcess(NULL,
cmdLine, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
delete [] cmdLine;
@@ -109,14 +109,14 @@ namespace boss {
BOOST_LOG_TRIVIAL(error) << "Could not get Subversion process exit code.";
throw error(error::subversion_error, "Could not get Subversion process exit code.");
}
if (!ReadFile(consoleRead, chBuf, BUFSIZE, &dwRead, NULL)) {
BOOST_LOG_TRIVIAL(error) << "Could not read Subversion process output.";
throw error(error::subversion_error, "Could not read Subversion process output.");
}
output = string(chBuf, dwRead);
return exitCode == 0;
}
@@ -124,11 +124,11 @@ namespace boss {
string GetRevision(const std::string& buffer) {
string revision, date;
size_t pos1, pos2;
pos1 = buffer.rfind("Revision: ");
if (pos1 == string::npos)
return "";
pos2 = buffer.find('\n', pos1);
revision = buffer.substr(pos1+10, pos2-pos1-10);
@@ -141,8 +141,21 @@ namespace boss {
return revision + " (" + date + ")";
}
std::string UpdateMasterlist(const Game& game, std::vector<std::string>& parsingErrors) {
//Gets repository URL string.
string GetURL(const std::string& buffer) {
size_t pos1, pos2;
pos1 = buffer.rfind("Repository Root: ");
if (pos1 == string::npos)
return "";
pos2 = buffer.find('\n', pos1);
return buffer.substr(pos1+17, pos2-pos1-17);
}
std::string UpdateMasterlist(Game& game, std::vector<std::string>& parsingErrors) {
string command, output, revision;
//First check if the working copy is set up or not.
command = g_path_svn.string() + " info \"" + game.MasterlistPath().string() + "\"";
@@ -158,7 +171,7 @@ namespace boss {
else
return "N/A";
}
if (!success) {
BOOST_LOG_TRIVIAL(trace) << "Working copy is not set up, checking out repository.";
//Working copy not set up, perform a checkout.
@@ -167,6 +180,30 @@ namespace boss {
BOOST_LOG_TRIVIAL(error) << "Subversion could not perform a checkout. Details: " << output;
throw error(error::subversion_error, "Subversion could not perform a checkout. Details: " + output);
}
} else {
//A working copy exists, but we need to make sure that it points to the right repository.
BOOST_LOG_TRIVIAL(trace) << "Comparing working copy repository URL with BOSS's URL";
command = g_path_svn.string() + " info \"" + game.MasterlistPath().string() + "\"";
if (!RunCommand(command, output)) {
BOOST_LOG_TRIVIAL(error) << "Subversion could not get the repository URL. Details: " << output;
throw error(error::subversion_error, "Subversion could not get the repository URL. Details: " + output);
}
string url = GetURL(output);
//Now compare URLs.
if (url != game.URL()) {
BOOST_LOG_TRIVIAL(trace) << "URLs do not match: relocating the working copy.";
command = g_path_svn.string() + " relocate " + game.URL();
if (!RunCommand(command, output)) {
BOOST_LOG_TRIVIAL(error) << "Subversion could not relocate the working copy. Details: " << output;
throw error(error::subversion_error, "Subversion could not relocate the working copy. Details: " + output);
}
}
}
//Now update masterlist.
@@ -177,35 +214,58 @@ namespace boss {
throw error(error::subversion_error, "Subversion could not update the masterlist. Details: " + output);
}
while (true) {
bool parsingFailed = false;
do {
//Now get the masterlist revision.
BOOST_LOG_TRIVIAL(trace) << "Getting the new masterlist version.";
command = g_path_svn.string() + " info \"" + game.MasterlistPath().string() + "\"";
if (!RunCommand(command, output)) {
BOOST_LOG_TRIVIAL(error) << "Subversion could not read the masterlist revision number. Details: " << output;
throw error(error::subversion_error, "Subversion could not read the masterlist revision number. Details: " + output);
}
BOOST_LOG_TRIVIAL(trace) << "Reading the masterlist version from the svn info output.";
revision = GetRevision(output);
try {
//Now get the masterlist revision.
BOOST_LOG_TRIVIAL(trace) << "Getting the new masterlist version.";
command = g_path_svn.string() + " info \"" + game.MasterlistPath().string() + "\"";
if (!RunCommand(command, output)) {
BOOST_LOG_TRIVIAL(error) << "Subversion could not read the masterlist revision number. Details: " << output;
throw error(error::subversion_error, "Subversion could not read the masterlist revision number. Details: " + output);
}
BOOST_LOG_TRIVIAL(trace) << "Reading the masterlist version from the svn info output.";
revision = GetRevision(output);
//Now test masterlist to see if it parses OK.
BOOST_LOG_TRIVIAL(trace) << "Testing the new masterlist to see if it parses OK.";
YAML::Node mlist = YAML::LoadFile(game.MasterlistPath().string());
return revision;
} catch (YAML::Exception& e) {
list<boss::Message> messages;
list<boss::Plugin> plugins;
if (mlist["globals"])
messages = mlist["globals"].as< list<boss::Message> >();
if (mlist["plugins"])
plugins = mlist["plugins"].as< list<boss::Plugin> >();
for (list<boss::Plugin>::iterator it=plugins.begin(), endIt=plugins.end(); it != endIt; ++it) {
it->EvalAllConditions(game, g_lang_any);
}
for (list<boss::Message>::iterator it=messages.begin(), endIt=messages.end(); it != endIt; ++it) {
it->EvalCondition(game, g_lang_any);
}
parsingFailed = false;
} catch (exception& e) {
parsingFailed = true;
//Roll back one revision if there's an error.
BOOST_LOG_TRIVIAL(error) << "Masterlist parsing failed. Masterlist revision " + revision + ": " + e.what();
parsingErrors.push_back("Masterlist revision " + revision + ": " + e.what());
command = g_path_svn.string() + " update --revision PREV \"" + game.MasterlistPath().string() + "\"";
if (!RunCommand(command, output)) {
BOOST_LOG_TRIVIAL(error) << "Subversion could not update the masterlist. Details: " << output;
throw error(error::subversion_error, "Subversion could not update the masterlist. Details: " + output);
}
}
}
} while (parsingFailed);
return revision;
}
}
+1 -1
View File
@@ -57,6 +57,6 @@ namespace boss {
```svn info masterlist.txt``` returns a bunch of info: the line "Revision: XXXX" contains the revision number.
*/
std::string UpdateMasterlist(const Game& game, std::vector<std::string>& parsingErrors);
std::string UpdateMasterlist(Game& game, std::vector<std::string>& parsingErrors);
}
#endif