WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions generate/templates/manual/include/cmd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#ifndef NODEGIT_CMD_H
#define NODEGIT_CMD_H

#include <string>
#include <map>

namespace nodegit {
/**
* \class Cmd
* Abstract class holding a command to execute.
*
* Instances of Cmd will store all the information needed to run the command,
* including environment variables to set, like CWD.
*/
class Cmd {
public:
/* Enumeration describing the environment variables that Cmd will handle
* - kCWD: Current Working Directory.
*/
enum class Env {kCWD};

Cmd() = default;
virtual ~Cmd() = default;
Cmd(const Cmd &other) = delete;
Cmd(Cmd &&other) = delete;
Cmd& operator=(const Cmd &other) = delete;
Cmd& operator=(Cmd &&other) = delete;

virtual std::string Command() const = 0; // return the command to execute
virtual std::string Args() const = 0; // return the arguments of the command if any

void SetEnv(Env env, const std::string &value) {
m_env[env] = value;
}
std::string GetEnv(Env env) const {
auto value = m_env.find(env);
if (value != m_env.end()) { return value->second; }
else { return std::string(""); }
}
void SetRedirectStdErr(bool redirectStdErr) {
m_redirectStdErr = redirectStdErr;
}
bool GetRedirectStdErr() const {
return m_redirectStdErr;
}

// TODO: turn private, and restrict set/get access with pre-validation if necessary
std::string out {}; // cmd output. TODO: stream here?
std::string errorMsg {}; // error message if the command execution failed

private:
std::map<Env, std::string> m_env {}; // environment variables for this command
bool m_redirectStdErr {true}; // whether or not to redirect stderr to stdout
};
} // namespace nodegit
#endif // NODEGIT_CMD_H
62 changes: 62 additions & 0 deletions generate/templates/manual/include/run_command.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#ifndef NODEGIT_RUN_CMD_H
#define NODEGIT_RUN_CMD_H

#include <iostream>
#include <cstdio>
#include <iostream>
#include <stdexcept>
#include <string>
#include <array>
#include "cmd.h"

namespace nodegit {
// TODO:
// This is just a first testing version to run commands in MacOS, Linux and Win32
namespace runcommand {
/**
* \brief Executes a command.
*
* \param cmd object storing all the information needed to execute a command. Result
* of the execution will also be stored here.
* \return true if command execution succeeded; false otherwise.
*/
bool exec(Cmd *cmd) {
// TODO: sanitize path
assert (cmd != nullptr);
std::string cwd = cmd->GetEnv(Cmd::Env::kCWD);
std::string cmdCwd = cwd.empty() ? std::string("") : std::string("cd ").append(cwd).append(" && ");
std::string cmdArgs = cmd->Args();
std::string finalCmdArgs = cmdArgs.empty() ? std::string("") : std::string(" ").append(cmdArgs);
std::string cmdRedirectErr = cmd->GetRedirectStdErr() ? " 2>&1" : std::string("");
std::string finalCmd = cmdCwd + cmd->Command() + finalCmdArgs + cmdRedirectErr;

#ifdef WIN32
auto pipe = _popen(finalCmd.c_str(), "r");
#else
auto pipe = popen(finalCmd.c_str(), "r");
#endif
if (!pipe) {
cmd->errorMsg = "popen() failed!";
return false;
}

std::array<char, 128> buffer {};
while (!feof(pipe)) {
if (fgets(buffer.data(), 128, pipe) != nullptr)
cmd->out += buffer.data();
}
#ifdef WIN32
auto rc = _pclose(pipe);
#else
auto rc = pclose(pipe);
#endif

if (rc != EXIT_SUCCESS) {
cmd->errorMsg = "pclose() failed!";
return false;
}
return true;
}
} // namespace runcommand
} // namespace nodegit
#endif // NODEGIT_RUN_CMD_H