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
1 change: 1 addition & 0 deletions nob.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const char *test_names[] = {
"sb_appendf",
"da_foreach",
"temp_aligned_alloc",
"test_git_fetch"
};
#define test_names_count ARRAY_LEN(test_names)

Expand Down
47 changes: 45 additions & 2 deletions nob.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ NOBDEF bool nob_copy_file(const char *src_path, const char *dst_path);
NOBDEF bool nob_copy_directory_recursively(const char *src_path, const char *dst_path);
NOBDEF bool nob_read_entire_dir(const char *parent, Nob_File_Paths *children);
NOBDEF bool nob_write_entire_file(const char *path, const void *data, size_t size);
NOBDEF bool nob_git_fetch(const char *repo_url, const char *dst_dir, const char *branch, bool shallow);

NOBDEF Nob_File_Type nob_get_file_type(const char *path);
NOBDEF bool nob_delete_file(const char *path);

Expand Down Expand Up @@ -952,11 +954,41 @@ NOBDEF bool nob_copy_file(const char *src_path, const char *dst_path)
#endif
}

NOBDEF bool nob_git_fetch(const char *repo_url, const char *dst_dir, const char *branch, bool shallow)
{
NOB_ASSERT(repo_url && dst_dir);

/* we can do more git processing here, like checking if the current folder is dirty,
or if the brnach/tag is the correct one. etc */
if (nob_file_exists(dst_dir) == 1) return true;

nob_mkdir_if_not_exists(dst_dir);

Nob_Cmd cmd = {0};
nob_cmd_append(&cmd, "git", "clone");
if (shallow) {
nob_cmd_append(&cmd, "--depth", "1");
}
if (branch && branch[0] != '\0') {
nob_cmd_append(&cmd, "--branch", branch);
}
nob_cmd_append(&cmd, repo_url, dst_dir);

if (!nob_cmd_run(&cmd)) {
nob_log(NOB_ERROR, "git clone failed for %s into %s", repo_url, dst_dir);
return false;
}

nob_log(NOB_INFO, "Repository %s is available under %s", repo_url, dst_dir);
return true;
}

NOBDEF void nob_cmd_render(Nob_Cmd cmd, Nob_String_Builder *render)
{
for (size_t i = 0; i < cmd.count; ++i) {
const char *arg = cmd.items[i];
if (arg == NULL) break;
if( arg[0] == '\0' ) continue;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be a good idea to conform the style to what is around. The spaces after ( and before ).
Less work for Zozin.

if (i > 0) nob_sb_append_cstr(render, " ");
if (!strchr(arg, ' ')) {
nob_sb_append_cstr(render, arg);
Expand Down Expand Up @@ -1183,10 +1215,21 @@ static Nob_Proc nob__cmd_start_process(Nob_Cmd cmd, Nob_Fd *fdin, Nob_Fd *fdout,
// NOTE: This leaks a bit of memory in the child process.
// But do we actually care? It's a one off leak anyway...
Nob_Cmd cmd_null = {0};
nob_da_append_many(&cmd_null, cmd.items, cmd.count);
// nob_da_append_many(&cmd_null, cmd.items, cmd.count);
nob_da_reserve(&cmd_null, cmd_null.count + (cmd.count));
size_t iw = 0;
for (size_t i = 0; i < cmd.count; ++i) {
if (cmd.items[i] == NULL) continue;
if (cmd.items[i][0] == '\0') continue;
cmd_null.items[iw] = cmd.items[i];
iw++;
}
cmd_null.count += (iw);

nob_cmd_append(&cmd_null, NULL);

if (execvp(cmd.items[0], (char * const*) cmd_null.items) < 0) {
if ( execvp(cmd_null.items[0], (char *const *)cmd_null.items) < 0 )
{
nob_log(NOB_ERROR, "Could not exec child process for %s: %s", cmd.items[0], strerror(errno));
exit(1);
}
Expand Down
2 changes: 2 additions & 0 deletions tests/cmd_args_passing.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ int main(void)
cmd_append(&cmd, "./print_args");
cmd_append(&cmd, "foo");
cmd_append(&cmd, "bar");
cmd_append(&cmd, "");
cmd_append(&cmd, NULL);
cmd_append(&cmd, "Hello, world");
cmd_append(&cmd, "\"Hello, world\"");
cmd_append(&cmd, "\"\\` %$*@");
Expand Down
63 changes: 63 additions & 0 deletions tests/test_git_fetch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#define NOB_IMPLEMENTATION
#include "nob.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
const char *dst = "flag_h";
const char *repo_url = "https://github.com/tsoding/flag.h";

if (!nob_git_fetch(repo_url, dst, NULL, true)) {
nob_log(NOB_ERROR, "nob_git_fetch failed");
return 1;
}

srand(time(NULL) );
int expected_number = rand();
char expected_str[32];
snprintf(expected_str, sizeof (expected_str), "%d", expected_number);

char main_c[256];
int main_c_len = snprintf(main_c, sizeof (main_c),
"#include <stdio.h>\n"
"#include \"flag.h\"\n"
"int main(void){ (void)printf(\"%s\"); return 0; }\n",
expected_str);

if (!nob_write_entire_file("git_fetch_main.c", main_c, (size_t)main_c_len)) {
nob_log(NOB_ERROR, "Could not write git_fetch_main.c");
return 1;
}

Nob_Cmd cmd = {0};
nob_cmd_append(&cmd, "cc", "-I", dst, "-o", "./git_fetch_main", "git_fetch_main.c");
if (!nob_cmd_run(&cmd)) {
nob_log(NOB_ERROR, "compile failed");
return 1;
}

nob_cmd_append(&cmd, "./git_fetch_main");
if (!nob_cmd_run(&cmd, .stdout_path = "./git_fetch_main_out.txt")) {
nob_log(NOB_ERROR, "run failed");
return 1;
}

Nob_String_Builder sb = {0};

if (!nob_read_entire_file("./git_fetch_main_out.txt", &sb)) return 1;

Nob_String_View out = nob_sb_to_sv(sb);

Nob_String_View trimmed = nob_sv_trim(out);
if (!nob_sv_eq(trimmed, nob_sv_from_cstr(expected_str))) {
nob_log(NOB_ERROR, "Unexpected output (see file)");
return 1;
}

nob_log(NOB_INFO, "git_fetch_main test passed");
return 0;
}