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