implemented execution context. needs thoroughly tested.
parent
9d89f5ad6a
commit
46e56b8d6f
|
@ -1,5 +1,7 @@
|
||||||
{
|
{
|
||||||
"units_path": "/home/phanes/development/internal/Examplar/conf/units/all_test.units",
|
"execution_context_override": true,
|
||||||
"plan_path": "/home/phanes/development/internal/Examplar/conf/plans/test.plan",
|
"execution_context": "/home/phanes/development/internal/Examplar/conf/",
|
||||||
"config_version": "1"
|
"units_path": "units/all_test.units",
|
||||||
|
"plan_path": "plans/test.plan",
|
||||||
|
"config_version": "2"
|
||||||
}
|
}
|
||||||
|
|
52
examplar.cpp
52
examplar.cpp
|
@ -23,8 +23,8 @@
|
||||||
#include "src/loaders/loaders.h"
|
#include "src/loaders/loaders.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
#include "src/loaders/helpers.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO Commandline switches
|
* TODO Commandline switches
|
||||||
|
@ -32,34 +32,45 @@
|
||||||
|
|
||||||
void print_usage()
|
void print_usage()
|
||||||
{
|
{
|
||||||
printf("examplar [ -h | --help ] [ -v | --verbose ] [ -c | --config CONFIG_PATH ]\n\n");
|
printf("examplar [ -h | --help ] [ -v | --verbose ] [ -e | --execution-context EXECUTION_CONTEXT ][ -c | --config CONFIG_PATH ]\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char * argv[] )
|
int main( int argc, char * argv[] )
|
||||||
{
|
{
|
||||||
int flags, opt;
|
int flags, opt;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
bool show_help = false;
|
bool show_help = false;
|
||||||
|
|
||||||
|
// indicator of whether examplar should use a commandline argument for overriding the context
|
||||||
|
// instead of what's supplied in the conf file
|
||||||
|
bool cli_context_supplied = false;
|
||||||
|
|
||||||
std::string config_path = "/etc/Examplar/config.json";
|
std::string config_path = "/etc/Examplar/config.json";
|
||||||
|
std::string execution_context;
|
||||||
|
|
||||||
// commandline switches:
|
// commandline switches:
|
||||||
// -h help
|
// -h help
|
||||||
// -v verbose
|
// -v verbose
|
||||||
// -c CONFIG_FILE_PATH -- defaults to '/etc/Examplar/config.json'
|
// -c CONFIG_FILE_PATH -- defaults to '/etc/Examplar/config.json'
|
||||||
|
// -e EXECUTION_CONTEXT -- current working directory when executing unit targets
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
static struct option long_options[] =
|
static struct option long_options[] =
|
||||||
{
|
{
|
||||||
{"verbose", no_argument, 0, 'v'},
|
{"verbose", no_argument, 0, 'v'},
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
{"config", required_argument, 0, 'c'},
|
{"config", required_argument, 0, 'c'},
|
||||||
|
{"execution-context", required_argument, 0, 'e'},
|
||||||
{0, 0}
|
{0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
|
|
||||||
opt = getopt_long (argc, argv, "vhc:",
|
opt = getopt_long (argc, argv, "vhec:", long_options, &option_index);
|
||||||
long_options, &option_index);
|
|
||||||
|
|
||||||
if (opt == -1)
|
if (opt == -1)
|
||||||
break;
|
break;
|
||||||
|
@ -80,6 +91,10 @@ int main( int argc, char * argv[] )
|
||||||
case '?':
|
case '?':
|
||||||
print_usage();
|
print_usage();
|
||||||
exit(1);
|
exit(1);
|
||||||
|
case 'e':
|
||||||
|
cli_context_supplied = true;
|
||||||
|
execution_context = std::string(optarg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -99,14 +114,33 @@ int main( int argc, char * argv[] )
|
||||||
// A Plan declares what units are executed and a Suite declares the definitions of those units.
|
// A Plan declares what units are executed and a Suite declares the definitions of those units.
|
||||||
Conf configuration = Conf(config_path, verbose );
|
Conf configuration = Conf(config_path, verbose );
|
||||||
|
|
||||||
// load the configuration file which contains filepaths to definitions of a plan and definitions of units.
|
// if the user set this option as a commandline argument
|
||||||
|
if ( cli_context_supplied == true )
|
||||||
|
{
|
||||||
|
// override the conf file's specified execution context
|
||||||
|
configuration.set_execution_context( execution_context );
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if context override
|
||||||
|
if ( configuration.has_context_override() )
|
||||||
|
{
|
||||||
|
// if so, set the CWD.
|
||||||
|
chdir( configuration.get_execution_context().c_str() );
|
||||||
|
std::ostringstream infostring;
|
||||||
|
infostring << "Execution context: " << get_working_path() << std::endl;
|
||||||
|
syslog(LOG_INFO, infostring.str().c_str() );
|
||||||
|
std::cout << infostring.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// load the filepaths to definitions of a plan and definitions of units.
|
||||||
std::string definitions_file = configuration.get_units_path();
|
std::string definitions_file = configuration.get_units_path();
|
||||||
std::string plan_file = configuration.get_plan_path();
|
std::string plan_file = configuration.get_plan_path();
|
||||||
|
|
||||||
Suite available_definitions;
|
Suite available_definitions;
|
||||||
available_definitions.load_units_file( definitions_file, verbose );
|
available_definitions.load_units_file( definitions_file, verbose );
|
||||||
|
|
||||||
Plan plan;
|
Plan plan( &configuration );
|
||||||
plan.load_plan_file( plan_file, verbose );
|
plan.load_plan_file( plan_file, verbose );
|
||||||
|
|
||||||
plan.load_definitions( available_definitions, verbose );
|
plan.load_definitions( available_definitions, verbose );
|
||||||
|
|
|
@ -19,17 +19,48 @@
|
||||||
*/
|
*/
|
||||||
#include "Conf.h"
|
#include "Conf.h"
|
||||||
|
|
||||||
/// CONF_PLANPATH_INVALID - Exception thrown when the Conf type can not load the supplied path for the Plan definition
|
/// ConfigLoadException - General exception handler for the Conf class.
|
||||||
/// file.
|
class ConfigLoadException: public std::exception
|
||||||
class CONF_PLANPATH_INVALID: public std::runtime_error { public:
|
{
|
||||||
CONF_PLANPATH_INVALID(): std::runtime_error("conf: The supplied path for the plan definition file is invalid.") {}
|
public:
|
||||||
|
/** Constructor (C strings).
|
||||||
|
* @param message C-style string error message.
|
||||||
|
* The string contents are copied upon construction.
|
||||||
|
* Hence, responsibility for deleting the char* lies
|
||||||
|
* with the caller.
|
||||||
|
*/
|
||||||
|
explicit ConfigLoadException(const char* message):
|
||||||
|
msg_(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constructor (C++ STL strings).
|
||||||
|
* @param message The error message.
|
||||||
|
*/
|
||||||
|
explicit ConfigLoadException(const std::string& message):
|
||||||
|
msg_(message)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/** Destructor.
|
||||||
|
* Virtual to allow for subclassing.
|
||||||
|
*/
|
||||||
|
virtual ~ConfigLoadException() throw (){}
|
||||||
|
|
||||||
|
/** Returns a pointer to the (constant) error description.
|
||||||
|
* @return A pointer to a const char*. The underlying memory
|
||||||
|
* is in posession of the Exception object. Callers must
|
||||||
|
* not attempt to free the memory.
|
||||||
|
*/
|
||||||
|
virtual const char* what() const throw (){
|
||||||
|
return msg_.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Error message.
|
||||||
|
*/
|
||||||
|
std::string msg_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// CONF_UNITSPATH_INVALID - Exception thrown when the Conf type can not load the supplied path for the Unit definition
|
|
||||||
/// files.
|
|
||||||
class CONF_UNITSPATH_INVALID: public std::runtime_error { public:
|
|
||||||
CONF_UNITSPATH_INVALID(): std::runtime_error("conf: The supplied path for the unit definition file is invalid.") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Conf::Conf - Constructor for Conf type. Loads the configuration for the application.
|
/// Conf::Conf - Constructor for Conf type. Loads the configuration for the application.
|
||||||
/// TODO Expand to detect when a directory path is supplied for units_path or plan_path and import all Tasks and Units.
|
/// TODO Expand to detect when a directory path is supplied for units_path or plan_path and import all Tasks and Units.
|
||||||
|
@ -37,18 +68,67 @@ class CONF_UNITSPATH_INVALID: public std::runtime_error { public:
|
||||||
/// \param filename - The filename to load the configuration from.
|
/// \param filename - The filename to load the configuration from.
|
||||||
Conf::Conf( std::string filename, bool verbose ): JSON_Loader()
|
Conf::Conf( std::string filename, bool verbose ): JSON_Loader()
|
||||||
{
|
{
|
||||||
|
// prepare context spaghetti
|
||||||
|
this->override_context = false;
|
||||||
|
|
||||||
// load the conf file.
|
// load the conf file.
|
||||||
this->load_json_file( filename, verbose );
|
this->load_json_file( filename, verbose );
|
||||||
|
|
||||||
|
if (this->get_serialized(this->config_version, "config_version" ,true) != 0)
|
||||||
|
{
|
||||||
|
throw ConfigLoadException("config_version string is not set in the config file supplied: " + filename);
|
||||||
|
}
|
||||||
|
if ( this->config_version.asString() != VERSION_STRING )
|
||||||
|
{
|
||||||
|
throw ConfigLoadException("config_version string expected was " + std::string(VERSION_STRING) + " in: " + filename);
|
||||||
|
}
|
||||||
|
|
||||||
// find the path to the plan file
|
// find the path to the plan file
|
||||||
if (this->get_serialized(this->plan_path, "plan_path", true) != 0 ) { throw CONF_PLANPATH_INVALID(); }
|
if (this->get_serialized(this->plan_path, "plan_path", true) != 0 )
|
||||||
|
{
|
||||||
|
throw ConfigLoadException("plan_path string is not set in the config file supplied:" + filename);
|
||||||
|
}
|
||||||
|
|
||||||
// find the path to the unit definitions file
|
// find the path to the unit definitions file
|
||||||
if (this->get_serialized(this->units_path, "units_path", true) != 0 ) { throw CONF_UNITSPATH_INVALID(); }
|
if (this->get_serialized(this->units_path, "units_path", true) != 0 )
|
||||||
|
{
|
||||||
|
throw ConfigLoadException("units_path string is not set in the config file supplied: " + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( this->get_serialized(this->override_execution_context, "execution_context_override", true) != 0 )
|
||||||
|
{
|
||||||
|
throw ConfigLoadException("execution_context_override boolean is not set in the config file supplied: " + filename);
|
||||||
|
} else {
|
||||||
|
this->override_context = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( this->get_serialized(this->execution_context, "execution_context", true) != 0 )
|
||||||
|
{
|
||||||
|
throw ConfigLoadException("execution_context string is not set in the config file supplied: " + filename);
|
||||||
|
} else {
|
||||||
|
this->execution_context_literal = this->execution_context.asString();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Conf::has_context_override - Specifies whether or not the override context function is enabled in the conf file.
|
||||||
|
bool Conf::has_context_override() {
|
||||||
|
return this->override_execution_context.asBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Conf::get_execution_context - Specifies the path to the current working directory to set for all unit executions.
|
||||||
|
std::string Conf::get_execution_context() {
|
||||||
|
return this->execution_context_literal;
|
||||||
|
}
|
||||||
|
|
||||||
/// Conf::get_plan_path - Retrieves the path to the Plan definition file from the application configuration file.
|
/// Conf::get_plan_path - Retrieves the path to the Plan definition file from the application configuration file.
|
||||||
std::string Conf::get_plan_path() { return this->plan_path.asString(); }
|
std::string Conf::get_plan_path() { return this->plan_path.asString(); }
|
||||||
|
|
||||||
|
|
||||||
/// Conf::get_units_path - Retrieves the path to the Unit definition file from the application configuration file.
|
/// Conf::get_units_path - Retrieves the path to the Unit definition file from the application configuration file.
|
||||||
std::string Conf::get_units_path() { return this->units_path.asString(); }
|
std::string Conf::get_units_path() { return this->units_path.asString(); }
|
||||||
|
|
||||||
|
/// Conf::set_execution_context- Sets the execution context.
|
||||||
|
void Conf::set_execution_context( std::string execution_context )
|
||||||
|
{
|
||||||
|
this->execution_context_literal = execution_context;
|
||||||
|
}
|
||||||
|
|
|
@ -21,17 +21,40 @@
|
||||||
#ifndef FTESTS_CONF_H
|
#ifndef FTESTS_CONF_H
|
||||||
#define FTESTS_CONF_H
|
#define FTESTS_CONF_H
|
||||||
#include "JSON_Loader.h"
|
#include "JSON_Loader.h"
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
|
||||||
|
#define STRINGIZE2(s) #s
|
||||||
|
#define STRINGIZE(s) STRINGIZE2(s)
|
||||||
|
# define IMPL_CONFIG_VERSION 2
|
||||||
|
# define VERSION_STRING STRINGIZE(IMPL_CONFIG_VERSION)
|
||||||
|
|
||||||
class Conf: public JSON_Loader
|
class Conf: public JSON_Loader
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Json::Value plan_path;
|
Json::Value plan_path;
|
||||||
Json::Value units_path;
|
Json::Value units_path;
|
||||||
|
Json::Value execution_context;
|
||||||
|
Json::Value config_version;
|
||||||
|
|
||||||
|
// flag to indicate if execution context should be overriden in config file
|
||||||
|
// if set to true Examplar should use whats in the config file for current working directory
|
||||||
|
// if set to false, Examplar should use the current working directory at time of execution
|
||||||
|
Json::Value override_execution_context;
|
||||||
|
|
||||||
|
bool override_context;
|
||||||
|
std::string execution_context_literal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Conf( std::string filename, bool verbose );
|
Conf( std::string filename, bool verbose );
|
||||||
std::string get_plan_path();
|
std::string get_plan_path();
|
||||||
std::string get_units_path();
|
std::string get_units_path();
|
||||||
|
|
||||||
|
bool has_context_override();
|
||||||
|
|
||||||
|
std::string get_execution_context();
|
||||||
|
void set_execution_context( std::string );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FTESTS_CONF_H
|
#endif //FTESTS_CONF_H
|
||||||
|
|
|
@ -120,7 +120,10 @@ protected:
|
||||||
/// Plan::Plan() - Constructor for Plan class. A Plan is a managed container for a Task vector. These tasks reference
|
/// Plan::Plan() - Constructor for Plan class. A Plan is a managed container for a Task vector. These tasks reference
|
||||||
/// Units that are defined in the Units files (Suite). If Units are definitions, Tasks are selections of those
|
/// Units that are defined in the Units files (Suite). If Units are definitions, Tasks are selections of those
|
||||||
/// definitions to execute, and if Units together form a Suite, Tasks together form a Plan.
|
/// definitions to execute, and if Units together form a Suite, Tasks together form a Plan.
|
||||||
Plan::Plan(): JSON_Loader() {};
|
Plan::Plan( Conf * configuration ): JSON_Loader()
|
||||||
|
{
|
||||||
|
this->configuration = configuration;
|
||||||
|
};
|
||||||
|
|
||||||
/// Plan::load_plan_file - Uses the json_root buffer on each run to append intact Units as they're deserialized from
|
/// Plan::load_plan_file - Uses the json_root buffer on each run to append intact Units as they're deserialized from
|
||||||
/// the provided file.
|
/// the provided file.
|
||||||
|
@ -259,7 +262,7 @@ void Plan::execute( bool verbose )
|
||||||
std::cout << "Executing task \"" << this->tasks[i].get_name() << "\"." << std::endl;
|
std::cout << "Executing task \"" << this->tasks[i].get_name() << "\"." << std::endl;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this->tasks[i].execute( verbose );
|
this->tasks[i].execute( this->configuration, verbose );
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
throw Plan_Task_GeneralExecutionException( "Plan Task: \"" + this->tasks[i].get_name() + "\" reported: " + e.what() );
|
throw Plan_Task_GeneralExecutionException( "Plan Task: \"" + this->tasks[i].get_name() + "\" reported: " + e.what() );
|
||||||
|
|
|
@ -25,15 +25,17 @@
|
||||||
#include "../json/json.h"
|
#include "../json/json.h"
|
||||||
#include "JSON_Loader.h"
|
#include "JSON_Loader.h"
|
||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
|
#include "Conf.h"
|
||||||
|
|
||||||
class Plan: public JSON_Loader
|
class Plan: public JSON_Loader
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// storage for the tasks that make up the plan
|
// storage for the tasks that make up the plan
|
||||||
std::vector<Task> tasks;
|
std::vector<Task> tasks;
|
||||||
|
Conf * configuration;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Plan();
|
Plan( Conf * configuration );
|
||||||
|
|
||||||
// append this->tasks from JSON file
|
// append this->tasks from JSON file
|
||||||
void load_plan_file( std::string filename, bool verbose );
|
void load_plan_file( std::string filename, bool verbose );
|
||||||
|
|
|
@ -19,10 +19,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include "../sproc/Sproc.h"
|
#include "../sproc/Sproc.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
/// Task_InvalidDataStructure - Exception thrown when a Task is defined with invalid JSON.
|
/// Task_InvalidDataStructure - Exception thrown when a Task is defined with invalid JSON.
|
||||||
class Task_InvalidDataStructure: public std::runtime_error {
|
class Task_InvalidDataStructure: public std::runtime_error {
|
||||||
|
@ -174,15 +174,10 @@ bool Task::has_definition()
|
||||||
return this->defined;
|
return this->defined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Task::execute - execute a task's unit definition.
|
/// Task::execute - execute a task's unit definition.
|
||||||
/// See the design document for what flow control needs to look like here.
|
/// See the design document for what flow control needs to look like here.
|
||||||
/// \param verbose - Verbosity level - not implemented yet.
|
/// \param verbose - Verbosity level - not implemented yet.
|
||||||
void Task::execute( bool verbose )
|
void Task::execute( Conf * configuration, bool verbose )
|
||||||
{
|
{
|
||||||
// DUFFING - If Examplar is broken it's probably going to be in this block.
|
// DUFFING - If Examplar is broken it's probably going to be in this block.
|
||||||
// Somebody come clean this up, eh?
|
// Somebody come clean this up, eh?
|
||||||
|
@ -199,18 +194,28 @@ void Task::execute( bool verbose )
|
||||||
std::string task_name = this->definition.get_name();
|
std::string task_name = this->definition.get_name();
|
||||||
// END PREWORK
|
// END PREWORK
|
||||||
|
|
||||||
|
|
||||||
// get the target execution command
|
// get the target execution command
|
||||||
std::string target_command = this->definition.get_target();
|
std::string target_command = this->definition.get_target();
|
||||||
|
|
||||||
// if we're in verbose mode, do some verbose things
|
// if we're in verbose mode, do some verbose things
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
{
|
{
|
||||||
|
|
||||||
infostring = std::ostringstream();
|
infostring = std::ostringstream();
|
||||||
infostring << "\tUsing unit \"" << task_name << "\"." << std::endl;
|
infostring << "\tUsing unit \"" << task_name << "\"." << std::endl;
|
||||||
syslog( LOG_INFO, infostring.str().c_str() );
|
syslog( LOG_INFO, infostring.str().c_str() );
|
||||||
std::cout << infostring.str();
|
std::cout << infostring.str();
|
||||||
|
|
||||||
|
// check if context override
|
||||||
|
if ( configuration->has_context_override() )
|
||||||
|
{
|
||||||
|
// if so, set the CWD.
|
||||||
|
chdir( configuration->get_execution_context().c_str() );
|
||||||
|
infostring = std::ostringstream();
|
||||||
|
infostring << "\tExecution context: " << get_working_path() << std::endl;
|
||||||
|
syslog(LOG_INFO, infostring.str().c_str() );
|
||||||
|
std::cout << infostring.str();
|
||||||
|
}
|
||||||
|
|
||||||
infostring = std::ostringstream();
|
infostring = std::ostringstream();
|
||||||
infostring << "\tExecuting target \"" << target_command << "\"." << std::endl;
|
infostring << "\tExecuting target \"" << target_command << "\"." << std::endl;
|
||||||
|
|
|
@ -21,9 +21,11 @@
|
||||||
#ifndef FTESTS_TASK_H
|
#ifndef FTESTS_TASK_H
|
||||||
#define FTESTS_TASK_H
|
#define FTESTS_TASK_H
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unistd.h>
|
||||||
#include "../json/json.h"
|
#include "../json/json.h"
|
||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
#include "Suite.h"
|
#include "Suite.h"
|
||||||
|
#include "Conf.h"
|
||||||
|
|
||||||
class Task
|
class Task
|
||||||
{
|
{
|
||||||
|
@ -62,7 +64,7 @@ class Task
|
||||||
std::string get_name();
|
std::string get_name();
|
||||||
|
|
||||||
// execute this task's definition
|
// execute this task's definition
|
||||||
void execute( bool verbose );
|
void execute( Conf * configuration, bool verbose );
|
||||||
|
|
||||||
void mark_complete();
|
void mark_complete();
|
||||||
|
|
||||||
|
|
|
@ -24,4 +24,10 @@ bool exists(const std::string& name)
|
||||||
{
|
{
|
||||||
struct stat buffer;
|
struct stat buffer;
|
||||||
return (stat (name.c_str(), &buffer) == 0);
|
return (stat (name.c_str(), &buffer) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_working_path()
|
||||||
|
{
|
||||||
|
char temp[MAXPATHLEN];
|
||||||
|
return ( getcwd(temp, MAXPATHLEN) ? std::string( temp ) : std::string("") );
|
||||||
}
|
}
|
|
@ -22,9 +22,12 @@
|
||||||
#define FTESTS_HELPERS_H
|
#define FTESTS_HELPERS_H
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
bool exists (const std::string& name);
|
bool exists (const std::string& name);
|
||||||
|
|
||||||
|
std::string get_working_path();
|
||||||
|
|
||||||
#endif //FTESTS_HELPERS_H
|
#endif //FTESTS_HELPERS_H
|
||||||
|
|
Loading…
Reference in New Issue