1
+ use std:: ffi:: CString ;
1
2
use std:: marker;
2
3
use std:: mem;
3
4
use std:: ptr;
@@ -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 name_is_valid ( tag_name : & str ) -> Result < bool , Error > {
23
+ crate :: init ( ) ;
24
+ let tag_name = CString :: new ( tag_name) ?;
25
+ let mut valid: libc:: c_int = 0 ;
26
+ unsafe {
27
+ try_call ! ( raw:: git_tag_name_is_valid( & mut valid, tag_name. as_ptr( ) ) ) ;
28
+ }
29
+ Ok ( 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,29 @@ 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 :: name_is_valid( "blah_blah" ) . unwrap( ) , true ) ;
164
+ assert_eq ! ( Tag :: name_is_valid( "v1.2.3" ) . unwrap( ) , true ) ;
165
+ assert_eq ! ( Tag :: name_is_valid( "my/tag" ) . unwrap( ) , true ) ;
166
+ assert_eq ! ( Tag :: name_is_valid( "@" ) . unwrap( ) , true ) ;
167
+
168
+ assert_eq ! ( Tag :: name_is_valid( "-foo" ) . unwrap( ) , false ) ;
169
+ assert_eq ! ( Tag :: name_is_valid( "foo:bar" ) . unwrap( ) , false ) ;
170
+ assert_eq ! ( Tag :: name_is_valid( "foo^bar" ) . unwrap( ) , false ) ;
171
+ assert_eq ! ( Tag :: name_is_valid( "foo." ) . unwrap( ) , false ) ;
172
+ assert_eq ! ( Tag :: name_is_valid( "@{" ) . unwrap( ) , false ) ;
173
+ assert_eq ! ( Tag :: name_is_valid( "as\\ cd" ) . unwrap( ) , false ) ;
174
+
175
+ assert_eq ! (
176
+ Tag :: name_is_valid( "ab\0 12" ) . err( ) . unwrap( ) . to_string( ) ,
177
+ "data contained a nul byte that could not be represented as a string"
178
+ ) ;
179
+ }
180
+
144
181
#[ test]
145
182
fn smoke ( ) {
146
183
let ( _td, repo) = crate :: test:: repo_init ( ) ;
0 commit comments