1
+ use std:: ffi:: CString ;
1
2
use std:: marker;
2
3
use std:: mem;
3
4
use std:: ptr;
4
5
use std:: str;
5
6
6
7
use crate :: util:: Binding ;
7
- use crate :: { raw, signature, Error , Object , ObjectType , Oid , Signature } ;
8
+ use crate :: { call , raw, signature, Error , Object , ObjectType , Oid , Signature } ;
8
9
9
10
/// A structure to represent a git [tag][1]
10
11
///
@@ -15,6 +16,19 @@ pub struct Tag<'repo> {
15
16
}
16
17
17
18
impl < ' repo > Tag < ' repo > {
19
+ /// Determine whether a tag name is valid, meaning that (when prefixed with refs/tags/) that
20
+ /// it is a valid reference name, and that any additional tag name restrictions are imposed
21
+ /// (eg, it cannot start with a -).
22
+ pub fn is_valid_name ( tag_name : & str ) -> bool {
23
+ crate :: init ( ) ;
24
+ let tag_name = CString :: new ( tag_name) . unwrap ( ) ;
25
+ let mut valid: libc:: c_int = 0 ;
26
+ unsafe {
27
+ call:: c_try ( raw:: git_tag_name_is_valid ( & mut valid, tag_name. as_ptr ( ) ) ) . unwrap ( ) ;
28
+ }
29
+ valid == 1
30
+ }
31
+
18
32
/// Get the id (SHA1) of a repository tag
19
33
pub fn id ( & self ) -> Oid {
20
34
unsafe { Binding :: from_raw ( raw:: git_tag_id ( & * self . raw ) ) }
@@ -141,6 +155,30 @@ impl<'repo> Drop for Tag<'repo> {
141
155
142
156
#[ cfg( test) ]
143
157
mod tests {
158
+ use crate :: Tag ;
159
+
160
+ // Reference -- https://git-scm.com/docs/git-check-ref-format
161
+ #[ test]
162
+ fn name_is_valid ( ) {
163
+ assert_eq ! ( Tag :: is_valid_name( "blah_blah" ) , true ) ;
164
+ assert_eq ! ( Tag :: is_valid_name( "v1.2.3" ) , true ) ;
165
+ assert_eq ! ( Tag :: is_valid_name( "my/tag" ) , true ) ;
166
+ assert_eq ! ( Tag :: is_valid_name( "@" ) , true ) ;
167
+
168
+ assert_eq ! ( Tag :: is_valid_name( "-foo" ) , false ) ;
169
+ assert_eq ! ( Tag :: is_valid_name( "foo:bar" ) , false ) ;
170
+ assert_eq ! ( Tag :: is_valid_name( "foo^bar" ) , false ) ;
171
+ assert_eq ! ( Tag :: is_valid_name( "foo." ) , false ) ;
172
+ assert_eq ! ( Tag :: is_valid_name( "@{" ) , false ) ;
173
+ assert_eq ! ( Tag :: is_valid_name( "as\\ cd" ) , false ) ;
174
+ }
175
+
176
+ #[ test]
177
+ #[ should_panic]
178
+ fn is_valid_name_for_invalid_tag ( ) {
179
+ Tag :: is_valid_name ( "ab\0 12" ) ;
180
+ }
181
+
144
182
#[ test]
145
183
fn smoke ( ) {
146
184
let ( _td, repo) = crate :: test:: repo_init ( ) ;
0 commit comments