Merge pull request #1 from Thraix/cli

Add config cli
This commit is contained in:
Tim Håkansson
2019-10-10 22:02:45 +02:00
committed by GitHub
8 changed files with 438 additions and 38 deletions
+11 -8
View File
@@ -1,4 +1,4 @@
# This Makefile was generated using MakeGen v1.1.7 made by Tim Håkansson
# This Makefile was generated using MakeGen v1.1.8 made by Tim Håkansson
# and is licensed under MIT. Full source of the project can be found at
# https://github.com/Thraix/MakeGen
CC=@g++
@@ -7,7 +7,7 @@ MKDIR_P=mkdir -p
BIN=bin/
OBJPATH=$(BIN)intermediates
INCLUDES=
OBJECTS=$(OBJPATH)/ConfigFile.o $(OBJPATH)/HFileGen.o $(OBJPATH)/IncludeDeps.o $(OBJPATH)/Makefile.o $(OBJPATH)/Utils.o $(OBJPATH)/main.o
OBJECTS=$(OBJPATH)/ConfigCLI.o $(OBJPATH)/ConfigFile.o $(OBJPATH)/HFileGen.o $(OBJPATH)/IncludeDeps.o $(OBJPATH)/Makefile.o $(OBJPATH)/Utils.o $(OBJPATH)/main.o
CFLAGS=$(INCLUDES) -std=c++17 -c -w -g3 -D_DEBUG
LIBDIR=
LDFLAGS=
@@ -33,21 +33,24 @@ $(OUTPUT): $(OBJECTS)
install: all
$(info Installing MakeGen to /usr/bin/)
@cp $(OUTPUT) /usr/bin/makegen
$(OBJPATH)/ConfigCLI.o : src/ConfigCLI.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h
$(info -[14%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/ConfigFile.o : src/ConfigFile.cpp src/ConfigFile.h src/FileUtils.h src/Common.h src/Utils.h
$(info -[16%]- $<)
$(info -[28%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/HFileGen.o : src/HFileGen.cpp src/FileUtils.h src/Common.h src/Utils.h src/ConfigFile.h src/HFileGen.h
$(info -[33%]- $<)
$(info -[42%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/IncludeDeps.o : src/IncludeDeps.cpp src/Common.h src/IncludeDeps.h src/ConfigFile.h src/FileUtils.h src/Utils.h
$(info -[50%]- $<)
$(info -[57%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/Makefile.o : src/Makefile.cpp src/IncludeDeps.h src/ConfigFile.h src/FileUtils.h src/Common.h src/Utils.h src/Makefile.h
$(info -[66%]- $<)
$(info -[71%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/Utils.o : src/Utils.cpp src/FileUtils.h src/Common.h src/Utils.h src/ConfigFile.h
$(info -[83%]- $<)
$(info -[85%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/main.o : src/main.cpp src/Common.h src/ConfigFile.h src/FileUtils.h src/Utils.h src/HFileGen.h src/Makefile.h src/Timer.h
$(OBJPATH)/main.o : src/main.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h src/FileUtils.h src/Utils.h src/HFileGen.h src/Makefile.h src/Timer.h
$(info -[100%]- $<)
$(CC) $(CFLAGS) -o $@ $<
+9 -2
View File
@@ -29,13 +29,20 @@ This will install MakeGen into `/usr/bin/makegen`.
If you want it to be installed in another place just run `make` and copy the file to where you want it.
## Usage
### Config file
In order to create a MakeGen configuration file use the following command:
makegen --conf
makegen conf gen prompt
This will prompt you with all the needed configurations in order to create a Makefile which will compile your code.
When this is done it will create a file called `makegen.conf` which contains all relevant data for MakeGen to create a Makefile.
If you want to change your config you can modify the makegen.conf file or use makegens config command line interface.
To see the possible changes you can do see the help file by entering:
makegen conf
### Compiling
After that simply compile your code with:
makegen
@@ -52,4 +59,4 @@ If multiple options are given to MakeGen it will execute them in the following o
clean all install run
Since MakeGen generates include dependencies in your Makefile it can cause the Makefile to get very cluttered.
In order to make it less cluttered you can run `makegen --simple` which will generate (and run) a Makefile without header file dependencies.
In order to make it less cluttered you can run `makegen --simple` which will generate (and run) a Makefile without header file dependencies.
+6 -5
View File
@@ -1,18 +1,19 @@
#libs
#libdirs
#includedirs
#srcdir
src
#defines
_DEBUG
#compileflags
#dependencies
#srcdir
src/
#outputdir
bin
bin/
#projectname
MakeGen
#outputname
makegen
#executable
true
#dependencies
#generatehfile
false
+11 -11
View File
@@ -12,20 +12,20 @@
// Release , should be backwards compatible with any minor version
#define MAKEGEN_VERSION_RELEASE 1
// Minor changes, should be compatible with any other minor version with same major and release.
#define MAKEGEN_VERSION_MINOR 7
#define MAKEGEN_VERSION_MINOR 8
#define MAKEGEN_VERSION ("v" STR(MAKEGEN_VERSION_MAJOR) "." STR(MAKEGEN_VERSION_RELEASE) "." STR(MAKEGEN_VERSION_MINOR))
const static unsigned int FLAG_HELP = BIT(0);
const static unsigned int FLAG_GEN = BIT(1);
const static unsigned int FLAG_VERSION = BIT(2);
const static unsigned int FLAG_CLEAN = BIT(3);
const static unsigned int FLAG_MAKE = BIT(4);
const static unsigned int FLAG_RUN = BIT(5);
const static unsigned int FLAG_INSTALL = BIT(6);
const static unsigned int FLAG_REBUILD = BIT(7);
const static unsigned int FLAG_SINGLE_THREAD = BIT(8);
const static unsigned int FLAG_DEPENDENCY = BIT(9);
const static unsigned int FLAG_SIMPLE = BIT(10);
const static unsigned int FLAG_VERSION = BIT(1);
const static unsigned int FLAG_CLEAN = BIT(2);
const static unsigned int FLAG_MAKE = BIT(3);
const static unsigned int FLAG_RUN = BIT(4);
const static unsigned int FLAG_INSTALL = BIT(5);
const static unsigned int FLAG_REBUILD = BIT(6);
const static unsigned int FLAG_SINGLE_THREAD = BIT(7);
const static unsigned int FLAG_DEPENDENCY = BIT(8);
const static unsigned int FLAG_SIMPLE = BIT(9);
const static unsigned int FLAG_CONFIG = BIT(10);
#define LOG_INFO(...) Log(__VA_ARGS__); std::cout << std::endl
+367
View File
@@ -0,0 +1,367 @@
#include "ConfigCLI.h"
#include "Common.h"
#include "ConfigFile.h"
#include <set>
void ConfigCLI::DisplayCLIHelp()
{
LOG_INFO("MakeGen conf is used to create, modify and query the makegen.conf file.");
LOG_INFO("");
LOG_INFO("Usage: makegen conf <command> [<args>] [--help] ");
LOG_INFO("");
LOG_INFO("Generating config files");
LOG_INFO(" gen Prompt the user to enter information to create config");
LOG_INFO("");
LOG_INFO("Modifying config settings");
LOG_INFO(" add Add values to config settings which support multiple arguments");
LOG_INFO(" remove Remove values to config settings which support multiple");
LOG_INFO(" arguments");
LOG_INFO(" set Set value to config settings which support only one argument");
LOG_INFO("");
LOG_INFO("Querying config settings");
LOG_INFO(" get Get value of the config setting");
}
void ConfigCLI::DisplayGenHelp()
{
LOG_INFO("Generate a config file from prompts");
LOG_INFO("");
LOG_INFO("Usage: makegen conf gen <option>");
LOG_INFO("");
LOG_INFO("options:");
LOG_INFO(" prompt Prompt the user for all needed settings");
}
void ConfigCLI::DisplayAddHelp()
{
LOG_INFO("Add values to config settings which support multiple arguments");
LOG_INFO("");
LOG_INFO("Usage: makegen conf add <setting> <value> [<values>]");
LOG_INFO("");
LOG_INFO("Valid settings are:");
LOG_INFO(" library Library");
LOG_INFO(" libdir Library directory");
LOG_INFO(" includedir Include directory");
LOG_INFO(" define Preprocessor define");
LOG_INFO(" cflag g++ compiler flags");
LOG_INFO(" dependency Project which current project depends on");
}
void ConfigCLI::DisplayRemoveHelp()
{
LOG_INFO("Remove values to config settings which support multiple arguments");
LOG_INFO("");
LOG_INFO("Usage: makegen conf remove <setting> <value> [<values>]");
LOG_INFO("");
LOG_INFO("Valid settings are:");
LOG_INFO(" library Library name");
LOG_INFO(" libdir Library directory");
LOG_INFO(" includedir Include directory");
LOG_INFO(" define Preprocessor define");
LOG_INFO(" cflag g++ compiler flags");
LOG_INFO(" dependency Project which current project depends on");
}
void ConfigCLI::DisplaySetHelp()
{
LOG_INFO("Set value to config settings which only support one argument");
LOG_INFO("");
LOG_INFO("Usage: makegen conf set <setting> <value>");
LOG_INFO("");
LOG_INFO("Valid string settings are:");
LOG_INFO(" outputdir Directory of the compiled output");
LOG_INFO(" output Name of the output executable/library");
LOG_INFO(" name Name of the project");
LOG_INFO(" hfile Name of the generated project h-file");
LOG_INFO("");
LOG_INFO("Valid boolean settings are:");
LOG_INFO(" executable Specifies if the project be compiled as executable or library");
LOG_INFO(" shared Specifies if the library should be compiled as shared.");
LOG_INFO(" genhfile Specifies if MakeGen should generate a project h-file");
LOG_INFO("");
LOG_INFO("Boolean values can be set to either true/t/yes/y or false/f/no/n");
}
void ConfigCLI::DisplayGetHelp()
{
LOG_INFO("Get value of the config setting");
LOG_INFO("");
LOG_INFO("Usage: makegen conf get <setting>");
LOG_INFO("");
LOG_INFO("Valid settings are:");
LOG_INFO(" library Library name");
LOG_INFO(" libdir Library directory");
LOG_INFO(" includedir Include directory");
LOG_INFO(" define Preprocessor define");
LOG_INFO(" cflag g++ compiler flags");
LOG_INFO(" dependency Project which current project depends on");
LOG_INFO(" outputdir Directory of the compiled output");
LOG_INFO(" output Name of the output executable/library");
LOG_INFO(" name Name of the project");
LOG_INFO(" hfile Name of the generated project h-file");
LOG_INFO(" executable Specifies if the project be compiled as executable or library");
LOG_INFO(" shared Specifies if the library should be compiled as shared.");
LOG_INFO(" genhfile Specifies if MakeGen should generate a project h-file");
}
std::map<std::string, std::vector<std::string>*> ConfigCLI::GetSettingVectorMap(ConfigFile& config)
{
return {
{"library",&config.libs},
{"libdir",&config.libdirs},
{"includedir",&config.includedirs},
{"define",&config.defines},
{"cflag",&config.flags},
{"dependency",&config.dependencies}
};
}
std::map<std::string, std::string*> ConfigCLI::GetSettingStringMap(ConfigFile& config)
{
return {
{"outputdir", &config.outputdir},
{"output", &config.outputname},
{"name", &config.projectname},
{"hfile", &config.hFile},
};
}
std::map<std::string, bool*> ConfigCLI::GetSettingBoolMap(ConfigFile& config)
{
return {
{"executable", &config.executable},
{"shared", &config.shared},
{"genhfile", &config.generateHFile}
};
}
int ConfigCLI::Gen(int argc, char** argv)
{
if(argc < 2 || std::string(argv[1]) == "--help")
{
DisplayGenHelp();
return 0;
}
if(argc < 2)
{
LOG_ERROR("gen needs exactly one parameter");
return 1;
}
std::string option = argv[1];
if(option == "prompt")
{
ConfigFile::Gen().Save();
return 0;
}
else
{
LOG_ERROR("Invalid option: ", option);
return 1;
}
}
int ConfigCLI::Add(int argc, char** argv, ConfigFile& config)
{
if(argc < 2 || std::string(argv[1]) == "--help")
{
DisplayAddHelp();
return 0;
}
if(argc < 3)
{
LOG_ERROR("add needs at least two parameters");
return 1;
}
auto settingMap = GetSettingVectorMap(config);
auto it = settingMap.find(argv[1]);
if(it == settingMap.end())
{
LOG_ERROR("Invalid setting: ", argv[1]);
return 1;
}
std::vector<std::string>* setting = it->second;
std::set<std::string> settingSet{setting->begin(), setting->end()};
for(int i = 2; i<argc;++i)
{
auto res = settingSet.emplace(argv[i]);
if(!res.second)
{
LOG_ERROR("Duplicate value: ", argv[i]);
}
}
*setting = {settingSet.begin(), settingSet.end()};
config.Save();
return 0;
}
int ConfigCLI::Remove(int argc, char** argv, ConfigFile& config)
{
if(argc < 2 || std::string(argv[1]) == "--help")
{
DisplayRemoveHelp();
return 0;
}
if(argc < 3)
{
LOG_ERROR("remove needs at least two parameters");
return 1;
}
auto settingMap = GetSettingVectorMap(config);
auto it = settingMap.find(argv[1]);
if(it == settingMap.end())
{
LOG_ERROR("Invalid setting: ", argv[1]);
return 1;
}
std::vector<std::string>* setting = it->second;
std::set<std::string> settingSet{setting->begin(), setting->end()};
for(int i = 2; i<argc;++i)
{
auto it = settingSet.find(argv[i]);
if(it == settingSet.end())
{
LOG_ERROR("No such value in setting: ", argv[i]);
}
else
settingSet.erase(it);
}
*setting = {settingSet.begin(), settingSet.end()};
config.Save();
return 0;
}
int ConfigCLI::Set(int argc, char** argv, ConfigFile& config)
{
if(argc < 2 || std::string(argv[1]) == "--help")
{
DisplaySetHelp();
return 0;
}
if(argc != 3)
{
LOG_ERROR("set needs exactly two parameters");
return 1;
}
auto settingStringMap = GetSettingStringMap(config);
auto it1 = settingStringMap.find(argv[1]);
if(it1 == settingStringMap.end())
{
auto settingBoolMap = GetSettingBoolMap(config);
auto it2 = settingBoolMap.find(argv[1]);
if(it2 == settingBoolMap.end())
{
LOG_ERROR("Invalid setting: ", argv[1]);
return 1;
}
std::string b = argv[2];
if(b == "true" || b == "t" || b == "yes" || b == "y")
*(it2->second) = true;
else if(b == "false" || b == "f" || b == "no" || b == "n")
*it2->second = false;
else
{
LOG_ERROR("Invalid boolean value: ", argv[2]);
return 1;
}
config.Save();
return 0;
}
*it1->second = argv[2];
config.Save();
return 0;
}
int ConfigCLI::Get(int argc, char** argv, ConfigFile& config)
{
if(argc < 2 || std::string(argv[1]) == "--help")
{
DisplayGetHelp();
return 0;
}
if(argc != 2)
{
LOG_ERROR("get needs exactly one parameter");
return 1;
}
auto settingVectorMap = GetSettingVectorMap(config);
auto itV = settingVectorMap.find(argv[1]);
if(itV == settingVectorMap.end())
{
auto settingStringMap = GetSettingStringMap(config);
auto itS = settingStringMap.find(argv[1]);
if(itS == settingStringMap.end())
{
auto settingBoolMap = GetSettingBoolMap(config);
auto itB = settingBoolMap.find(argv[1]);
if(itB == settingBoolMap.end())
{
LOG_ERROR("Invalid setting: ", argv[1]);
return 1;
}
bool* t = itB->second;
LOG_INFO(*itB->second ? "true" : "false");
return 0;
}
LOG_INFO(*itS->second);
return 0;
}
for(auto it = itV->second->begin(); it != itV->second->end(); ++it)
{
LOG_INFO(*it);
}
return 0;
}
int ConfigCLI::Main(int argc, char** argv)
{
// Do nothing
if(argc < 2 || std::string(argv[1]) == "--help")
{
DisplayCLIHelp();
return 0;
}
std::optional<ConfigFile> config = ConfigFile::GetConfigFile();
std::string command = argv[1];
if(command == "gen")
{
if(config)
{
LOG_ERROR("Config file already exist (makegen.conf)");
return 1;
}
return Gen(argc-1, &argv[1]);
}
else if(config)
{
if(command == "add")
return Add(argc-1, &argv[1], *config);
else if(command == "remove")
return Remove(argc-1, &argv[1], *config);
else if(command == "set")
return Set(argc-1, &argv[1], *config);
else if(command == "get")
return Get(argc-1, &argv[1], *config);
else
{
LOG_ERROR("Unknown config command: ", command);
return 1;
}
}
else
{
LOG_ERROR("There is no config file in the current directory");
return 1;
}
}
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include "ConfigFile.h"
struct ConfigCLI
{
public:
static int Main(int argc, char** argv);
private:
static void DisplayCLIHelp();
static void DisplayGenHelp();
static void DisplayAddHelp();
static void DisplayRemoveHelp();
static void DisplaySetHelp();
static void DisplayGetHelp();
static std::map<std::string, std::vector<std::string>*> GetSettingVectorMap(ConfigFile& config);
static std::map<std::string, std::string*> GetSettingStringMap(ConfigFile& config);
static std::map<std::string, bool*> GetSettingBoolMap(ConfigFile& config);
static int Gen(int argc, char** argv);
static int Add(int argc, char** argv, ConfigFile& config);
static int Remove(int argc, char** argv, ConfigFile& config);
static int Set(int argc, char** argv, ConfigFile& config);
static int Get(int argc, char** argv, ConfigFile& config);
};
+2 -2
View File
@@ -234,10 +234,10 @@ ConfigFile ConfigFile::Gen()
else
{
InputBoolean("Should it be compiled as a shared library? (y/n)", conf.shared);
InputBoolean("Should it compile a single h file? (y/n):", conf.generateHFile);
InputBoolean("Should it compile a project h-file? (y/n):", conf.generateHFile);
if(conf.generateHFile)
{
InputString("Enter the h file name (and path): ", conf.hFile, false, false);
InputString("Enter the project h-file name (relative to source directory): ", conf.hFile, false, false);
}
}
InputMultiple("Enter include directory:", conf.includedirs, true);
+5 -10
View File
@@ -1,4 +1,5 @@
#include "Common.h"
#include "ConfigCLI.h"
#include "ConfigFile.h"
#include "FileUtils.h"
#include "HFileGen.h"
@@ -22,8 +23,6 @@ void PrintHelp()
LOG_INFO("");
LOG_INFO(" Options:");
LOG_INFO(" -h, --help Displays this information");
LOG_INFO(" --conf Prompt the user to enter information to create config");
LOG_INFO(" file");
LOG_INFO(" -v, --version Displays the version of this program");
LOG_INFO(" -m,-a, make, all Generates a Makefile and runs");
LOG_INFO(" make all");
@@ -55,6 +54,8 @@ void GenMakefile(const ConfigFile& conf, unsigned int flags)
unsigned int ReadFlags(int argc, char** argv)
{
if(argc >= 2 && std::string(argv[1]) == "conf")
return FLAG_CONFIG;
unsigned int flags = 0;
bool make = true;
for(int i = 1;i<argc;i++)
@@ -66,10 +67,6 @@ unsigned int ReadFlags(int argc, char** argv)
{
flags |= FLAG_HELP;
}
else if(flag == "--conf")
{
flags |= FLAG_GEN;
}
else if(flag == "-v" || flag == "--version")
{
flags |= FLAG_VERSION;
@@ -177,10 +174,9 @@ int main(int argc, char** argv)
LOG_INFO("MakeGen ",MAKEGEN_VERSION);
return 0;
}
if(flags & FLAG_GEN)
if(flags & FLAG_CONFIG)
{
ConfigFile::Gen().Save();
return 0;
return ConfigCLI::Main(argc-1, &argv[1]);
}
std::map<std::string, ConfigFile> files{};
auto conf = ConfigFile::GetConfigFile();
@@ -192,6 +188,5 @@ int main(int argc, char** argv)
else
{
LOG_ERROR("No ", CONFIG_FILENAME, " or Makefile found.");
PrintHelp();
}
}