@@ -31,7 +31,14 @@ fn main() {
3131
3232 let migration_subcommand = SubCommand :: with_name ( "migration" )
3333 . setting ( AppSettings :: VersionlessSubcommands )
34- . subcommand (
34+ . arg ( Arg :: with_name ( "MIGRATION_DIRECTORY" )
35+ . long ( "migration-dir" )
36+ . help ( "The location of your migration directory. By default this \
37+ will look for a directory called `migrations` in the \
38+ current directory and its parents.")
39+ . takes_value ( true )
40+ . global ( true )
41+ ) . subcommand (
3542 SubCommand :: with_name ( "run" )
3643 . about ( "Runs all pending migrations" )
3744 ) . subcommand (
@@ -102,11 +109,11 @@ fn run_migration_command(matches: &ArgMatches) {
102109 match matches. subcommand ( ) {
103110 ( "run" , Some ( _) ) => {
104111 call_with_conn ! ( database_url, migrations:: run_pending_migrations)
105- . map_err ( handle_error) . unwrap ( ) ;
112+ . unwrap_or_else ( handle_error) ;
106113 }
107114 ( "revert" , Some ( _) ) => {
108115 call_with_conn ! ( database_url, migrations:: revert_latest_migration)
109- . map_err ( handle_error) . unwrap ( ) ;
116+ . unwrap_or_else ( handle_error) ;
110117 }
111118 ( "redo" , Some ( _) ) => {
112119 call_with_conn ! ( database_url, redo_latest_migration) ;
@@ -115,13 +122,12 @@ fn run_migration_command(matches: &ArgMatches) {
115122 let migration_name = args. value_of ( "MIGRATION_NAME" ) . unwrap ( ) ;
116123 let version = migration_version ( args) ;
117124 let versioned_name = format ! ( "{}_{}" , version, migration_name) ;
118- let mut migration_dir = migrations:: find_migrations_directory ( )
119- . map_err ( handle_error) . unwrap ( ) . join ( versioned_name) ;
125+ let migration_dir = migrations_dir ( args) . join ( versioned_name) ;
120126 fs:: create_dir ( & migration_dir) . unwrap ( ) ;
121127
122128 let migration_dir_relative = convert_absolute_path_to_relative (
123- & mut migration_dir,
124- & mut env:: current_dir ( ) . unwrap ( )
129+ & migration_dir,
130+ & env:: current_dir ( ) . unwrap ( )
125131 ) ;
126132
127133 let up_path = migration_dir. join ( "up.sql" ) ;
@@ -141,12 +147,23 @@ fn migration_version<'a>(matches: &'a ArgMatches) -> Box<Display + 'a> {
141147 . unwrap_or_else ( || Box :: new ( Local :: now ( ) . format ( "%Y%m%d%H%M%S" ) ) )
142148}
143149
150+ fn migrations_dir ( matches : & ArgMatches ) -> PathBuf {
151+ matches. value_of ( "MIGRATION_DIRECTORY" )
152+ . map ( PathBuf :: from)
153+ . or_else ( || {
154+ env:: var ( "MIGRATION_DIRECTORY" ) . map ( PathBuf :: from) . ok ( )
155+ } ) . unwrap_or_else ( || {
156+ migrations:: find_migrations_directory ( )
157+ . unwrap_or_else ( handle_error)
158+ } )
159+ }
160+
144161fn run_setup_command ( matches : & ArgMatches ) {
145162 migrations:: find_migrations_directory ( )
146- . unwrap_or_else ( |_|
147- create_migrations_directory ( )
148- . map_err ( handle_error) . unwrap ( )
149- ) ;
163+ . unwrap_or_else ( |_| {
164+ create_migrations_directory ( )
165+ . unwrap_or_else ( handle_error)
166+ } ) ;
150167
151168 database:: setup_database ( matches) . unwrap_or_else ( handle_error) ;
152169}
@@ -204,22 +221,23 @@ fn redo_latest_migration<Conn>(conn: &Conn) where
204221 } ) . unwrap_or_else ( handle_error) ;
205222}
206223
207- fn handle_error < E : Error > ( error : E ) {
224+ fn handle_error < E : Error , T > ( error : E ) -> T {
208225 panic ! ( "{}" , error) ;
209226}
210227
211228// Converts an absolute path to a relative path, with the restriction that the
212229// target path must be in the same directory or above the current path.
213- fn convert_absolute_path_to_relative ( target_path : & mut PathBuf , current_path : & mut PathBuf )
230+ fn convert_absolute_path_to_relative ( target_path : & Path , mut current_path : & Path )
214231 -> PathBuf
215232{
216233 let mut result = PathBuf :: new ( ) ;
217- let target_path = target_path. as_path ( ) ;
218- let mut current_path = current_path. as_path ( ) ;
219234
220235 while !target_path. starts_with ( current_path) {
221236 result. push ( ".." ) ;
222- current_path = current_path. parent ( ) . unwrap ( ) ;
237+ match current_path. parent ( ) {
238+ Some ( parent) => current_path = parent,
239+ None => return target_path. into ( ) ,
240+ }
223241 }
224242
225243 result. join ( strip_prefix ( target_path, current_path) )
@@ -291,19 +309,19 @@ mod tests {
291309 #[ test]
292310 fn convert_absolute_path_to_relative_works ( ) {
293311 assert_eq ! ( PathBuf :: from( "migrations/12345_create_user" ) ,
294- convert_absolute_path_to_relative( & mut PathBuf :: from( "projects/foo/migrations/12345_create_user" ) ,
295- & mut PathBuf :: from( "projects/foo" ) ) ) ;
312+ convert_absolute_path_to_relative( & PathBuf :: from( "projects/foo/migrations/12345_create_user" ) ,
313+ & PathBuf :: from( "projects/foo" ) ) ) ;
296314 assert_eq ! ( PathBuf :: from( "../migrations/12345_create_user" ) ,
297- convert_absolute_path_to_relative( & mut PathBuf :: from( "projects/foo/migrations/12345_create_user" ) ,
298- & mut PathBuf :: from( "projects/foo/src" ) ) ) ;
315+ convert_absolute_path_to_relative( & PathBuf :: from( "projects/foo/migrations/12345_create_user" ) ,
316+ & PathBuf :: from( "projects/foo/src" ) ) ) ;
299317 assert_eq ! ( PathBuf :: from( "../../../migrations/12345_create_user" ) ,
300- convert_absolute_path_to_relative( & mut PathBuf :: from( "projects/foo/migrations/12345_create_user" ) ,
301- & mut PathBuf :: from( "projects/foo/src/controllers/errors" ) ) ) ;
318+ convert_absolute_path_to_relative( & PathBuf :: from( "projects/foo/migrations/12345_create_user" ) ,
319+ & PathBuf :: from( "projects/foo/src/controllers/errors" ) ) ) ;
302320 assert_eq ! ( PathBuf :: from( "12345_create_user" ) ,
303- convert_absolute_path_to_relative( & mut PathBuf :: from( "projects/foo/migrations/12345_create_user" ) ,
304- & mut PathBuf :: from( "projects/foo/migrations" ) ) ) ;
321+ convert_absolute_path_to_relative( & PathBuf :: from( "projects/foo/migrations/12345_create_user" ) ,
322+ & PathBuf :: from( "projects/foo/migrations" ) ) ) ;
305323 assert_eq ! ( PathBuf :: from( "../12345_create_user" ) ,
306- convert_absolute_path_to_relative( & mut PathBuf :: from( "projects/foo/migrations/12345_create_user" ) ,
307- & mut PathBuf :: from( "projects/foo/migrations/67890_create_post" ) ) ) ;
324+ convert_absolute_path_to_relative( & PathBuf :: from( "projects/foo/migrations/12345_create_user" ) ,
325+ & PathBuf :: from( "projects/foo/migrations/67890_create_post" ) ) ) ;
308326 }
309327}
0 commit comments