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