1 /*
2  * libgit2 "rev-parse" example - shows how to parse revspecs
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.rev_parse;
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.example.args;
24 private static import libgit2.example.common;
25 private static import libgit2.merge;
26 private static import libgit2.object;
27 private static import libgit2.oid;
28 private static import libgit2.revparse;
29 private static import libgit2.types;
30 
31 /**
32  * Forward declarations for helpers.
33  */
34 extern (C)
35 public struct parse_state
36 {
37 	const (char)* repodir;
38 	const (char)* spec;
39 	int not;
40 }
41 
42 extern (C)
43 nothrow @nogc
44 public int lg2_rev_parse(libgit2.types.git_repository* repo, int argc, char** argv)
45 
46 	in
47 	{
48 	}
49 
50 	do
51 	{
52 		.parse_state ps = .parse_state.init;
53 
54 		.parse_opts(&ps, argc, argv);
55 
56 		libgit2.example.common.check_lg2(.parse_revision(repo, &ps), "Parsing", null);
57 
58 		return 0;
59 	}
60 
61 nothrow @nogc
62 private void usage(const (char)* message, const (char)* arg)
63 
64 	in
65 	{
66 	}
67 
68 	do
69 	{
70 		if ((message != null) && (arg != null)) {
71 			core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "%s: %s\n", message, arg);
72 		} else if (message != null) {
73 			core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "%s\n", message);
74 		}
75 
76 		core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "usage: rev-parse [ --option ] <args>...\n");
77 		core.stdc.stdlib.exit(1);
78 	}
79 
80 nothrow @nogc
81 private void parse_opts(.parse_state* ps, int argc, char** argv)
82 
83 	in
84 	{
85 	}
86 
87 	do
88 	{
89 		libgit2.example.args.args_info args = libgit2.example.args.ARGS_INFO_INIT(argc, argv);
90 
91 		for (args.pos = 1; args.pos < argc; ++args.pos) {
92 			const (char)* a = argv[args.pos];
93 
94 			if (a[0] != '-') {
95 				if (ps.spec != null) {
96 					.usage("Too many specs", a);
97 				}
98 
99 				ps.spec = a;
100 			} else if (!core.stdc..string.strcmp(a, "--not")) {
101 				ps.not = !ps.not;
102 			} else if (!libgit2.example.args.match_str_arg(&ps.repodir, &args, "--git-dir")) {
103 				.usage("Cannot handle argument", a);
104 			}
105 		}
106 	}
107 
108 nothrow @nogc
109 private int parse_revision(libgit2.types.git_repository* repo, .parse_state* ps)
110 
111 	in
112 	{
113 	}
114 
115 	do
116 	{
117 		libgit2.revparse.git_revspec rs;
118 		libgit2.example.common.check_lg2(libgit2.revparse.git_revparse(&rs, repo, ps.spec), "Could not parse", ps.spec);
119 
120 		char[libgit2.oid.GIT_OID_SHA1_HEXSIZE + 1] str;
121 
122 		if ((rs.flags & libgit2.revparse.git_revspec_t.GIT_REVSPEC_SINGLE) != 0) {
123 			libgit2.oid.git_oid_tostr(&(str[0]), str.length, libgit2.object.git_object_id(rs.from));
124 			core.stdc.stdio.printf("%s\n", &(str[0]));
125 			libgit2.object.git_object_free(rs.from);
126 		} else if ((rs.flags & libgit2.revparse.git_revspec_t.GIT_REVSPEC_RANGE) != 0) {
127 			libgit2.oid.git_oid_tostr(&(str[0]), str.length, libgit2.object.git_object_id(rs.to));
128 			core.stdc.stdio.printf("%s\n", &(str[0]));
129 			libgit2.object.git_object_free(rs.to);
130 
131 			if ((rs.flags & libgit2.revparse.git_revspec_t.GIT_REVSPEC_MERGE_BASE) != 0) {
132 				libgit2.oid.git_oid base;
133 				libgit2.example.common.check_lg2(libgit2.merge.git_merge_base(&base, repo, libgit2.object.git_object_id(rs.from), libgit2.object.git_object_id(rs.to)), "Could not find merge base", ps.spec);
134 
135 				libgit2.oid.git_oid_tostr(&(str[0]), str.length, &base);
136 				core.stdc.stdio.printf("%s\n", &(str[0]));
137 			}
138 
139 			libgit2.oid.git_oid_tostr(&(str[0]), str.length, libgit2.object.git_object_id(rs.from));
140 			core.stdc.stdio.printf("^%s\n", &(str[0]));
141 			libgit2.object.git_object_free(rs.from);
142 		} else {
143 			libgit2.example.common.fatal("Invalid results from git_revparse", ps.spec);
144 		}
145 
146 		return 0;
147 	}