submodule_helpers.c 6.37 KB
Newer Older
Russell Belfer committed
1 2 3 4 5
#include "clar_libgit2.h"
#include "path.h"
#include "util.h"
#include "posix.h"
#include "submodule_helpers.h"
6
#include "git2/sys/repository.h"
Russell Belfer committed
7 8 9 10 11 12 13

/* rewrite gitmodules -> .gitmodules
 * rewrite the empty or relative urls inside each module
 * rename the .gitted directory inside any submodule to .git
 */
void rewrite_gitmodules(const char *workdir)
{
14
	git_str in_f = GIT_STR_INIT, out_f = GIT_STR_INIT, path = GIT_STR_INIT;
Russell Belfer committed
15 16 17
	FILE *in, *out;
	char line[256];

18 19
	cl_git_pass(git_str_joinpath(&in_f, workdir, "gitmodules"));
	cl_git_pass(git_str_joinpath(&out_f, workdir, ".gitmodules"));
Russell Belfer committed
20

21 22
	cl_assert((in  = fopen(in_f.ptr, "rb")) != NULL);
	cl_assert((out = fopen(out_f.ptr, "wb")) != NULL);
Russell Belfer committed
23 24 25 26 27 28 29 30 31 32 33

	while (fgets(line, sizeof(line), in) != NULL) {
		char *scan = line;

		while (*scan == ' ' || *scan == '\t') scan++;

		/* rename .gitted -> .git in submodule directories */
		if (git__prefixcmp(scan, "path =") == 0) {
			scan += strlen("path =");
			while (*scan == ' ') scan++;

34 35 36
			git_str_joinpath(&path, workdir, scan);
			git_str_rtrim(&path);
			git_str_joinpath(&path, path.ptr, ".gitted");
Russell Belfer committed
37

38 39 40 41
			if (!git_str_oom(&path) && p_access(path.ptr, F_OK) == 0) {
				git_str_joinpath(&out_f, workdir, scan);
				git_str_rtrim(&out_f);
				git_str_joinpath(&out_f, out_f.ptr, ".git");
Russell Belfer committed
42

43
				if (!git_str_oom(&out_f))
Russell Belfer committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
					p_rename(path.ptr, out_f.ptr);
			}
		}

		/* copy non-"url =" lines verbatim */
		if (git__prefixcmp(scan, "url =") != 0) {
			fputs(line, out);
			continue;
		}

		/* convert relative URLs in "url =" lines */
		scan += strlen("url =");
		while (*scan == ' ') scan++;

		if (*scan == '.') {
59 60
			git_str_joinpath(&path, workdir, scan);
			git_str_rtrim(&path);
Russell Belfer committed
61
		} else if (!*scan || *scan == '\n') {
62
			git_str_joinpath(&path, workdir, "../testrepo.git");
Russell Belfer committed
63 64 65 66 67
		} else {
			fputs(line, out);
			continue;
		}

68
		git_fs_path_prettify(&path, path.ptr, NULL);
69 70
		git_str_putc(&path, '\n');
		cl_assert(!git_str_oom(&path));
Russell Belfer committed
71 72 73 74 75 76 77 78 79 80

		fwrite(line, scan - line, sizeof(char), out);
		fputs(path.ptr, out);
	}

	fclose(in);
	fclose(out);

	cl_must_pass(p_unlink(in_f.ptr));

81 82 83
	git_str_dispose(&in_f);
	git_str_dispose(&out_f);
	git_str_dispose(&path);
Russell Belfer committed
84
}
85

86 87 88 89 90 91 92 93
static void cleanup_fixture_submodules(void *payload)
{
	cl_git_sandbox_cleanup(); /* either "submodules" or "submod2" */

	if (payload)
		cl_fixture_cleanup(payload);
}

94 95 96 97 98 99 100 101 102
git_repository *setup_fixture_submodules(void)
{
	git_repository *repo = cl_git_sandbox_init("submodules");

	cl_fixture_sandbox("testrepo.git");

	rewrite_gitmodules(git_repository_workdir(repo));
	p_rename("submodules/testrepo/.gitted", "submodules/testrepo/.git");

103 104
	cl_set_cleanup(cleanup_fixture_submodules, "testrepo.git");

105
	cl_git_pass(git_repository_reinit_filesystem(repo, 1));
106

107 108 109 110 111 112 113 114 115 116 117 118 119 120
	return repo;
}

git_repository *setup_fixture_submod2(void)
{
	git_repository *repo = cl_git_sandbox_init("submod2");

	cl_fixture_sandbox("submod2_target");
	p_rename("submod2_target/.gitted", "submod2_target/.git");

	rewrite_gitmodules(git_repository_workdir(repo));
	p_rename("submod2/not-submodule/.gitted", "submod2/not-submodule/.git");
	p_rename("submod2/not/.gitted", "submod2/not/.git");

121
	cl_set_cleanup(cleanup_fixture_submodules, "submod2_target");
122

123
	cl_git_pass(git_repository_reinit_filesystem(repo, 1));
124

125
	return repo;
126
}
127

128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
git_repository *setup_fixture_submod3(void)
{
	git_repository *repo = cl_git_sandbox_init("submod3");

	cl_fixture_sandbox("submod2_target");
	p_rename("submod2_target/.gitted", "submod2_target/.git");

	rewrite_gitmodules(git_repository_workdir(repo));
	p_rename("submod3/One/.gitted", "submod3/One/.git");
	p_rename("submod3/TWO/.gitted", "submod3/TWO/.git");
	p_rename("submod3/three/.gitted", "submod3/three/.git");
	p_rename("submod3/FoUr/.gitted", "submod3/FoUr/.git");
	p_rename("submod3/Five/.gitted", "submod3/Five/.git");
	p_rename("submod3/six/.gitted", "submod3/six/.git");
	p_rename("submod3/sEvEn/.gitted", "submod3/sEvEn/.git");
	p_rename("submod3/EIGHT/.gitted", "submod3/EIGHT/.git");
	p_rename("submod3/nine/.gitted", "submod3/nine/.git");
	p_rename("submod3/TEN/.gitted", "submod3/TEN/.git");

	cl_set_cleanup(cleanup_fixture_submodules, "submod2_target");

	cl_git_pass(git_repository_reinit_filesystem(repo, 1));

	return repo;
}

154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
git_repository *setup_fixture_super(void)
{
	git_repository *repo = cl_git_sandbox_init("super");

	cl_fixture_sandbox("sub.git");
	p_mkdir("super/sub", 0777);

	rewrite_gitmodules(git_repository_workdir(repo));

	cl_set_cleanup(cleanup_fixture_submodules, "sub.git");

	cl_git_pass(git_repository_reinit_filesystem(repo, 1));

	return repo;
}

170 171 172 173 174 175 176 177 178 179 180 181 182 183
git_repository *setup_fixture_submodule_simple(void)
{
	git_repository *repo = cl_git_sandbox_init("submodule_simple");

	cl_fixture_sandbox("testrepo.git");
	p_mkdir("submodule_simple/testrepo", 0777);

	cl_set_cleanup(cleanup_fixture_submodules, "testrepo.git");

	cl_git_pass(git_repository_reinit_filesystem(repo, 1));

	return repo;
}

184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
git_repository *setup_fixture_submodule_with_path(void)
{
	git_repository *repo = cl_git_sandbox_init("submodule_with_path");

	cl_fixture_sandbox("testrepo.git");
	p_mkdir("submodule_with_path/lib", 0777);
	p_mkdir("submodule_with_path/lib/testrepo", 0777);

	cl_set_cleanup(cleanup_fixture_submodules, "testrepo.git");

	cl_git_pass(git_repository_reinit_filesystem(repo, 1));

	return repo;
}

199 200
void assert__submodule_exists(
	git_repository *repo, const char *name,
201
	const char *msg, const char *file, const char *func, int line)
202 203
{
	git_submodule *sm;
204 205
	int error = git_submodule_lookup(&sm, repo, name);
	if (error)
206 207
		cl_git_report_failure(error, 0, file, func, line, msg);
	cl_assert_at_line(sm != NULL, file, func, line);
208 209 210
	git_submodule_free(sm);
}

211 212
void refute__submodule_exists(
	git_repository *repo, const char *name, int expected_error,
213
	const char *msg, const char *file, const char *func, int line)
214
{
215
	clar__assert_equal(
216
		file, func, line, msg, 1, "%i",
217
		expected_error, (int)(git_submodule_lookup(NULL, repo, name)));
218 219 220 221 222 223
}

unsigned int get_submodule_status(git_repository *repo, const char *name)
{
	unsigned int status = 0;

224 225
	assert(repo && name);

226
	cl_git_pass(git_submodule_status(&status, repo, name, GIT_SUBMODULE_IGNORE_UNSPECIFIED));
227 228 229

	return status;
}
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245

static int print_submodules(git_submodule *sm, const char *name, void *p)
{
	unsigned int loc = 0;
	GIT_UNUSED(p);
	git_submodule_location(&loc, sm);
	fprintf(stderr, "# submodule %s (at %s) flags %x\n",
		name, git_submodule_path(sm), loc);
	return 0;
}

void dump_submodules(git_repository *repo)
{
	git_submodule_foreach(repo, print_submodules, NULL);
}