1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use crate::{repo, Config, Exec, Location};
use git2::Repository;
use std::io;
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
#[structopt(aliases = &["mv", "move"], about = "Relocate repository")]
pub struct Opt {
#[structopt(short, long, help = "Use regular expressions")]
pub regex: bool,
#[structopt(short, long, help = "Show detailed output")]
pub verbose: bool,
#[structopt(help = Location::about())]
pub target: Location,
#[structopt(help = Location::about())]
pub destination: Location,
}
impl Exec for Opt {
fn exec(self, config: Config) -> i32 {
let mut errors = 0;
let Self {
regex,
verbose,
mut target,
destination,
} = self;
match repo::unique(&config.src, target.clone(), regex) {
Ok(path) => {
let dest_path = config.src.join(destination.id());
let rename_res = repo::rename(&path, &dest_path);
if rename_res
.as_ref()
.err()
.map(|err| {
err.kind() == io::ErrorKind::AlreadyExists
&& match regex {
true => target.matches_re(&path),
false => target.matches(&path),
}
})
.unwrap_or(true)
{
if let Err(err) = Repository::open(&dest_path).map(|repo| {
repo.remote_set_url("origin", &destination.url())
.and_then(|_| Ok(info!("origin: {}", &destination.url())))
}) {
errors += 1;
info!("could not set remote: {}", err);
}
if rename_res.is_ok() && verbose {
info!(
"renamed '{}' to '{}'",
path.strip_prefix(config.src).unwrap().display(),
destination.id()
);
}
} else {
errors += 1;
info!("rename failed: {}", rename_res.err().unwrap())
}
}
Err(err) => {
errors += 1;
info!("{}", err)
}
}
errors
}
}