aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Conf.cpp6
-rw-r--r--src/main.cpp94
2 files changed, 90 insertions, 10 deletions
diff --git a/src/Conf.cpp b/src/Conf.cpp
index 6a8de19..695bc9e 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -508,12 +508,6 @@ namespace sibs
buildPath += TINYDIR_STRING("release");
break;
}
-
- if(sibsConfig.shouldBuildTests() && sibsConfig.getTestPath().empty())
- {
- printf("Project is missing package.tests config. No tests to build\n");
- exit(0);
- }
}
const char* asString(Platform platform)
diff --git a/src/main.cpp b/src/main.cpp
index d8ce41c..6c9df97 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -93,6 +93,8 @@ using namespace std::chrono;
// TODO: Make Process::exec safe to use. Currently you pass an argument and it's run as a command, but the string can be escaped to perform malicious acts.
// Process::exec should be modified to take a list of arguments to execute command with.
+// TODO: Verify paths (test path, ignore dirs, include dirs, expose include dir, sibs test --file dir) are sub directory of the project
+
#if OS_FAMILY == OS_FAMILY_POSIX
#define fout std::cout
#define ferr std::cerr
@@ -139,7 +141,7 @@ void usageBuild()
void usageNew()
{
- printf("Usage: sibs new <project_name> <--exec|--static|--dynamic> <--lang [c|c++|zig]>\n\n");
+ printf("Usage: sibs new <project_name> <--exec|--static|--dynamic> [--lang c|c++|zig]\n\n");
printf("Create a new sibs project\n\n");
printf("Options:\n");
printf(" project_name\t\tThe name of the project you want to create\n");
@@ -154,11 +156,13 @@ void usageNew()
void usageTest()
{
- printf("Usage: sibs test [project_path] [--no-sanitize]\n\n");
+ printf("Usage: sibs test [project_path] [--no-sanitize] [--file filepath...|--all-files]\n\n");
printf("Build and run tests for a sibs project\n\n");
printf("Options:\n");
printf(" project_path\t\tThe directory containing a project.conf file - Optional (default: current directory)\n");
- printf(" --no-sanitize\t\tDisable runtime address/undefined behavior - Optional\n");
+ printf(" --no-sanitize\t\tDisable runtime address/undefined behavior - Optional (default: enabled), Only applicable for C and C++\n");
+ printf(" --file\t\t\tSpecify file to test, path to test file should be defined after this. Can be defined multiple times to test multiple files - Optional (default: not used), Only applicable for Zig\n");
+ printf(" --all-files\t\t\tTest all files - Optional (default: not used), Only applicable for Zig\n");
printf("Examples:\n");
printf(" sibs test\n");
printf(" sibs test dirA/dirB\n");
@@ -167,7 +171,7 @@ void usageTest()
void usageInit()
{
- printf("Usage: sibs init [project_path] <--exec|--static|--dynamic> <--lang [c|c++|zig]>\n\n");
+ printf("Usage: sibs init [project_path] <--exec|--static|--dynamic> [--lang c|c++|zig]\n\n");
printf("Create sibs project structure in an existing directory\n\n");
printf("Options:\n");
printf(" project_path\t\tThe directory where you want to initialize sibs project - Optional (default: current directory)\n");
@@ -390,6 +394,8 @@ int testProject(int argc, const _tinydir_char_t **argv)
usageTest();
FileString projectPath;
+ vector<FileString> filesToTest;
+ bool testAllFiles = false;
bool sanitize = true;
for(int i = 0; i < argc; ++i)
@@ -399,6 +405,39 @@ int testProject(int argc, const _tinydir_char_t **argv)
{
sanitize = false;
}
+ else if(_tinydir_strcmp(arg, TINYDIR_STRING("--file")) == 0)
+ {
+ if(i == argc - 1)
+ {
+ ferr << "Error: Expected path to file to test after --file " << endl;
+ usageTest();
+ }
+
+ ++i;
+ arg = argv[i];
+ filesToTest.push_back(arg);
+
+ if(testAllFiles)
+ {
+ ferr << "Error: --file can't be used together with --all-files " << endl;
+ usageTest();
+ }
+ }
+ else if(_tinydir_strcmp(arg, TINYDIR_STRING("--all-files")) == 0)
+ {
+ if(testAllFiles)
+ {
+ ferr << "Error: --all-files defined twice " << endl;
+ usageTest();
+ }
+ testAllFiles = true;
+
+ if(!filesToTest.empty())
+ {
+ ferr << "Error: --all-files can't be used together with --file " << endl;
+ usageTest();
+ }
+ }
else if(_tinydir_strncmp(arg, TINYDIR_STRING("--"), 2) == 0)
{
ferr << "Error: Invalid argument " << arg << endl;
@@ -431,6 +470,44 @@ int testProject(int argc, const _tinydir_char_t **argv)
}
projectPath = projectRealPathResult.unwrap();
+ for(const FileString &testFile : filesToTest)
+ {
+ if(testFile.empty())
+ {
+ ferr << "Error: Test filepath can't be empty" << endl;
+ exit(20);
+ }
+
+ FileType fileType = getFileType(testFile.c_str());
+ switch(fileType)
+ {
+ case FileType::FILE_NOT_FOUND:
+ {
+ ferr << "Error: Test file not found: " << testFile << endl;
+ exit(20);
+ break;
+ }
+ case FileType::DIRECTORY:
+ {
+ ferr << "Error: Test file " << testFile << " is a directory, expected to be a file" << endl;
+ exit(20);
+ break;
+ }
+ case FileType::REGULAR:
+ {
+ // TODO: This can be optimized, there is no need to create a copy to check file extension
+ FileString fileExtension = backend::BackendUtils::getFileExtension(testFile);
+ sibs::Language fileLanguage = backend::BackendUtils::getFileLanguage(fileExtension.c_str());
+ if(fileLanguage != sibs::Language::ZIG)
+ {
+ ferr << "Error: file specific testing can only be done on zig files. " << testFile << " is not a zig file" << endl;
+ exit(42);
+ }
+ break;
+ }
+ }
+ }
+
FileString projectConfFilePath = projectPath;
projectConfFilePath += TINYDIR_STRING("/project.conf");
validateFilePath(projectConfFilePath.c_str());
@@ -446,6 +523,15 @@ int testProject(int argc, const _tinydir_char_t **argv)
SibsConfig sibsConfig(compiler, projectPath, OPT_LEV_DEBUG, true);
sibsConfig.showWarnings = true;
sibsConfig.setSanitize(sanitize);
+ sibsConfig.zigTestFiles = move(filesToTest);
+ sibsConfig.zigTestAllFiles = testAllFiles;
+
+ if(sibsConfig.getTestPath().empty() && !sibsConfig.zigTestAllFiles && sibsConfig.zigTestFiles.empty())
+ {
+ printf("Project is missing package.tests config. No tests to build\n");
+ exit(50);
+ }
+
return buildProject(projectPath, projectConfFilePath, sibsConfig);
}