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