@@ -26,6 +26,7 @@ pub struct ToolSpec {
26
26
pub enum Protocol {
27
27
Github ,
28
28
Gitlab ,
29
+ Artifactory ,
29
30
}
30
31
31
32
impl ToolSpec {
@@ -96,13 +97,15 @@ impl ToolSpec {
96
97
match self . protocol {
97
98
Protocol :: Github => CiString ( format ! ( "{}" , self . path) ) ,
98
99
Protocol :: Gitlab => CiString ( format ! ( "gitlab@{}" , self . path) ) ,
100
+ Protocol :: Artifactory => CiString ( format ! ( "{}@{}" , self . host, self . path) ) ,
99
101
}
100
102
}
101
103
102
104
pub fn source ( & self ) -> String {
103
105
let provider = match self . protocol {
104
106
Protocol :: Github => "github.com" ,
105
107
Protocol :: Gitlab => "gitlab.com" ,
108
+ Protocol :: Artifactory => "artifactory.com" ,
106
109
} ;
107
110
108
111
format ! ( "{}/{}" , provider, self . path)
@@ -120,6 +123,7 @@ impl ToolSpec {
120
123
match self . protocol {
121
124
Protocol :: Github => Provider :: Github ,
122
125
Protocol :: Gitlab => Provider :: Gitlab ,
126
+ Protocol :: Artifactory => Provider :: Artifactory ,
123
127
}
124
128
}
125
129
}
@@ -130,7 +134,7 @@ impl fmt::Display for ToolSpec {
130
134
}
131
135
}
132
136
133
- #[ derive( Debug ) ]
137
+ #[ derive( Debug , PartialEq ) ]
134
138
pub struct ConfigFile {
135
139
pub tools : BTreeMap < String , ToolSpec > ,
136
140
pub hosts : HashMap < String , Host > ,
@@ -149,6 +153,57 @@ impl Host {
149
153
protocol,
150
154
}
151
155
}
156
+
157
+ pub fn from_value ( value : & Value ) -> ConfigFileParseResult < Self > {
158
+ if let Value :: Table ( mut map) = value. clone ( ) {
159
+ let source = map
160
+ . remove ( "source" )
161
+ . ok_or_else ( || ConfigFileParseError :: Host {
162
+ host : value. to_string ( ) ,
163
+ } ) ?
164
+ . as_str ( )
165
+ . ok_or_else ( || ConfigFileParseError :: Host {
166
+ host : value. to_string ( ) ,
167
+ } ) ?
168
+ . to_string ( ) ;
169
+
170
+ let protocol_value =
171
+ map. remove ( "protocol" )
172
+ . ok_or_else ( || ConfigFileParseError :: Host {
173
+ host : value. to_string ( ) ,
174
+ } ) ?;
175
+
176
+ if !map. is_empty ( ) {
177
+ return Err ( ConfigFileParseError :: Host {
178
+ host : value. to_string ( ) ,
179
+ } ) ;
180
+ }
181
+
182
+ let protocol_str =
183
+ protocol_value
184
+ . as_str ( )
185
+ . ok_or_else ( || ConfigFileParseError :: Host {
186
+ host : value. to_string ( ) ,
187
+ } ) ?;
188
+
189
+ let protocol = match protocol_str {
190
+ "github" => Protocol :: Github ,
191
+ "gitlab" => Protocol :: Gitlab ,
192
+ "artifactory" => Protocol :: Artifactory ,
193
+ _ => {
194
+ return Err ( ConfigFileParseError :: InvalidProtocol {
195
+ protocol : protocol_str. to_string ( ) ,
196
+ } )
197
+ }
198
+ } ;
199
+
200
+ Ok ( Self { source, protocol } )
201
+ } else {
202
+ Err ( ConfigFileParseError :: Host {
203
+ host : value. to_string ( ) ,
204
+ } )
205
+ }
206
+ }
152
207
}
153
208
154
209
impl ConfigFile {
@@ -167,6 +222,18 @@ impl ConfigFile {
167
222
let mut config = ConfigFile :: new_with_defaults ( ) ;
168
223
169
224
if let Value :: Table ( top_level) = & value {
225
+ if let Some ( hosts) = & top_level. get ( "hosts" ) {
226
+ if let Value :: Table ( hosts) = hosts {
227
+ for ( host, toml) in hosts {
228
+ let host_source =
229
+ Host :: from_value ( & toml) . map_err ( |_| ConfigFileParseError :: Tool {
230
+ tool : value. to_string ( ) ,
231
+ } ) ?;
232
+ config. hosts . insert ( host. to_owned ( ) , host_source) ;
233
+ }
234
+ }
235
+ }
236
+
170
237
if let Some ( tools) = & top_level. get ( "tools" ) {
171
238
if let Value :: Table ( tools) = tools {
172
239
for ( tool, toml) in tools {
@@ -260,6 +327,7 @@ impl fmt::Display for ConfigFile {
260
327
261
328
#[ cfg( test) ]
262
329
mod test {
330
+ const ARTIFACTORY : & ' static str = "https://artifactory.com" ;
263
331
use super :: * ;
264
332
265
333
fn new_github < S : Into < String > > ( github : S , version : VersionReq ) -> ToolSpec {
@@ -280,10 +348,32 @@ mod test {
280
348
}
281
349
}
282
350
351
+ fn new_artifactory < S : Into < String > > ( host : S , path : S , version : VersionReq ) -> ToolSpec {
352
+ ToolSpec {
353
+ host : host. into ( ) ,
354
+ path : path. into ( ) ,
355
+ version : version,
356
+ protocol : Protocol :: Artifactory ,
357
+ }
358
+ }
359
+
360
+ fn new_config ( tools : BTreeMap < String , ToolSpec > , hosts : HashMap < String , Host > ) -> ConfigFile {
361
+ let mut config = ConfigFile :: new_with_defaults ( ) ;
362
+ config. fill_from ( ConfigFile { tools, hosts } ) ;
363
+ config
364
+ }
365
+
283
366
fn version ( string : & str ) -> VersionReq {
284
367
VersionReq :: parse ( string) . unwrap ( )
285
368
}
286
369
370
+ fn new_host < S : Into < String > > ( source : S , protocol : Protocol ) -> Host {
371
+ Host {
372
+ source : source. into ( ) ,
373
+ protocol,
374
+ }
375
+ }
376
+
287
377
fn default_hosts ( ) -> HashMap < String , Host > {
288
378
HashMap :: from ( [
289
379
(
@@ -301,7 +391,17 @@ mod test {
301
391
] )
302
392
}
303
393
394
+ fn artifactory_host ( ) -> HashMap < String , Host > {
395
+ let mut hosts = default_hosts ( ) ;
396
+ hosts. insert (
397
+ "artifactory" . to_string ( ) ,
398
+ Host :: new ( ARTIFACTORY . to_string ( ) , Protocol :: Artifactory ) ,
399
+ ) ;
400
+ hosts
401
+ }
402
+
304
403
mod deserialization {
404
+
305
405
use super :: * ;
306
406
307
407
#[ test]
@@ -333,25 +433,65 @@ mod test {
333
433
assert_eq ! ( gitlab, new_gitlab( "user/repo" , version( "0.1.0" ) ) ) ;
334
434
}
335
435
436
+ #[ test]
437
+ fn artifactory_from_artifactory_field ( ) {
438
+ let value: Value = toml:: from_str (
439
+ & [
440
+ r#"artifactory = "generic-rbx-local-tools/rotriever/""# ,
441
+ r#"version = "0.5.4""# ,
442
+ ]
443
+ . join ( "\n " ) ,
444
+ )
445
+ . unwrap ( ) ;
446
+
447
+ let artifactory = ToolSpec :: from_value ( & value, & artifactory_host ( ) ) . unwrap ( ) ;
448
+ assert_eq ! (
449
+ artifactory,
450
+ new_artifactory(
451
+ "https://artifactory.com" ,
452
+ "generic-rbx-local-tools/rotriever/" ,
453
+ version( "0.5.4" )
454
+ )
455
+ ) ;
456
+ }
457
+
458
+ #[ test]
459
+ fn host_artifactory ( ) {
460
+ let value: Value = toml:: from_str (
461
+ & [
462
+ r#"source = "https://artifactory.com""# ,
463
+ r#"protocol = "artifactory""# ,
464
+ ]
465
+ . join ( "\n " ) ,
466
+ )
467
+ . unwrap ( ) ;
468
+
469
+ let host = Host :: from_value ( & value) . unwrap ( ) ;
470
+ assert_eq ! (
471
+ host,
472
+ new_host( "https://artifactory.com" , Protocol :: Artifactory )
473
+ )
474
+ }
475
+
336
476
#[ test]
337
477
fn extraneous_fields_tools ( ) {
338
478
let value: Value = toml:: from_str (
339
479
& [
340
- r#"github = "Roblox /rotriever""# ,
341
- r#"path = "Roblox /rotriever""# ,
480
+ r#"rbx_artifactory = "generic-rbx-local-tools /rotriever/ ""# ,
481
+ r#"path = "generic-rbx-local-tools /rotriever/ ""# ,
342
482
r#"version = "0.5.4""# ,
343
483
]
344
484
. join ( "\n " ) ,
345
485
)
346
486
. unwrap ( ) ;
347
487
348
- let artifactory = ToolSpec :: from_value ( & value, & default_hosts ( ) ) . unwrap_err ( ) ;
488
+ let artifactory = ToolSpec :: from_value ( & value, & artifactory_host ( ) ) . unwrap_err ( ) ;
349
489
assert_eq ! (
350
490
artifactory,
351
491
ConfigFileParseError :: Tool {
352
492
tool: [
353
- r#"github = "Roblox /rotriever""# ,
354
- r#"path = "Roblox /rotriever""# ,
493
+ r#"path = "generic-rbx-local-tools /rotriever/ ""# ,
494
+ r#"rbx_artifactory = "generic-rbx-local-tools /rotriever/ ""# ,
355
495
r#"version = "0.5.4""# ,
356
496
r#""# ,
357
497
]
@@ -360,6 +500,68 @@ mod test {
360
500
}
361
501
)
362
502
}
503
+
504
+ #[ test]
505
+ fn extraneous_fields_host ( ) {
506
+ let value: Value = toml:: from_str (
507
+ & [
508
+ r#"source = "https://artifactory.com""# ,
509
+ r#"protocol = "artifactory""# ,
510
+ r#"extra = "field""# ,
511
+ ]
512
+ . join ( "\n " ) ,
513
+ )
514
+ . unwrap ( ) ;
515
+
516
+ let err = Host :: from_value ( & value) . unwrap_err ( ) ;
517
+ assert_eq ! (
518
+ err,
519
+ ConfigFileParseError :: Host {
520
+ host: [
521
+ r#"extra = "field""# ,
522
+ r#"protocol = "artifactory""# ,
523
+ r#"source = "https://artifactory.com""# ,
524
+ r#""# ,
525
+ ]
526
+ . join( "\n " )
527
+ . to_string( )
528
+ }
529
+ )
530
+ }
531
+ #[ test]
532
+ fn config_file_with_hosts ( ) {
533
+ let value: Value = toml:: from_str ( & [
534
+ r#"[hosts]"# ,
535
+ r#"artifactory = {source = "https://artifactory.com", protocol = "artifactory"}"# ,
536
+ r#""# ,
537
+ r#"[tools]"# ,
538
+ r#"tool = {artifactory = "path/to/tool", version = "1.0.0"}"# ,
539
+ ] . join ( "\n " ) )
540
+ . unwrap ( ) ;
541
+
542
+ let config = ConfigFile :: from_value ( value) . unwrap ( ) ;
543
+ assert_eq ! (
544
+ config,
545
+ new_config(
546
+ BTreeMap :: from( [ (
547
+ "tool" . to_string( ) ,
548
+ ToolSpec {
549
+ host: "https://artifactory.com" . to_string( ) ,
550
+ path: "path/to/tool" . to_string( ) ,
551
+ version: VersionReq :: parse( "1.0.0" ) . unwrap( ) ,
552
+ protocol: Protocol :: Artifactory
553
+ }
554
+ ) ] ) ,
555
+ HashMap :: from( [ (
556
+ "artifactory" . to_string( ) ,
557
+ Host {
558
+ source: "https://artifactory.com" . to_string( ) ,
559
+ protocol: Protocol :: Artifactory
560
+ }
561
+ ) ] )
562
+ )
563
+ )
564
+ }
363
565
}
364
566
365
567
#[ test]
0 commit comments