From 8b052110d8802eda3d4d76700bde8ecc80dbf79a Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 3 Jan 2018 21:17:49 +0100 Subject: Add "sibs test" command. Tests are only run when that command is invoked --- src/main.cpp | 208 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 135 insertions(+), 73 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index e2df0fe..f16bf64 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -56,6 +56,7 @@ void usage() printf("Commands:\n"); printf(" build\t\tBuild a project that contains a project.conf file\n"); printf(" new\t\tCreate a new project\n"); + printf(" test\t\tBuild and run tests for a sibs project\n"); exit(1); } @@ -88,6 +89,18 @@ void usageNew() exit(1); } +void usageTest() +{ + printf("Usage: sibs test [project_path]\n\n"); + printf("Build and run tests for a sibs project\n\n"); + printf("Options:\n"); + printf(" project_path\t\t The directory containing a project.conf file - Optional (default: current working directory)\n"); + printf("Examples:\n"); + printf(" sibs test\n"); + printf(" sibs test dirA/dirB\n"); + exit(1); +} + void validateDirectoryPath(const _tinydir_char_t *projectPath) { FileType projectPathFileType = getFileType(projectPath); @@ -142,78 +155,8 @@ bool isPathSubPathOf(const FileString &path, const FileString &subPathOf) return _tinydir_strncmp(path.c_str(), subPathOf.c_str(), subPathOf.size()) == 0; } -int buildProject(int argc, const _tinydir_char_t **argv) +int buildProject(const FileString &projectPath, const FileString &projectConfFilePath, const SibsConfig &sibsConfig) { - if(argc > 2) - usageBuild(); - - OptimizationLevel optimizationLevel = OPT_LEV_NONE; - FileString projectPath; - - for(int i = 0; i < argc; ++i) - { - const _tinydir_char_t *arg = argv[i]; - if(_tinydir_strcmp(arg, TINYDIR_STRING("--debug")) == 0) - { - if(optimizationLevel != OPT_LEV_NONE) - { - ferr << "Error: Optimization level defined more than once. First defined as " << asString(optimizationLevel) << " then as debug" << endl; - usageBuild(); - } - optimizationLevel = OPT_LEV_DEBUG; - } - else if(_tinydir_strcmp(arg, TINYDIR_STRING("--release")) == 0) - { - if(optimizationLevel != OPT_LEV_NONE) - { - ferr << "Error: Optimization level defined more than once. First defined as " << asString(optimizationLevel) << " then as release" << endl; - usageBuild(); - } - optimizationLevel = OPT_LEV_RELEASE; - } - else - { - if(!projectPath.empty()) - { - ferr << "Error: Project path was defined more than once. First defined as " << projectPath << " then as " << arg << endl; - usageBuild(); - } - projectPath = arg; - } - } - - if(optimizationLevel == OPT_LEV_NONE) - optimizationLevel = OPT_LEV_DEBUG; - - // TODO: If projectPath is not defined and working directory does not contain project.conf, then search every parent directory until one is found - if(projectPath.empty()) - projectPath = TINYDIR_STRING("."); - - validateDirectoryPath(projectPath.c_str()); - if(projectPath.back() != '/') - projectPath += TINYDIR_STRING("/"); - - Result projectRealPathResult = getRealPath(projectPath.c_str()); - if(!projectRealPathResult) - { - ferr << "Failed to get real path for: '" << projectPath.c_str() << "': " << toFileString(projectRealPathResult.getErrMsg()) << endl; - exit(40); - } - projectPath = projectRealPathResult.unwrap(); - - FileString projectConfFilePath = projectPath; - projectConfFilePath += TINYDIR_STRING("/project.conf"); - validateFilePath(projectConfFilePath.c_str()); - - // TODO: Detect compiler to use at runtime. Should also be configurable - // by passing argument to `sibs build` -#if OS_FAMILY == OS_FAMILY_POSIX - Compiler compiler = Compiler::GCC; -#else - Compiler compiler = Compiler::MSVC; -#endif - - SibsConfig sibsConfig(compiler, projectPath, optimizationLevel); Result result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig); if(result.isErr()) { @@ -285,7 +228,6 @@ int buildProject(int argc, const _tinydir_char_t **argv) } else { - // TODO: If compiling without "test" option, do not add test source dir to ninja. Ninja logic will then not build tests if (!sibsConfig.getTestPath().empty() && isPathSubPathOf(pathNative.c_str(), sibsConfig.getTestPath())) { string filePathUtf8 = toUtf8(pathNative.c_str()); @@ -305,11 +247,127 @@ int buildProject(int argc, const _tinydir_char_t **argv) } } auto elapsedTime = duration_cast>(high_resolution_clock::now() - startTime); - printf("Build finished in %fs\n", elapsedTime.count()); + printf("Finished in %fs\n", elapsedTime.count()); return 0; } +int buildProject(int argc, const _tinydir_char_t **argv) +{ + if(argc > 2) + usageBuild(); + + OptimizationLevel optimizationLevel = OPT_LEV_NONE; + FileString projectPath; + + for(int i = 0; i < argc; ++i) + { + const _tinydir_char_t *arg = argv[i]; + if(_tinydir_strcmp(arg, TINYDIR_STRING("--debug")) == 0) + { + if(optimizationLevel != OPT_LEV_NONE) + { + ferr << "Error: Optimization level defined more than once. First defined as " << asString(optimizationLevel) << " then as debug" << endl; + usageBuild(); + } + optimizationLevel = OPT_LEV_DEBUG; + } + else if(_tinydir_strcmp(arg, TINYDIR_STRING("--release")) == 0) + { + if(optimizationLevel != OPT_LEV_NONE) + { + ferr << "Error: Optimization level defined more than once. First defined as " << asString(optimizationLevel) << " then as release" << endl; + usageBuild(); + } + optimizationLevel = OPT_LEV_RELEASE; + } + else + { + if(!projectPath.empty()) + { + ferr << "Error: Project path was defined more than once. First defined as " << projectPath << " then as " << arg << endl; + usageBuild(); + } + projectPath = arg; + } + } + + if(optimizationLevel == OPT_LEV_NONE) + optimizationLevel = OPT_LEV_DEBUG; + + // TODO: If projectPath is not defined and working directory does not contain project.conf, then search every parent directory until one is found + if(projectPath.empty()) + projectPath = TINYDIR_STRING("."); + + validateDirectoryPath(projectPath.c_str()); + if(projectPath.back() != '/') + projectPath += TINYDIR_STRING("/"); + + Result projectRealPathResult = getRealPath(projectPath.c_str()); + if(!projectRealPathResult) + { + ferr << "Failed to get real path for: '" << projectPath.c_str() << "': " << toFileString(projectRealPathResult.getErrMsg()) << endl; + exit(40); + } + projectPath = projectRealPathResult.unwrap(); + + FileString projectConfFilePath = projectPath; + projectConfFilePath += TINYDIR_STRING("/project.conf"); + validateFilePath(projectConfFilePath.c_str()); + + // TODO: Detect compiler to use at runtime. Should also be configurable + // by passing argument to `sibs build` +#if OS_FAMILY == OS_FAMILY_POSIX + Compiler compiler = Compiler::GCC; +#else + Compiler compiler = Compiler::MSVC; +#endif + + SibsConfig sibsConfig(compiler, projectPath, optimizationLevel, false); + return buildProject(projectPath, projectConfFilePath, sibsConfig); +} + +int testProject(int argc, const _tinydir_char_t **argv) +{ + if(argc > 1) + usageTest(); + + FileString projectPath; + if(argc == 1) + projectPath = argv[0]; + + // TODO: If projectPath is not defined and working directory does not contain project.conf, then search every parent directory until one is found + if(projectPath.empty()) + projectPath = TINYDIR_STRING("."); + + validateDirectoryPath(projectPath.c_str()); + if(projectPath.back() != '/') + projectPath += TINYDIR_STRING("/"); + + Result projectRealPathResult = getRealPath(projectPath.c_str()); + if(!projectRealPathResult) + { + ferr << "Failed to get real path for: '" << projectPath.c_str() << "': " << toFileString(projectRealPathResult.getErrMsg()) << endl; + exit(40); + } + projectPath = projectRealPathResult.unwrap(); + + FileString projectConfFilePath = projectPath; + projectConfFilePath += TINYDIR_STRING("/project.conf"); + validateFilePath(projectConfFilePath.c_str()); + + // TODO: Detect compiler to use at runtime. Should also be configurable + // by passing argument to `sibs build` +#if OS_FAMILY == OS_FAMILY_POSIX + Compiler compiler = Compiler::GCC; +#else + Compiler compiler = Compiler::MSVC; +#endif + + SibsConfig sibsConfig(compiler, projectPath, OPT_LEV_DEBUG, true); + return buildProject(projectPath, projectConfFilePath, sibsConfig); +} + void newProjectCreateMainDir(const FileString &projectPath) { Result createProjectDirResult = createDirectoryRecursive(projectPath.c_str()); @@ -451,6 +509,10 @@ int wmain(int argc, const _tinydir_char_t **argv) { return newProject(subCommandArgCount, subCommandArgPtr); } + else if(_tinydir_strcmp(arg, TINYDIR_STRING("test")) == 0) + { + return testProject(subCommandArgCount, subCommandArgPtr); + } else { ferr << "Expected command to be either 'build' or 'new', was: " << arg << endl << endl; -- cgit v1.2.3