1 /*
2  * libgit2 "stash" example - shows how to use the stash API
3  *
4  * Written by the libgit2 contributors
5  *
6  * To the extent possible under law, the author(s) have dedicated all copyright
7  * and related and neighboring rights to this software to the public domain
8  * worldwide. This software is distributed without any warranty.
9  *
10  * You should have received a copy of the CC0 Public Domain Dedication along
11  * with this software. If not, see
12  * <http://creativecommons.org/publicdomain/zero/1.0/>.
13  */
14 module libgit2_d.example.stash;
15 
16 
17 private static import core.stdc.stdio;
18 private static import core.stdc.stdlib;
19 private static import core.stdc..string;
20 private static import libgit2_d.commit;
21 private static import libgit2_d.example.common;
22 private static import libgit2_d.oid;
23 private static import libgit2_d.signature;
24 private static import libgit2_d.stash;
25 private static import libgit2_d.types;
26 
27 package:
28 
29 enum subcmd
30 {
31 	SUBCMD_APPLY,
32 	SUBCMD_LIST,
33 	SUBCMD_POP,
34 	SUBCMD_PUSH,
35 }
36 
37 //Declaration name in C language
38 enum
39 {
40 	SUBCMD_APPLY = .subcmd.SUBCMD_APPLY,
41 	SUBCMD_LIST = .subcmd.SUBCMD_LIST,
42 	SUBCMD_POP = .subcmd.SUBCMD_POP,
43 	SUBCMD_PUSH = .subcmd.SUBCMD_PUSH,
44 }
45 
46 struct opts
47 {
48 	.subcmd cmd;
49 	int argc;
50 	char** argv;
51 }
52 
53 nothrow @nogc
54 private void usage(const (char)* fmt, const char* msg = null)
55 
56 	in
57 	{
58 	}
59 
60 	do
61 	{
62 		core.stdc.stdio.fputs("usage: git stash list\n", core.stdc.stdio.stderr);
63 		core.stdc.stdio.fputs("   or: git stash ( pop | apply )\n", core.stdc.stdio.stderr);
64 		core.stdc.stdio.fputs("   or: git stash [push]\n", core.stdc.stdio.stderr);
65 		core.stdc.stdio.fputs("\n", core.stdc.stdio.stderr);
66 
67 		if (msg == null) {
68 			core.stdc.stdio.fprintf(core.stdc.stdio.stderr, fmt);
69 		} else {
70 			core.stdc.stdio.fprintf(core.stdc.stdio.stderr, fmt, msg);
71 		}
72 
73 		core.stdc.stdlib.exit(1);
74 	}
75 
76 nothrow @nogc
77 private void parse_subcommand(.opts* opts, int argc, char** argv)
78 
79 	in
80 	{
81 	}
82 
83 	do
84 	{
85 		const char* arg = (argc < 2) ? ("push") : (argv[1]);
86 		.subcmd cmd;
87 
88 		if (!core.stdc..string.strcmp(arg, "apply")) {
89 			cmd = .subcmd.SUBCMD_APPLY;
90 		} else if (!core.stdc..string.strcmp(arg, "list")) {
91 			cmd = .subcmd.SUBCMD_LIST;
92 		} else if (!core.stdc..string.strcmp(arg, "pop")) {
93 			cmd = .subcmd.SUBCMD_POP;
94 		} else if (!core.stdc..string.strcmp(arg, "push")) {
95 			cmd = .subcmd.SUBCMD_PUSH;
96 		} else {
97 			.usage("invalid command %s", arg);
98 
99 			return;
100 		}
101 
102 		opts.cmd = cmd;
103 		opts.argc = (argc < 2) ? (argc - 1) : (argc - 2);
104 		opts.argv = argv;
105 	}
106 
107 nothrow @nogc
108 private int cmd_apply(libgit2_d.types.git_repository* repo, .opts* opts)
109 
110 	in
111 	{
112 	}
113 
114 	do
115 	{
116 		if (opts.argc) {
117 			.usage("apply does not accept any parameters");
118 		}
119 
120 		libgit2_d.example.common.check_lg2(libgit2_d.stash.git_stash_apply(repo, 0, null), "Unable to apply stash", null);
121 
122 		return 0;
123 	}
124 
125 extern (C)
126 nothrow @nogc
127 private int list_stash_cb(size_t index, const (char)* message, const (libgit2_d.oid.git_oid)* stash_id, void* payload)
128 
129 	in
130 	{
131 	}
132 
133 	do
134 	{
135 		//cast(void)(stash_id);
136 		//cast(void)(payload);
137 		core.stdc.stdio.printf("stash@{%" ~ libgit2_d.example.common.PRIuZ ~ "}: %s\n", index, message);
138 
139 		return 0;
140 	}
141 
142 nothrow @nogc
143 private int cmd_list(libgit2_d.types.git_repository* repo, .opts* opts)
144 
145 	in
146 	{
147 	}
148 
149 	do
150 	{
151 		if (opts.argc) {
152 			.usage("list does not accept any parameters");
153 		}
154 
155 		libgit2_d.example.common.check_lg2(libgit2_d.stash.git_stash_foreach(repo, &.list_stash_cb, null), "Unable to list stashes", null);
156 
157 		return 0;
158 	}
159 
160 nothrow @nogc
161 private int cmd_push(libgit2_d.types.git_repository* repo, .opts* opts)
162 
163 	in
164 	{
165 	}
166 
167 	do
168 	{
169 		if (opts.argc) {
170 			.usage("push does not accept any parameters");
171 		}
172 
173 		libgit2_d.types.git_signature* signature;
174 		libgit2_d.example.common.check_lg2(libgit2_d.signature.git_signature_default(&signature, repo), "Unable to get signature", null);
175 
176 		libgit2_d.oid.git_oid stashid;
177 		libgit2_d.example.common.check_lg2(libgit2_d.stash.git_stash_save(&stashid, repo, signature, null, libgit2_d.stash.git_stash_flags.GIT_STASH_DEFAULT), "Unable to save stash", null);
178 
179 		libgit2_d.types.git_commit* stash;
180 		libgit2_d.example.common.check_lg2(libgit2_d.commit.git_commit_lookup(&stash, repo, &stashid), "Unable to lookup stash commit", null);
181 
182 		core.stdc.stdio.printf("Saved working directory %s\n", libgit2_d.commit.git_commit_summary(stash));
183 
184 		libgit2_d.signature.git_signature_free(signature);
185 		libgit2_d.commit.git_commit_free(stash);
186 
187 		return 0;
188 	}
189 
190 nothrow @nogc
191 private int cmd_pop(libgit2_d.types.git_repository* repo, .opts* opts)
192 
193 	in
194 	{
195 	}
196 
197 	do
198 	{
199 		if (opts.argc) {
200 			.usage("pop does not accept any parameters");
201 		}
202 
203 		libgit2_d.example.common.check_lg2(libgit2_d.stash.git_stash_pop(repo, 0, null), "Unable to pop stash", null);
204 
205 		core.stdc.stdio.printf("Dropped refs/stash@{0}\n");
206 
207 		return 0;
208 	}
209 
210 extern (C)
211 nothrow @nogc
212 //int lg2_stash(libgit2_d.types.git_repository* repo, int argc, char*[] argv)
213 public int lg2_stash(libgit2_d.types.git_repository* repo, int argc, char** argv)
214 
215 	in
216 	{
217 	}
218 
219 	do
220 	{
221 		.opts opts = .opts.init;
222 
223 		.parse_subcommand(&opts, argc, argv);
224 
225 		switch (opts.cmd) {
226 			case .subcmd.SUBCMD_APPLY:
227 				return .cmd_apply(repo, &opts);
228 
229 			case .subcmd.SUBCMD_LIST:
230 				return .cmd_list(repo, &opts);
231 
232 			case .subcmd.SUBCMD_PUSH:
233 				return .cmd_push(repo, &opts);
234 
235 			case .subcmd.SUBCMD_POP:
236 				return .cmd_pop(repo, &opts);
237 
238 			default:
239 				break;
240 		}
241 
242 		return -1;
243 	}