@@ -31,13 +31,15 @@ struct TomlCrate {
3131 versions : Option < Vec < String > > ,
3232 git_url : Option < String > ,
3333 git_hash : Option < String > ,
34+ path : Option < String > ,
3435}
3536
36- // represents an archive we download from crates.io
37+ // represents an archive we download from crates.io, or a git repo, or a local repo
3738#[ derive( Debug , Serialize , Deserialize , Eq , Hash , PartialEq ) ]
3839enum CrateSource {
3940 CratesIo { name : String , version : String } ,
4041 Git { name : String , url : String , commit : String } ,
42+ Path { name : String , path : PathBuf } ,
4143}
4244
4345// represents the extracted sourcecode of a crate
@@ -111,7 +113,7 @@ impl CrateSource {
111113 } ,
112114 CrateSource :: Git { name, url, commit } => {
113115 let repo_path = {
114- let mut repo_path = PathBuf :: from ( "target/lintcheck/downloads " ) ;
116+ let mut repo_path = PathBuf :: from ( "target/lintcheck/crates " ) ;
115117 // add a -git suffix in case we have the same crate from crates.io and a git repo
116118 repo_path. push ( format ! ( "{}-git" , name) ) ;
117119 repo_path
@@ -139,6 +141,37 @@ impl CrateSource {
139141 path : repo_path,
140142 }
141143 } ,
144+ CrateSource :: Path { name, path } => {
145+ use fs_extra:: dir;
146+
147+ // simply copy the entire directory into our target dir
148+ let copy_dest = PathBuf :: from ( "target/lintcheck/crates/" ) ;
149+
150+ // the source path of the crate we copied, ${copy_dest}/crate_name
151+ let crate_root = copy_dest. join ( name) ; // .../crates/local_crate
152+
153+ if !crate_root. exists ( ) {
154+ println ! ( "Copying {} to {}" , path. display( ) , copy_dest. display( ) ) ;
155+
156+ dir:: copy ( path, & copy_dest, & dir:: CopyOptions :: new ( ) ) . expect ( & format ! (
157+ "Failed to copy from {}, to {}" ,
158+ path. display( ) ,
159+ crate_root. display( )
160+ ) ) ;
161+ } else {
162+ println ! (
163+ "Not copying {} to {}, destination already exists" ,
164+ path. display( ) ,
165+ crate_root. display( )
166+ ) ;
167+ }
168+
169+ Crate {
170+ version : String :: from ( "local" ) ,
171+ name : name. clone ( ) ,
172+ path : crate_root,
173+ }
174+ } ,
142175 }
143176 }
144177}
@@ -211,6 +244,13 @@ fn read_crates(toml_path: Option<&str>) -> (String, Vec<CrateSource>) {
211244 // multiple Cratesources)
212245 let mut crate_sources = Vec :: new ( ) ;
213246 tomlcrates. into_iter ( ) . for_each ( |tk| {
247+ if let Some ( ref path) = tk. path {
248+ crate_sources. push ( CrateSource :: Path {
249+ name : tk. name . clone ( ) ,
250+ path : PathBuf :: from ( path) ,
251+ } ) ;
252+ }
253+
214254 // if we have multiple versions, save each one
215255 if let Some ( ref versions) = tk. versions {
216256 versions. iter ( ) . for_each ( |ver| {
@@ -234,7 +274,10 @@ fn read_crates(toml_path: Option<&str>) -> (String, Vec<CrateSource>) {
234274 {
235275 eprintln ! ( "tomlkrate: {:?}" , tk) ;
236276 if tk. git_hash . is_some ( ) != tk. git_url . is_some ( ) {
237- panic ! ( "Encountered TomlCrate with only one of git_hash and git_url!" )
277+ panic ! ( "Error: Encountered TomlCrate with only one of git_hash and git_url!" ) ;
278+ }
279+ if tk. path . is_some ( ) && ( tk. git_hash . is_some ( ) || tk. versions . is_some ( ) ) {
280+ panic ! ( "Error: TomlCrate can only have one of 'git_.*', 'version' or 'path' fields" ) ;
238281 }
239282 unreachable ! ( "Failed to translate TomlCrate into CrateSource!" ) ;
240283 }
@@ -298,6 +341,7 @@ pub fn run(clap_config: &ArgMatches) {
298341 let name = match krate {
299342 CrateSource :: CratesIo { name, .. } => name,
300343 CrateSource :: Git { name, .. } => name,
344+ CrateSource :: Path { name, .. } => name,
301345 } ;
302346 name == only_one_crate
303347 } ) {
0 commit comments