- °³¿ä
- ·¡ÆÛ
- »ùÇÃ
- ¸µÅ©
1 °³¿ä
¾ÖÇø®ÄÉÀÌ¼Ç ¾È¿¡¼ ÆÛÆ÷½º ÀúÀå¼Ò¿¡ ¾×¼¼½ºÇϸé ÁÁÀ» ¶§°¡ ÀÖ´Ù.
°³¹ßÆÀ ³»ºÎ¿¡¼ »ç¿ëÇÏ´Â °¢Á¾ ÀÎÇϿ콺 ÅøÀÌ ´ëÇ¥ÀûÀ̶ó°í ÇÒ ¼ö ÀÖ´Ù. ÆÛÆ÷½º¿¡¼´Â À̸¦ À§ÇØ ¿©·¯°¡Áö ¾ð¾î¸¦ À§ÇÑ API¸¦ Á¦°øÇϴµ¥, ºÒÇàÀÎÁö ´ÙÇàÀÎÁö C++ APIµµ ±× ¸ñ·Ï ÁßÀÇ Çϳª´Ù. ±×·¯³ª °¢Á¾ ±â´É¿¡ ´ëÇØ¼ º°µµÀÇ API°¡ Á¸ÀçÇÏ´Â °ÍÀÌ ¾Æ´Ï¶ó, Ä¿¸Çµå ¶óÀο¡¼ ÀÔ·ÂÇÏ´Â ÆÛÆ÷½º ¸í·É¾î¸¦ ±×´ë·Î ÀÔ·ÂÇϰí, ±× Ãâ·ÂÀ» ±×³É ¹®ÀÚ¿·Î ¹Þµµ·Ï µÇ¾îÀÖ´Ù. Áï ¹º°¡ ´ë´ÜÇÑ ÀÏÀ» Çϱâ À§Çؼ´Â ÀÏÀÏÀÌ ¹®ÀÚ¿ ÆÄ½ÌÇØ¾ß ÇÑ´Ù´Â À̾߱â´Ù. ÀÌ·² °Å¸é ±×³É ÆÛÆ÷½º Ŭ¶óÀÌ¾ðÆ® ±ò°í, system API »ç¿ëÇÏ´Â °Å¶û º°¹Ý Â÷À̰¡ ¾ø´Â °Í °°Àºµ¥, ¹¹ ¾î¼·ª.
ÆÛÆ÷½º Ŭ¶óÀ̾ðÆ®/¼¹ö¿Í´Â ´Þ¸® API ÂÊÀº ¹®¼°¡ ¸Å¿ì ºó¾àÇÏ´Ù. ÆÛÆ÷½º Ãø¿¡¼ µüÈ÷ °³¼±ÇÒ ÀÇÁöµµ ¾ø¾îº¸ÀδÙ. °³¼±ÇÒ ÀÇÁö°¡ ÀÖ¾ú´Ù¸é API¸¦ ÀÌ·¸°Ô ¸¸µé¾î³õÁö´Â ¾Ê¾Ò°ÚÁö.
2 ·¡ÆÛ
////////////////////////////////////////////////////////////////////////////////////////////////////
/// \file Perforce.h
/// \author excel96
/// \date 2008.12.30
////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <map>
#include <objbase.h>
#include <string>
#include <tchar.h>
#include <vector>
#pragma warning(push)
#pragma warning(disable:4100)
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#include <p4/clientapi.h>
namespace Perforce
{
struct LexLess
{
bool operator()(const std::string& lhs, const std::string& rhs) const
{
return CompareStringA(
LOCALE_USER_DEFAULT, NORM_IGNORECASE, lhs.c_str(), -1, rhs.c_str(), -1
) == CSTR_LESS_THAN;
}
};
typedef std::vector<std::string> Array;
typedef std::map<std::string, std::string, LexLess> Dictionary;
/// ÆÛÆ÷½º ·¡ÆÛ
class Client : protected ClientUser
{
private:
ClientApi m_Client; ///< API ÄÁÅØ½ºÆ®
Dictionary m_Output; ///< ¸í·É °á°ú¹°
Error m_Error; ///< ¿¡·¯°ª
public:
/// \brief »ý¼ºÀÚ
Client();
/// \brief ¼Ò¸êÀÚ
~Client();
public:
/// \brief ·Î±×ÀÎÇÑ´Ù.
bool Login();
/// \brief ·Î±×¾Æ¿ôÇÑ´Ù.
void Logout();
public:
/// \brief ¸í·ÉÀ» ½ÇÇàÇÑ´Ù.
bool Run(const std::string& command, const Array& arguments);
/// \brief ¸í·ÉÀ» ½ÇÇàÇÑ´Ù.
bool Run(const std::string& command);
/// \brief ¸í·ÉÀ» ½ÇÇàÇÑ´Ù.
bool Run(const std::string& command, const std::string& arg0);
/// \brief ¸í·ÉÀ» ½ÇÇàÇÑ´Ù.
bool Run(const std::string& command, const std::string& arg0, const std::string& arg1);
/// \brief ¸í·É ½ÇÇà °á°ú¸¦ ¹ÝȯÇÑ´Ù.
const Dictionary& GetOutput() const;
/// \brief ¸í·É ½ÇÇà °á°ú¸¦ ¹ÝȯÇÑ´Ù.
const std::string& GetOutput(const std::string& name) const;
/// \brief ¿¡·¯ ¹®ÀÚ¿À» ¹ÝȯÇÑ´Ù.
std::string GetErrorString();
public:
/// \brief ·ÎÄà °æ·Î¸¦ µðÆÌ °æ·Î·Î º¯È¯ÇÑ´Ù.
std::string Local2Depot(std::string path, bool dir);
/// \brief µðÆÌ °æ·Î¸¦ ·ÎÄà °æ·Î·Î º¯È¯ÇÑ´Ù.
std::string Depot2Local(const std::string& path);
/// \brief ÆíÁýÀ» À§ÇØ ¿¬´Ù.
bool Edit(const std::string& path);
private:
/// \brief ClientUser Ŭ·¡½º Äݹé
virtual void OutputError(const char* errBuf);
/// \brief ClientUser Ŭ·¡½º Äݹé
virtual void OutputInfo(char level, const char* data);
/// \brief ClientUser Ŭ·¡½º Äݹé
virtual void OutputBinary(const char* data, int length);
/// \brief ClientUser Ŭ·¡½º Äݹé
virtual void OutputText(const char* data, int length);
/// \brief ClientUser Ŭ·¡½º Äݹé
virtual void OutputStat(StrDict* varList);
};
/// \brief Ãâ·Â °á°ú¹°À» ¹®ÀÚ¿·Î ÅëÇÕÇØ¼ ¹ÝȯÇÑ´Ù.
std::string Join(const Dictionary& dict, const std::string& seperator = "\r\n");
}
#pragma warning(pop)
////////////////////////////////////////////////////////////////////////////////////////////////////
/// \file Perforce.cpp
/// \author excel96
/// \date 2008.12.30
////////////////////////////////////////////////////////////////////////////////////////////////////
#include "Perforce.h"
#include <sstream>
#ifdef _DEBUG
#ifdef _DLL
#pragma comment(lib, "debugdll_libclient")
#pragma comment(lib, "debugdll_librpc")
#pragma comment(lib, "debugdll_libsupp")
#else
#pragma comment(lib, "debug_libclient")
#pragma comment(lib, "debug_librpc")
#pragma comment(lib, "debug_libsupp")
#endif
#else
#ifdef _DLL
#pragma comment(lib, "releasedll_libclient")
#pragma comment(lib, "releasedll_librpc")
#pragma comment(lib, "releasedll_libsupp")
#else
#pragma comment(lib, "release_libclient")
#pragma comment(lib, "release_librpc")
#pragma comment(lib, "release_libsupp")
#endif
#endif
namespace Perforce
{
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
////////////////////////////////////////////////////////////////////////////////////////////////
Client::Client()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ¼Ò¸êÀÚ
////////////////////////////////////////////////////////////////////////////////////////////////
Client::~Client()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ·Î±×ÀÎÇÑ´Ù.
///
/// ·¹Áö½ºÆ®¸®¿¡ Á¸ÀçÇÏ´Â ÆÛÆ÷½º Á¤º¸¸¦ ÀÌ¿ëÇØ ·Î±×ÀÎÇϱ⠶§¹®¿¡ ¿öÅ©½ºÆäÀ̽º°¡ ¹Ì¸® ¼¼ÆÃµÇ¾î
/// ÀÖ¾î¾ß ÇÑ´Ù.
///
/// \return bool ¹«»çÈ÷ ·Î±×ÀÎÇß´Ù¸é true
////////////////////////////////////////////////////////////////////////////////////////////////
bool Client::Login()
{
m_Client.SetProtocol("tag", "");
m_Client.Init(&m_Error);
return m_Error.Test() == false;
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ·Î±×¾Æ¿ôÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////////////////////
void Client::Logout()
{
m_Client.Final(&m_Error);
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ¸í·ÉÀ» ½ÇÇàÇÑ´Ù.
/// \param command ½ÇÇàÇÒ ¸í·É
/// \param arguments ÀÎÀÚ
/// \return bool
////////////////////////////////////////////////////////////////////////////////////////////////
bool Client::Run(const std::string& command, const Array& arguments)
{
m_Output.clear();
char** argv = NULL;
if (!arguments.empty())
{
argv = new char*[arguments.size()];
for (size_t i=0; i<arguments.size(); ++i)
argv[i] = (char*)(arguments[i].c_str());
}
m_Client.SetArgv(static_cast<int>(arguments.size()), argv);
m_Client.Run(command.c_str(), this);
if (argv)
delete [] argv;
return !m_Error.Test();
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ¸í·ÉÀ» ½ÇÇàÇÑ´Ù.
/// \param command ½ÇÇàÇÒ ¸í·É¾î
/// \return bool ¹«»çÈ÷ ½ÇÇàÇß´Ù¸é true, ¹º°¡ ¿¡·¯°¡ »ý°å´Ù¸é false
////////////////////////////////////////////////////////////////////////////////////////////////
bool Client::Run(const std::string& command)
{
return Run(command, Array());
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ¸í·ÉÀ» ½ÇÇàÇÑ´Ù.
/// \param command ½ÇÇàÇÒ ¸í·É
/// \param arg0 ÀÎÀÚ
/// \return bool ¹«»çÈ÷ ½ÇÇàÇß´Ù¸é true, ¹º°¡ ¿¡·¯°¡ »ý°å´Ù¸é false
////////////////////////////////////////////////////////////////////////////////////////////////
bool Client::Run(const std::string& command, const std::string& arg0)
{
Array arguments;
arguments.push_back(arg0);
return Run(command, arguments);
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ¸í·ÉÀ» ½ÇÇàÇÑ´Ù.
/// \param command ½ÇÇàÇÒ ¸í·É
/// \param arg0 ÀÎÀÚ
/// \param arg1 ÀÎÀÚ
/// \return bool ¹«»çÈ÷ ½ÇÇàÇß´Ù¸é true, ¹º°¡ ¿¡·¯°¡ »ý°å´Ù¸é false
////////////////////////////////////////////////////////////////////////////////////////////////
bool Client::Run(const std::string& command, const std::string& arg0, const std::string& arg1)
{
Array arguments;
arguments.push_back(arg0);
arguments.push_back(arg1);
return Run(command, arguments);
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ¸í·É ½ÇÇà °á°ú¸¦ ¹ÝȯÇÑ´Ù.
/// \return const Dictionary& ½ÇÇà °á°ú
////////////////////////////////////////////////////////////////////////////////////////////////
const Dictionary& Client::GetOutput() const
{
return m_Output;
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ¸í·É ½ÇÇà °á°ú¸¦ ¹ÝȯÇÑ´Ù.
/// \param name °ª À̸§
/// \return const std::string& °ª
////////////////////////////////////////////////////////////////////////////////////////////////
const std::string& Client::GetOutput(const std::string& name) const
{
static std::string dummy;
Dictionary::const_iterator itr(m_Output.find(name));
return itr != m_Output.end() ? itr->second : dummy;
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ¿¡·¯ ¹®ÀÚ¿À» ¹ÝȯÇÑ´Ù.
/// \return std::string ¿¡·¯ ¹®ÀÚ¿
////////////////////////////////////////////////////////////////////////////////////////////////
std::string Client::GetErrorString()
{
std::string result;
if (m_Error.Test())
{
StrBuf msg;
m_Error.Fmt(&msg);
return std::string(msg.Text());
}
return result;
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ·ÎÄà °æ·Î¸¦ µðÆÌ °æ·Î·Î º¯È¯ÇÑ´Ù.
/// \param path ·ÎÄÃ °æ·Î
/// \return std::string µðÆÌ °æ·Î
////////////////////////////////////////////////////////////////////////////////////////////////
std::string Client::Local2Depot(std::string path, bool dir)
{
std::string converted;
if (dir)
{
if (!path.empty() && path[path.size()-1] != '\\')
path += '\\';
path += _T("1");
}
Array arguments;
arguments.push_back(path);
if (Run("where", arguments))
{
converted = GetOutput("depotFile");
if (dir)
converted = converted.substr(0, converted.size()-1);
}
return converted;
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief µðÆÌ °æ·Î¸¦ ·ÎÄà °æ·Î·Î º¯È¯ÇÑ´Ù.
/// \param path µðÆÌ °æ·Î
/// \return std::string ·ÎÄÃ °æ·Î
////////////////////////////////////////////////////////////////////////////////////////////////
std::string Client::Depot2Local(const std::string& path)
{
std::string converted;
bool dir = !path.empty() && path[path.size()-1] == '/';
Array arguments;
if (dir)
arguments.push_back(path + "...");
else
arguments.push_back(path);
if (Run("where", arguments))
{
converted = GetOutput("path");
if (dir)
converted = converted.substr(0, converted.size()-3);
}
return converted;
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ÆíÁýÀ» À§ÇØ ¿¬´Ù.
/// \param path µðÆÌ °æ·Î
/// \return bool ¹«»çÈ÷ ¿¾ú´Ù¸é true
////////////////////////////////////////////////////////////////////////////////////////////////
bool Client::Edit(const std::string& path)
{
Array arguments;
arguments.push_back(path);
return Run("edit", arguments);
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ClientUser Ŭ·¡½º Äݹé
/// \param errBuf
////////////////////////////////////////////////////////////////////////////////////////////////
void Client::OutputError(const char* /*errBuf*/)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ClientUser Ŭ·¡½º Äݹé
/// \param level
/// \param data
////////////////////////////////////////////////////////////////////////////////////////////////
void Client::OutputInfo(char /*level*/, const char* /*data*/)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ClientUser Ŭ·¡½º Äݹé
/// \param data
/// \param length
////////////////////////////////////////////////////////////////////////////////////////////////
void Client::OutputBinary(const char* /*data*/, int /*length*/)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ClientUser Ŭ·¡½º Äݹé
/// \param data
/// \param length
////////////////////////////////////////////////////////////////////////////////////////////////
void Client::OutputText(const char* /*data*/, int /*length*/)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief ClientUser Ŭ·¡½º Äݹé
/// \param varList
////////////////////////////////////////////////////////////////////////////////////////////////
void Client::OutputStat(StrDict* varList)
{
StrBuf msg;
StrRef var, val;
for (int i = 0; varList->GetVar(i, var, val); ++i)
{
if (var == "func" || var == P4Tag::v_specFormatted)
continue;
if (m_Output.find(var.Text()) == m_Output.end())
m_Output.insert(Dictionary::value_type(var.Text(), val.Text()));
}
}
}
3 »ùÇÃ
Perforce::Client perforce;
if (perforce.Login())
{
perforce.Run("edit", "somewhere/over/the/rainbow/*.csv");
...
perforce.Run("revert", "-a", "somewhere/over/the/rainbow/*.csv");
...
}
4 ¸µÅ©
SeriousMoin v1 (koMoinMoin 1.0a4 Modified)