@@ -56,6 +56,53 @@ fn encoding_from_name(encoding_name: &str) -> Option<&(dyn encoding::Encoding +
56
56
}
57
57
}
58
58
59
+ /// Convert a user-supplied path to an absolute path, and convert it to a verbatim path on Windows.
60
+ fn path_from_string ( path : & str ) -> PathBuf {
61
+ let mut path = PathBuf :: from ( path) ;
62
+ // make path absolute
63
+ if path. is_relative ( ) {
64
+ path = std:: env:: current_dir ( ) . unwrap ( ) . join ( path)
65
+ } ;
66
+ let mut components = path. components ( ) ;
67
+
68
+ // make Windows paths verbatim (with `\\?\` prefixes) which allow for extended-length paths.
69
+ let mut result = match components. next ( ) {
70
+ None => unimplemented ! ( "empty path" ) ,
71
+
72
+ Some ( component) => match component {
73
+ std:: path:: Component :: Prefix ( prefix) => match prefix. kind ( ) {
74
+ std:: path:: Prefix :: Disk ( drive) => {
75
+ let root = format ! ( r"\\?\{}:\" , drive as char ) ;
76
+ PathBuf :: from ( root)
77
+ }
78
+ std:: path:: Prefix :: UNC ( server, share) => {
79
+ let mut root = std:: ffi:: OsString :: from ( r"\\?\UNC\" ) ;
80
+ root. push ( server) ;
81
+ root. push ( r"\" ) ;
82
+ root. push ( share) ;
83
+ PathBuf :: from ( root)
84
+ }
85
+ std:: path:: Prefix :: Verbatim ( _)
86
+ | std:: path:: Prefix :: VerbatimUNC ( _, _)
87
+ | std:: path:: Prefix :: VerbatimDisk ( _)
88
+ | std:: path:: Prefix :: DeviceNS ( _) => Path :: new ( & component) . to_path_buf ( ) ,
89
+ } ,
90
+ _ => Path :: new ( & component) . to_path_buf ( ) ,
91
+ } ,
92
+ } ;
93
+ // remove `.` and `..` components
94
+ for component in components {
95
+ match component {
96
+ std:: path:: Component :: CurDir => continue ,
97
+ std:: path:: Component :: ParentDir => {
98
+ result. pop ( ) ;
99
+ }
100
+ _ => result. push ( component) ,
101
+ }
102
+ }
103
+ result
104
+ }
105
+
59
106
fn main ( ) -> std:: io:: Result < ( ) > {
60
107
tracing_subscriber:: fmt ( )
61
108
. with_target ( false )
@@ -122,15 +169,15 @@ fn main() -> std::io::Result<()> {
122
169
let src_archive_dir = matches
123
170
. value_of ( "source-archive-dir" )
124
171
. expect ( "missing --source-archive-dir" ) ;
125
- let src_archive_dir = PathBuf :: from ( src_archive_dir) ;
172
+ let src_archive_dir = path_from_string ( src_archive_dir) ;
126
173
127
174
let trap_dir = matches
128
175
. value_of ( "output-dir" )
129
176
. expect ( "missing --output-dir" ) ;
130
- let trap_dir = PathBuf :: from ( trap_dir) ;
177
+ let trap_dir = path_from_string ( trap_dir) ;
131
178
132
179
let file_list = matches. value_of ( "file-list" ) . expect ( "missing --file-list" ) ;
133
- let file_list = fs:: File :: open ( file_list) ?;
180
+ let file_list = fs:: File :: open ( path_from_string ( file_list) ) ?;
134
181
135
182
let language = tree_sitter_ruby:: language ( ) ;
136
183
let erb = tree_sitter_embedded_template:: language ( ) ;
@@ -164,7 +211,7 @@ fn main() -> std::io::Result<()> {
164
211
& path,
165
212
& source,
166
213
& [ ] ,
167
- ) ? ;
214
+ ) ;
168
215
169
216
let ( ranges, line_breaks) = scan_erb (
170
217
erb,
@@ -251,7 +298,7 @@ fn main() -> std::io::Result<()> {
251
298
& path,
252
299
& source,
253
300
& code_ranges,
254
- ) ? ;
301
+ ) ;
255
302
std:: fs:: create_dir_all ( & src_archive_file. parent ( ) . unwrap ( ) ) ?;
256
303
if needs_conversion {
257
304
std:: fs:: write ( & src_archive_file, & source) ?;
0 commit comments