1 /*
2  *             Copyright Sönke Ludwig 2014.
3  *  Distributed under the Boost Software License, Version 1.0.
4  *     (See accompanying file LICENSE_1_0.txt or copy at
5  *           http://www.boost.org/LICENSE_1_0.txt)
6  */
7 module git.submodule;
8 
9 import git.commit;
10 import git.oid;
11 import git.tree;
12 import git.repository;
13 import git.types;
14 import git.util;
15 import git.version_;
16 
17 import deimos.git2.submodule;
18 import deimos.git2.errors;
19 import deimos.git2.types;
20 
21 import std.conv : to;
22 import std.string : toStringz;
23 
24 GitSubModule lookupSubModule(GitRepo repo, string name)
25 {
26 	git_submodule* dst;
27 	require(git_submodule_lookup(&dst, repo.cHandle, name.toStringz) == 0);
28 	return GitSubModule(repo, dst);
29 }
30 
31 GitSubModule addSubModuleAndSetup(GitRepo repo, string url, string path, bool use_gitlink)
32 {
33 	git_submodule* dst;
34 	require(git_submodule_add_setup(&dst, repo.cHandle, url.toStringz, path.toStringz, use_gitlink) == 0);
35 	return GitSubModule(repo, dst);
36 }
37 
38 void iterateSubModules(GitRepo repo, scope ContinueWalk delegate(GitSubModule dm, string name) del)
39 {
40 	struct CTX { ContinueWalk delegate(GitSubModule dm, string name) del; GitRepo repo; Exception e; }
41 
42 	static extern(C) nothrow int callback(git_submodule* sm, const(char)* name, void* payload)
43 	{
44 		auto ctx = cast(CTX*)payload;
45 		try {
46 			if (ctx.del(GitSubModule(ctx.repo, sm), name.to!string) != ContinueWalk.yes)
47 				return 1;
48 		} catch (Exception e) {
49 			ctx.e = e;
50 			return -1;
51 		}
52 		return 0;
53 	}
54 
55 	auto ctx = CTX(del, repo);
56 	auto ret = git_submodule_foreach(repo.cHandle, &callback, &ctx);
57 	if (ctx.e) throw ctx.e;
58 	require(ret == 0);
59 }
60 
61 void reloadSubModules(GitRepo repo)
62 {
63 	require(git_submodule_reload_all(repo.cHandle) == 0);
64 }
65 
66 struct GitSubModule {
67 	package this(GitRepo repo, git_submodule* submod)
68 	{
69 		_repo = repo;
70 		_submod = submod;
71 	}
72 
73 	@property inout(GitRepo) owner() inout { return _repo; }
74 
75 	@property string name() { return git_submodule_name(this.cHandle).to!string; }
76 	@property string path() { return git_submodule_path(this.cHandle).to!string; }
77 	@property string url() { return git_submodule_url(this.cHandle).to!string; }
78 	@property void url(string url) { require(git_submodule_set_url(this.cHandle, url.toStringz) == 0); }
79 	@property GitOid indexID() { return GitOid(*git_submodule_index_id(this.cHandle)); }
80 	@property GitOid headID() { return GitOid(*git_submodule_head_id(this.cHandle)); }
81 	@property GitOid wdID() { return GitOid(*git_submodule_wd_id(this.cHandle)); }
82 	/*@property git_submodule_ignore_t git_submodule_ignore(
83 	this.cHandle);
84 git_submodule_ignore_t git_submodule_set_ignore(
85 	this.cHandle,
86 	git_submodule_ignore_t ignore);
87 git_submodule_update_t git_submodule_update(
88 	this.cHandle);
89 git_submodule_update_t git_submodule_set_update(
90 	this.cHandle,
91 	git_submodule_update_t update);*/
92 	@property bool fetchRecurseSubModules() { return git_submodule_fetch_recurse_submodules(this.cHandle) != 0; }
93 	@property void fetchRecurseSubModules(bool value) { require(git_submodule_set_fetch_recurse_submodules(this.cHandle, value) == 0); }
94 
95 	@property GitSubModuleStatusFlags status()
96 	{
97 		uint dst;
98 		require(git_submodule_status(&dst, this.cHandle) == 0);
99 		return cast(GitSubModuleStatusFlags)dst;
100 	}
101 
102 	@property GitSubModuleStatusFlags location()
103 	{
104 		uint dst;
105 		require(git_submodule_location(&dst, this.cHandle) == 0);
106 		return cast(GitSubModuleStatusFlags)dst;
107 	}
108 
109 	GitRepo open()
110 	{
111 		git_repository* dst;
112 		require(git_submodule_open(&dst, this.cHandle) == 0);
113 		return GitRepo(dst);
114 	}
115 
116 	void init(bool overwrite) { require(git_submodule_init(this.cHandle, overwrite) == 0); }
117 	void save() { require(git_submodule_save(this.cHandle) == 0); }
118 	void sync() { require(git_submodule_sync(this.cHandle) == 0); }
119 	void reload() { require(git_submodule_reload(this.cHandle) == 0); }
120 
121 	void finalizeAdd() { require(git_submodule_add_finalize(this.cHandle) == 0); }
122 
123 	void addToIndex(bool write_index) { require(git_submodule_add_to_index(this.cHandle, write_index) == 0); }
124 
125 
126 	package @property inout(git_submodule)* cHandle() inout { return _submod; }
127 
128 	private git_submodule* _submod;
129 	// Reference to the parent repository to keep it alive.
130 	private GitRepo _repo;
131 }
132 
133 
134 enum GitSubModuleStatusFlags {
135 	inHead = GIT_SUBMODULE_STATUS_IN_HEAD,
136 	inIndex = GIT_SUBMODULE_STATUS_IN_INDEX,
137 	inConfig = GIT_SUBMODULE_STATUS_IN_CONFIG,
138 	inWD = GIT_SUBMODULE_STATUS_IN_WD,
139 	indexAdded = GIT_SUBMODULE_STATUS_INDEX_ADDED,
140 	indexDeleted = GIT_SUBMODULE_STATUS_INDEX_DELETED,
141 	indexModified = GIT_SUBMODULE_STATUS_INDEX_MODIFIED,
142 	wdUninitialized = GIT_SUBMODULE_STATUS_WD_UNINITIALIZED,
143 	wdAdded = GIT_SUBMODULE_STATUS_WD_ADDED,
144 	wdDeleted = GIT_SUBMODULE_STATUS_WD_DELETED,
145 	wdModified = GIT_SUBMODULE_STATUS_WD_MODIFIED,
146 	wdIndexModified = GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED,
147 	wdWDModified = GIT_SUBMODULE_STATUS_WD_WD_MODIFIED,
148 	wdUntracked = GIT_SUBMODULE_STATUS_WD_UNTRACKED,
149 	inFlagsMask = GIT_SUBMODULE_STATUS__IN_FLAGS,
150 	indexFlagsMask = GIT_SUBMODULE_STATUS__INDEX_FLAGS,
151 	wdFlagsMask = GIT_SUBMODULE_STATUS__WD_FLAGS,
152 }