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  * <https://creativecommons.org/publicdomain/zero/1.0/>.
13  */
14 /**
15  * License: $(LINK2 https://creativecommons.org/publicdomain/zero/1.0/, CC0 1.0 Universal)
16  */
17 module libgit2.example.stash;
18 
19 
20 private static import core.stdc.stdio;
21 private static import core.stdc.stdlib;
22 private static import core.stdc.string;
23 private static import libgit2.commit;
24 private static import libgit2.example.common;
25 private static import libgit2.oid;
26 private static import libgit2.signature;
27 private static import libgit2.stash;
28 private static import libgit2.types;
29 
30 enum subcmd
31 {
32 	SUBCMD_APPLY,
33 	SUBCMD_LIST,
34 	SUBCMD_POP,
35 	SUBCMD_PUSH,
36 }
37 
38 //Declaration name in C language
39 enum
40 {
41 	SUBCMD_APPLY = .subcmd.SUBCMD_APPLY,
42 	SUBCMD_LIST = .subcmd.SUBCMD_LIST,
43 	SUBCMD_POP = .subcmd.SUBCMD_POP,
44 	SUBCMD_PUSH = .subcmd.SUBCMD_PUSH,
45 }
46 
47 struct opts
48 {
49 	.subcmd cmd;
50 	int argc;
51 	char** argv;
52 }
53 
54 nothrow @nogc
55 private void usage(const (char)* fmt, const char* msg = null)
56 
57 	in
58 	{
59 	}
60 
61 	do
62 	{
63 		core.stdc.stdio.fputs("usage: git stash list\n", core.stdc.stdio.stderr);
64 		core.stdc.stdio.fputs("   or: git stash ( pop | apply )\n", core.stdc.stdio.stderr);
65 		core.stdc.stdio.fputs("   or: git stash [push]\n", core.stdc.stdio.stderr);
66 		core.stdc.stdio.fputs("\n", core.stdc.stdio.stderr);
67 
68 		if (msg == null) {
69 			core.stdc.stdio.fprintf(core.stdc.stdio.stderr, fmt);
70 		} else {
71 			core.stdc.stdio.fprintf(core.stdc.stdio.stderr, fmt, msg);
72 		}
73 
74 		core.stdc.stdlib.exit(1);
75 	}
76 
77 nothrow @nogc
78 private void parse_subcommand(.opts* opts, int argc, char** argv)
79 
80 	in
81 	{
82 	}
83 
84 	do
85 	{
86 		const char* arg = (argc < 2) ? ("push") : (argv[1]);
87 		.subcmd cmd;
88 
89 		if (!core.stdc..string.strcmp(arg, "apply")) {
90 			cmd = .subcmd.SUBCMD_APPLY;
91 		} else if (!core.stdc..string.strcmp(arg, "list")) {
92 			cmd = .subcmd.SUBCMD_LIST;
93 		} else if (!core.stdc..string.strcmp(arg, "pop")) {
94 			cmd = .subcmd.SUBCMD_POP;
95 		} else if (!core.stdc..string.strcmp(arg, "push")) {
96 			cmd = .subcmd.SUBCMD_PUSH;
97 		} else {
98 			.usage("invalid command %s", arg);
99 
100 			return;
101 		}
102 
103 		opts.cmd = cmd;
104 		opts.argc = (argc < 2) ? (argc - 1) : (argc - 2);
105 		opts.argv = argv;
106 	}
107 
108 nothrow @nogc
109 private int cmd_apply(libgit2.types.git_repository* repo, .opts* opts)
110 
111 	in
112 	{
113 	}
114 
115 	do
116 	{
117 		if (opts.argc) {
118 			.usage("apply does not accept any parameters");
119 		}
120 
121 		libgit2.example.common.check_lg2(libgit2.stash.git_stash_apply(repo, 0, null), "Unable to apply stash", null);
122 
123 		return 0;
124 	}
125 
126 extern (C)
127 nothrow @nogc
128 private int list_stash_cb(size_t index, const (char)* message, const (libgit2.oid.git_oid)* stash_id, void* payload)
129 
130 	in
131 	{
132 	}
133 
134 	do
135 	{
136 		//cast(void)(stash_id);
137 		//cast(void)(payload);
138 		core.stdc.stdio.printf("stash@{%" ~ libgit2.example.common.PRIuZ ~ "}: %s\n", index, message);
139 
140 		return 0;
141 	}
142 
143 nothrow @nogc
144 private int cmd_list(libgit2.types.git_repository* repo, .opts* opts)
145 
146 	in
147 	{
148 	}
149 
150 	do
151 	{
152 		if (opts.argc) {
153 			.usage("list does not accept any parameters");
154 		}
155 
156 		libgit2.example.common.check_lg2(libgit2.stash.git_stash_foreach(repo, &.list_stash_cb, null), "Unable to list stashes", null);
157 
158 		return 0;
159 	}
160 
161 nothrow @nogc
162 private int cmd_push(libgit2.types.git_repository* repo, .opts* opts)
163 
164 	in
165 	{
166 	}
167 
168 	do
169 	{
170 		if (opts.argc) {
171 			.usage("push does not accept any parameters");
172 		}
173 
174 		libgit2.types.git_signature* signature;
175 		libgit2.example.common.check_lg2(libgit2.signature.git_signature_default(&signature, repo), "Unable to get signature", null);
176 
177 		libgit2.oid.git_oid stashid;
178 		libgit2.example.common.check_lg2(libgit2.stash.git_stash_save(&stashid, repo, signature, null, libgit2.stash.git_stash_flags.GIT_STASH_DEFAULT), "Unable to save stash", null);
179 
180 		libgit2.types.git_commit* stash;
181 		libgit2.example.common.check_lg2(libgit2.commit.git_commit_lookup(&stash, repo, &stashid), "Unable to lookup stash commit", null);
182 
183 		core.stdc.stdio.printf("Saved working directory %s\n", libgit2.commit.git_commit_summary(stash));
184 
185 		libgit2.signature.git_signature_free(signature);
186 		libgit2.commit.git_commit_free(stash);
187 
188 		return 0;
189 	}
190 
191 nothrow @nogc
192 private int cmd_pop(libgit2.types.git_repository* repo, .opts* opts)
193 
194 	in
195 	{
196 	}
197 
198 	do
199 	{
200 		if (opts.argc) {
201 			.usage("pop does not accept any parameters");
202 		}
203 
204 		libgit2.example.common.check_lg2(libgit2.stash.git_stash_pop(repo, 0, null), "Unable to pop stash", null);
205 
206 		core.stdc.stdio.printf("Dropped refs/stash@{0}\n");
207 
208 		return 0;
209 	}
210 
211 extern (C)
212 nothrow @nogc
213 public int lg2_stash(libgit2.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 	}