@@ -5,12 +5,9 @@ use std::path::PathBuf;
5
5
use toml;
6
6
7
7
use errors:: { CustomError , DirError } ;
8
+ use util:: read_file;
8
9
use Error ;
9
10
10
- lazy_static ! {
11
- static ref REQUIRED_FIELDS : [ & ' static str ; 3 ] = [ "title" , "description_file" , "grader_file" ] ;
12
- }
13
-
14
11
#[ derive( Debug , StructOpt ) ]
15
12
pub enum ChalCommand {
16
13
/// Import challenges from a directory into the database
@@ -46,6 +43,20 @@ impl ChalImportCommand {
46
43
} ;
47
44
let path = entry. path ( ) ;
48
45
46
+ match path
47
+ . file_name ( )
48
+ . and_then ( |ostr| ostr. to_str ( ) )
49
+ . and_then ( |name| {
50
+ if name. starts_with ( "." ) {
51
+ None
52
+ } else {
53
+ Some ( ( ) )
54
+ }
55
+ } ) {
56
+ Some ( _) => ( ) ,
57
+ None => continue ,
58
+ }
59
+
49
60
// find problem.toml
50
61
let problem_toml_path = path. join ( "problem.toml" ) ;
51
62
if !problem_toml_path. exists ( ) {
@@ -57,21 +68,7 @@ impl ChalImportCommand {
57
68
}
58
69
59
70
// read the problem file
60
- let problem_contents = match {
61
- let mut file = match File :: open ( & problem_toml_path) {
62
- Ok ( file) => file,
63
- Err ( err) => {
64
- return Err ( CustomError :: new ( format ! ( "Error accessing file: {}" , err) ) . into ( ) )
65
- }
66
- } ;
67
- let mut contents = String :: new ( ) ;
68
- match file. read_to_string ( & mut contents) {
69
- Ok ( _) => Ok :: < _ , Error > ( contents) ,
70
- Err ( err) => {
71
- Err ( CustomError :: new ( format ! ( "Error reading file: {}" , err) ) . into ( ) )
72
- }
73
- }
74
- } {
71
+ let problem_contents = match read_file ( & problem_toml_path) {
75
72
Ok ( problem) => problem,
76
73
Err ( err) => {
77
74
failed. push ( ( Some ( path) , err) ) ;
@@ -102,31 +99,77 @@ impl ChalImportCommand {
102
99
} ;
103
100
104
101
// check for the existence of required fields
105
- let mut flag = false ;
106
- for field in REQUIRED_FIELDS . iter ( ) {
107
- if !problem_toml . contains_key ( field . to_owned ( ) ) {
102
+ let title = match problem_toml . get ( "title" ) {
103
+ Some ( toml :: Value :: String ( title ) ) => title ,
104
+ _ => {
108
105
failed. push ( (
109
106
Some ( path) ,
110
- CustomError :: new ( format ! (
111
- "problem.toml is missing required key '{}'" ,
112
- field
113
- ) ) . into ( ) ,
107
+ CustomError :: new ( "String key 'title' not found." ) . into ( ) ,
114
108
) ) ;
115
- flag = true ;
116
- break ;
109
+ continue ;
117
110
}
118
- }
119
- if flag {
120
- continue ;
121
- }
111
+ } ;
112
+ let description = match (
113
+ problem_toml. get ( "description" ) ,
114
+ problem_toml. get ( "description_file" ) ,
115
+ ) {
116
+ ( Some ( _) , Some ( _) ) => {
117
+ failed. push ( (
118
+ Some ( path) ,
119
+ CustomError :: new ( "Cannot use both 'description' and 'description_file'." )
120
+ . into ( ) ,
121
+ ) ) ;
122
+ continue ;
123
+ }
124
+ ( Some ( toml:: Value :: String ( description) ) , None ) => description. clone ( ) ,
125
+ ( None , Some ( toml:: Value :: String ( description_file) ) ) => {
126
+ match read_file ( & description_file) {
127
+ Ok ( description) => description,
128
+ Err ( err) => {
129
+ failed. push ( ( Some ( path) , err. into ( ) ) ) ;
130
+ continue ;
131
+ }
132
+ }
133
+ }
134
+ _ => {
135
+ failed. push ( (
136
+ Some ( path) ,
137
+ CustomError :: new ( "Neither 'description' nor 'description_file' found." )
138
+ . into ( ) ,
139
+ ) ) ;
140
+ continue ;
141
+ }
142
+ } ;
143
+ let grader = match problem_toml. get ( "grader" ) {
144
+ Some ( toml:: Value :: String ( grader_path) ) => {
145
+ let path = PathBuf :: from ( & grader_path) ;
146
+ if !path. exists ( ) {
147
+ failed. push ( (
148
+ Some ( path) ,
149
+ CustomError :: new ( "Grader file not found." ) . into ( ) ,
150
+ ) ) ;
151
+ continue ;
152
+ }
153
+ path
154
+ }
155
+ _ => {
156
+ failed. push ( (
157
+ Some ( path) ,
158
+ CustomError :: new ( "String key 'grader' not found." ) . into ( ) ,
159
+ ) ) ;
160
+ continue ;
161
+ }
162
+ } ;
122
163
}
123
164
124
165
if failed. len ( ) > 0 {
125
166
error ! ( "Failed to load directories:" ) ;
126
167
for ( path, err) in failed {
127
- error ! ( " - {:?}: {}" , path, err) ;
168
+ error ! ( " - {:?}: {:? }" , path, err) ;
128
169
}
170
+ return Err ( CustomError :: new ( "Failed to import some challenges." ) . into ( ) ) ;
129
171
}
172
+ info ! ( "Successfully imported all challenges." ) ;
130
173
Ok ( ( ) )
131
174
}
132
175
}
0 commit comments