14
14
//! currently always a crate name.
15
15
16
16
use std:: collections:: BTreeMap ;
17
- use std:: env;
18
17
use std:: path:: PathBuf ;
19
- use std:: fs:: { read_dir , create_dir_all, OpenOptions , File } ;
20
- use std:: io:: { Read , Write } ;
18
+ use std:: fs:: { remove_file , create_dir_all, File } ;
19
+ use std:: io:: Write ;
21
20
use std:: error:: Error ;
22
- use rustc_serialize:: json:: { self , as_json} ;
21
+ use rustc_serialize:: json:: as_json;
23
22
24
23
use codemap:: Span ;
25
24
use ext:: base:: ExtCtxt ;
26
25
use diagnostics:: plugin:: { ErrorMap , ErrorInfo } ;
27
26
28
- pub use self :: Uniqueness :: * ;
29
-
30
27
// Default metadata directory to use for extended error JSON.
31
- const ERROR_METADATA_DIR_DEFAULT : & ' static str = "tmp/extended-errors" ;
32
-
33
- // The name of the environment variable that sets the metadata dir.
34
- const ERROR_METADATA_VAR : & ' static str = "ERROR_METADATA_DIR" ;
28
+ const ERROR_METADATA_PREFIX : & ' static str = "tmp/extended-errors" ;
35
29
36
30
/// JSON encodable/decodable version of `ErrorInfo`.
37
31
#[ derive( PartialEq , RustcDecodable , RustcEncodable ) ]
@@ -61,84 +55,32 @@ impl ErrorLocation {
61
55
}
62
56
}
63
57
64
- /// Type for describing the uniqueness of a set of error codes, as returned by `check_uniqueness`.
65
- pub enum Uniqueness {
66
- /// All errors in the set checked are unique according to the metadata files checked.
67
- Unique ,
68
- /// One or more errors in the set occur in another metadata file.
69
- /// This variant contains the first duplicate error code followed by the name
70
- /// of the metadata file where the duplicate appears.
71
- Duplicate ( String , String )
72
- }
73
-
74
- /// Get the directory where metadata files should be stored.
75
- pub fn get_metadata_dir ( ) -> PathBuf {
76
- match env:: var ( ERROR_METADATA_VAR ) {
77
- Ok ( v) => From :: from ( v) ,
78
- Err ( _) => From :: from ( ERROR_METADATA_DIR_DEFAULT )
79
- }
80
- }
81
-
82
- /// Get the path where error metadata for the set named by `name` should be stored.
83
- fn get_metadata_path ( name : & str ) -> PathBuf {
84
- get_metadata_dir ( ) . join ( format ! ( "{}.json" , name) )
58
+ /// Get the directory where metadata for a given `prefix` should be stored.
59
+ ///
60
+ /// See `output_metadata`.
61
+ pub fn get_metadata_dir ( prefix : & str ) -> PathBuf {
62
+ PathBuf :: from ( ERROR_METADATA_PREFIX ) . join ( prefix)
85
63
}
86
64
87
- /// Check that the errors in `err_map` aren't present in any metadata files in the
88
- /// metadata directory except the metadata file corresponding to `name`.
89
- pub fn check_uniqueness ( name : & str , err_map : & ErrorMap ) -> Result < Uniqueness , Box < Error > > {
90
- let metadata_dir = get_metadata_dir ( ) ;
91
- let metadata_path = get_metadata_path ( name) ;
92
-
93
- // Create the error directory if it does not exist.
94
- try!( create_dir_all ( & metadata_dir) ) ;
95
-
96
- // Check each file in the metadata directory.
97
- for entry in try!( read_dir ( & metadata_dir) ) {
98
- let path = try!( entry) . path ( ) ;
99
-
100
- // Skip any existing file for this set.
101
- if path == metadata_path {
102
- continue ;
103
- }
104
-
105
- // Read the metadata file into a string.
106
- let mut metadata_str = String :: new ( ) ;
107
- try!(
108
- File :: open ( & path) . and_then ( |mut f|
109
- f. read_to_string ( & mut metadata_str) )
110
- ) ;
111
-
112
- // Parse the JSON contents.
113
- let metadata: ErrorMetadataMap = try!( json:: decode ( & metadata_str) ) ;
114
-
115
- // Check for duplicates.
116
- for err in err_map. keys ( ) {
117
- let err_code = err. as_str ( ) ;
118
- if metadata. contains_key ( err_code) {
119
- return Ok ( Duplicate (
120
- err_code. to_string ( ) ,
121
- path. to_string_lossy ( ) . into_owned ( )
122
- ) ) ;
123
- }
124
- }
125
- }
126
-
127
- Ok ( Unique )
65
+ /// Map `name` to a path in the given directory: <directory>/<name>.json
66
+ fn get_metadata_path ( directory : PathBuf , name : & str ) -> PathBuf {
67
+ directory. join ( format ! ( "{}.json" , name) )
128
68
}
129
69
130
- /// Write metadata for the errors in `err_map` to disk, to a file corresponding to `name`.
131
- pub fn output_metadata ( ecx : & ExtCtxt , name : & str , err_map : & ErrorMap )
70
+ /// Write metadata for the errors in `err_map` to disk, to a file corresponding to `prefix/name`.
71
+ ///
72
+ /// For our current purposes the prefix is the target architecture and the name is a crate name.
73
+ /// If an error occurs steps will be taken to ensure that no file is created.
74
+ pub fn output_metadata ( ecx : & ExtCtxt , prefix : & str , name : & str , err_map : & ErrorMap )
132
75
-> Result < ( ) , Box < Error > >
133
76
{
134
- let metadata_path = get_metadata_path ( name) ;
77
+ // Create the directory to place the file in.
78
+ let metadata_dir = get_metadata_dir ( prefix) ;
79
+ try!( create_dir_all ( & metadata_dir) ) ;
135
80
136
- // Open the dump file.
137
- let mut dump_file = try!( OpenOptions :: new ( )
138
- . write ( true )
139
- . create ( true )
140
- . open ( & metadata_path)
141
- ) ;
81
+ // Open the metadata file.
82
+ let metadata_path = get_metadata_path ( metadata_dir, name) ;
83
+ let mut metadata_file = try!( File :: create ( & metadata_path) ) ;
142
84
143
85
// Construct a serializable map.
144
86
let json_map = err_map. iter ( ) . map ( |( k, & ErrorInfo { description, use_site } ) | {
@@ -150,6 +92,10 @@ pub fn output_metadata(ecx: &ExtCtxt, name: &str, err_map: &ErrorMap)
150
92
( key, value)
151
93
} ) . collect :: < ErrorMetadataMap > ( ) ;
152
94
153
- try!( write ! ( & mut dump_file, "{}" , as_json( & json_map) ) ) ;
154
- Ok ( ( ) )
95
+ // Write the data to the file, deleting it if the write fails.
96
+ let result = write ! ( & mut metadata_file, "{}" , as_json( & json_map) ) ;
97
+ if result. is_err ( ) {
98
+ try!( remove_file ( & metadata_path) ) ;
99
+ }
100
+ Ok ( try!( result) )
155
101
}
0 commit comments