common/teamcity_messages.cpp (136 lines of code) (raw):
#include "teamcity_messages.h"
#include <cstdlib>
#include <sstream>
namespace jetbrains {
namespace teamcity {
std::string getFlowIdFromEnvironment() {
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__) && !defined(__MINGW32__)
char *flowId = NULL;
size_t sz = 0;
std::string result;
if(!_dupenv_s(&flowId, &sz,"TEAMCITY_PROCESS_FLOW_ID")) {
result = flowId != NULL ? flowId : "";
free(flowId);
}
return result;
#else
const char *flowId = getenv("TEAMCITY_PROCESS_FLOW_ID");
return flowId == NULL ? "" : flowId;
#endif
}
bool underTeamcity() {
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__) && !defined(__MINGW32__)
char *teamCityProjectName = 0;
size_t sz = 0;
bool result = false;
if(!_dupenv_s(&teamCityProjectName, &sz, "TEAMCITY_PROJECT_NAME")) {
result = teamCityProjectName != NULL;
free(teamCityProjectName);
}
return result;
#else
return getenv("TEAMCITY_PROJECT_NAME") != NULL;
#endif
}
TeamcityMessages::TeamcityMessages()
: m_out(&std::cout)
{}
void TeamcityMessages::setOutput(std::ostream &out) {
m_out = &out;
}
std::string TeamcityMessages::escape(const std::string &s) {
std::string result;
result.reserve(s.length());
for (size_t i = 0; i < s.length(); i++) {
char c = s[i];
switch (c) {
case '\n': result.append("|n"); break;
case '\r': result.append("|r"); break;
case '\'': result.append("|'"); break;
case '|': result.append("||"); break;
case ']': result.append("|]"); break;
default: result.append(&c, 1);
}
}
return result;
}
void TeamcityMessages::openMsg(const std::string &name) {
// endl for http://jetbrains.net/tracker/issue/TW-4412
*m_out << std::endl << "##teamcity[" << name;
}
void TeamcityMessages::closeMsg() {
*m_out << "]";
// endl for http://jetbrains.net/tracker/issue/TW-4412
*m_out << std::endl;
}
void TeamcityMessages::writeProperty(const std::string &name, const std::string &value) {
*m_out << " " << name << "='" << escape(value) << "'";
}
void TeamcityMessages::suiteStarted(const std::string &name, const std::string &flowid) {
openMsg("testSuiteStarted");
writeProperty("name", name);
if(flowid.length() > 0) {
writeProperty("flowId", flowid);
}
closeMsg();
}
void TeamcityMessages::suiteFinished(const std::string &name, const std::string &flowid) {
openMsg("testSuiteFinished");
writeProperty("name", name);
if(flowid.length() > 0) {
writeProperty("flowId", flowid);
}
closeMsg();
}
void TeamcityMessages::testStarted(const std::string &name, const std::string &flowid, bool captureStandardOutput) {
openMsg("testStarted");
writeProperty("name", name);
if(flowid.length() > 0) {
writeProperty("flowId", flowid);
}
if(captureStandardOutput) {
writeProperty("captureStandardOutput", "true"); // false by default
}
closeMsg();
}
void TeamcityMessages::testFinished(const std::string &name, int durationMs, const std::string &flowid) {
openMsg("testFinished");
writeProperty("name", name);
if(flowid.length() > 0) {
writeProperty("flowId", flowid);
}
if(durationMs >= 0) {
std::stringstream out(std::ios_base::out);
out << durationMs;
writeProperty("duration", out.str());
}
closeMsg();
}
void TeamcityMessages::testFailed(const std::string &name, const std::string &message, const std::string &details, const std::string &flowid) {
openMsg("testFailed");
writeProperty("name", name);
writeProperty("message", message);
writeProperty("details", details);
if(flowid.length() > 0) {
writeProperty("flowId", flowid);
}
closeMsg();
}
void TeamcityMessages::testIgnored(const std::string &name, const std::string &message, const std::string &flowid) {
openMsg("testIgnored");
writeProperty("name", name);
writeProperty("message", message);
if(flowid.length() > 0) {
writeProperty("flowId", flowid);
}
closeMsg();
}
void TeamcityMessages::testOutput(const std::string &name, const std::string &output, const std::string &flowid, bool isStdError) {
openMsg(isStdError ? "testStdErr" : "testStdOut");
writeProperty("name", name);
writeProperty("out", output);
if(flowid.length() > 0) {
writeProperty("flowId", flowid);
}
closeMsg();
}
}
}