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.tag;
8 
9 import git.commit;
10 import git.object_;
11 import git.oid;
12 import git.repository;
13 import git.signature;
14 import git.types;
15 import git.util;
16 import git.version_;
17 
18 import deimos.git2.oid;
19 import deimos.git2.tag;
20 import deimos.git2.errors;
21 import deimos.git2.strarray;
22 import deimos.git2.types;
23 
24 import std.conv : to;
25 import std.exception : enforce;
26 import std.string : toStringz;
27 
28 
29 GitTag lookupTag(GitRepo repo, GitOid oid)
30 {
31 	git_tag* dst;
32 	require(git_tag_lookup(&dst, repo.cHandle, &oid._get_oid()) == 0);
33 	return GitTag(repo, dst);
34 }
35 
36 GitTag lookupTag(GitRepo repo, GitOid oid, size_t oid_length)
37 {
38 	git_tag* dst;
39 	require(git_tag_lookup_prefix(&dst, repo.cHandle, &oid._get_oid(), oid_length) == 0);
40 	return GitTag(repo, dst);
41 }
42 
43 GitOid createTag(GitRepo repo, string tag_name, in GitObject target, in GitSignature tagger, string message, bool force)
44 {
45 	GitOid dst;
46 	require(git_tag_create(&dst._get_oid(), repo.cHandle, tag_name.toStringz, target.cHandle, tagger.cHandle, message.toStringz(), force) == 0);
47 	return dst;
48 }
49 
50 GitOid createTagAnnotation(GitRepo repo, string tag_name, in GitObject target, in GitSignature tagger, string message)
51 {
52 	GitOid dst;
53 	require(git_tag_annotation_create(&dst._get_oid(), repo.cHandle, tag_name.toStringz, target.cHandle, tagger.cHandle, message.toStringz()) == 0);
54 	return dst;
55 }
56 
57 GitOid createTagFromBuffer(GitRepo repo, string buffer, bool force)
58 {
59 	GitOid dst;
60 	require(git_tag_create_frombuffer(&dst._get_oid(), repo.cHandle, buffer.toStringz, force) == 0);
61 	return dst;
62 }
63 
64 GitOid createTagLightweight(GitRepo repo, string tag_name, in GitObject target, bool force)
65 {
66 	GitOid dst;
67 	require(git_tag_create_lightweight(&dst._get_oid(), repo.cHandle, tag_name.toStringz, target.cHandle, force) == 0);
68 	return dst;
69 }
70 
71 void deleteTag(GitRepo repo, string tag_name)
72 {
73 	require(git_tag_delete(repo.cHandle, tag_name.toStringz) == 0);
74 }
75 
76 void iterateTags(GitRepo repo, scope ContinueWalk delegate(string name, GitOid oid) del)
77 {
78 	static struct CTX { ContinueWalk delegate(string name, GitOid oid) del; Exception e; }
79 
80 	static extern(C) nothrow int callback(const(char)* name, git_oid *oid, void *payload)
81 	{
82 		auto ctx = cast(CTX*)payload;
83 		try {
84 			if (ctx.del(name.to!string, GitOid(*oid)) != ContinueWalk.yes)
85 				return 1;
86 		} catch (Exception e) {
87 			ctx.e = e;
88 			return -1;
89 		}
90 		return 0;
91 	}
92 
93 	auto ctx = CTX(del);
94 	auto ret = git_tag_foreach(repo.cHandle, &callback, &ctx);
95 	if (ctx.e) throw ctx.e;
96 	require(ret == 0);
97 }
98 
99 string[] listTags(GitRepo repo)
100 {
101 	git_strarray arr;
102 	require(git_tag_list(&arr, repo.cHandle) == 0);
103 	git_strarray_free(&arr);
104 	auto ret = new string[arr.count];
105 	foreach (i; 0 .. arr.count)
106 		ret[i] = arr.strings[i].to!string;
107 	return ret;
108 }
109 
110 string[] listMatchingTags(GitRepo repo, string pattern)
111 {
112 	git_strarray arr;
113 	require(git_tag_list_match(&arr, pattern.toStringz, repo.cHandle) == 0);
114 	git_strarray_free(&arr);
115 	auto ret = new string[arr.count];
116 	foreach (i; 0 .. arr.count)
117 		ret[i] = arr.strings[i].to!string;
118 	return ret;
119 }
120 
121 
122 struct GitTag {
123 	this(GitObject obj)
124 	{
125 		enforce(obj.type == GitType.commit, "GIT object is not a commit.");
126 		_object = obj;
127 	}
128 
129 	package this(GitRepo repo, git_tag* tag)
130 	{
131 		_object = GitObject(repo, cast(git_object*)tag);
132 	}
133 
134 	@property inout(GitRepo) owner() inout { return _object.owner; }
135 	@property GitOid id() const { return GitOid(*git_tag_id(this.cHandle)); }
136 	@property string name() { return git_tag_name(this.cHandle).to!string; }
137 	@property GitObject target()
138 	{
139 		git_object* dst;
140 		require(git_tag_target(&dst, this.cHandle) == 0);
141 		return GitObject(this.owner, dst);
142 	}
143 	@property GitOid targetID() const { return GitOid(*git_tag_target_id(this.cHandle)); }
144 	@property GitType targetType() const { return cast(GitType)git_tag_target_type(this.cHandle); }
145 	@property GitSignature tagger() { return GitSignature(this, git_tag_tagger(this.cHandle)); }
146 	@property string message() const { return git_tag_message(this.cHandle).to!string; }
147 
148 	GitObject peel()
149 	{
150 		git_object* dst;
151 		require(git_tag_peel(&dst, this.cHandle) == 0);
152 		return GitObject(this.owner, dst);
153 	}
154 
155 	package @property inout(git_tag)* cHandle() inout { return cast(inout(git_tag)*)_object.cHandle; }
156 
157 	private GitObject _object;
158 }