Skip to content

Commit f17ff8d

Browse files
committed
Added abstraction layer, mod repo_access, between main and the local git checkout implementation.
1 parent 7de17b5 commit f17ff8d

File tree

3 files changed

+101
-17
lines changed

3 files changed

+101
-17
lines changed

src/git.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ fn get_repo() -> Result<Repository, Error> {
6262
}
6363
}
6464

65-
pub fn expand_commit(sha: &str) -> Result<String, Error> {
65+
pub(crate) fn get_commit(sha: &str) -> Result<Commit, Error> {
6666
let repo = get_repo()?;
67-
let rev = lookup_rev(&repo, sha)?;
68-
Ok(rev.id().to_string())
67+
let mut rev = lookup_rev(&repo, sha)?;
68+
Ok(Commit::from_git2_commit(&mut rev))
6969
}
7070

7171
/// Returns the bors merge commits between the two specified boundaries

src/main.rs

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ use tee::TeeReader;
3131
use tempdir::TempDir;
3232
use xz2::read::XzDecoder;
3333

34-
mod git;
3534
mod least_satisfying;
35+
mod repo_access;
3636

3737
use crate::least_satisfying::{least_satisfying, Satisfies};
38+
use crate::repo_access::{AccessViaLocalGit, RustRepositoryAccessor};
3839

3940
#[derive(Debug, Clone, PartialEq)]
4041
pub struct Commit {
@@ -54,14 +55,6 @@ const EPOCH_COMMIT: &str = "927c55d86b0be44337f37cf5b0a76fb8ba86e06c";
5455
const NIGHTLY_SERVER: &str = "https://static.rust-lang.org/dist";
5556
const CI_SERVER: &str = "https://s3-us-west-1.amazonaws.com/rust-lang-ci2";
5657

57-
fn get_commits(start: &str, end: &str) -> Result<Vec<Commit>, Error> {
58-
eprintln!("fetching commits from {} to {}", start, end);
59-
let commits = git::get_commits_between(start, end)?;
60-
assert_eq!(commits.first().expect("at least one commit").sha, git::expand_commit(start)?);
61-
62-
Ok(commits)
63-
}
64-
6558
#[derive(Debug, StructOpt)]
6659
#[structopt(after_help = "EXAMPLES:
6760
Run a fully automatic nightly bisect doing `cargo check`:
@@ -152,6 +145,9 @@ struct Opts {
152145
)]
153146
by_commit: bool,
154147

148+
#[structopt(long = "access", help = "How to access Rust git repository [github|checkout]")]
149+
access: Option<String>,
150+
155151
#[structopt(long = "install", help = "Install the given artifact")]
156152
install: Option<Bound>,
157153

@@ -875,6 +871,7 @@ struct Config {
875871
toolchains_path: PathBuf,
876872
target: String,
877873
is_commit: bool,
874+
repo_access: Box<dyn RustRepositoryAccessor>,
878875
}
879876

880877
impl Config {
@@ -946,12 +943,20 @@ impl Config {
946943
}
947944
}
948945

946+
let repo_access: Box<dyn RustRepositoryAccessor>;
947+
repo_access = match args.access.as_ref().map(|x|x.as_str()) {
948+
None | Some("checkout") => Box::new(AccessViaLocalGit),
949+
Some("github") => unimplemented!(),
950+
Some(other) => bail!("unknown access argument: {}", other),
951+
};
952+
949953
Ok(Config {
950954
is_commit: args.by_commit || is_commit == Some(true),
951955
args,
952956
target,
953957
toolchains_path,
954958
rustup_tmp_path,
959+
repo_access,
955960
})
956961
}
957962
}
@@ -990,7 +995,7 @@ fn run() -> Result<(), Error> {
990995
fn install(cfg: &Config, client: &Client, bound: &Bound) -> Result<(), Error> {
991996
match *bound {
992997
Bound::Commit(ref sha) => {
993-
let sha = git::expand_commit(sha)?;
998+
let sha = cfg.repo_access.commit(sha)?.sha;
994999
let mut t = Toolchain {
9951000
spec: ToolchainSpec::Ci {
9961001
commit: sha.clone(),
@@ -1040,7 +1045,13 @@ fn bisect(cfg: &Config, client: &Client) -> Result<(), Error> {
10401045
previous_date.format(YYYY_MM_DD),
10411046
);
10421047

1043-
let ci_bisection_result = bisect_ci_between(cfg, client, &working_commit, &bad_commit)?;
1048+
let ci_bisection_result = bisect_ci_via(
1049+
cfg,
1050+
client,
1051+
&*cfg.repo_access,
1052+
&working_commit,
1053+
&bad_commit)?;
1054+
10441055
print_results(cfg, client, &ci_bisection_result);
10451056
print_final_report(&nightly_bisection_result, &ci_bisection_result);
10461057
}
@@ -1387,12 +1398,45 @@ fn bisect_ci(cfg: &Config, client: &Client) -> Result<BisectionResult, Error> {
13871398

13881399
eprintln!("starting at {}, ending at {}", start, end);
13891400

1390-
bisect_ci_between(cfg, client, start, end)
1401+
bisect_ci_via(cfg, client, &*cfg.repo_access, start, end)
13911402
}
13921403

1393-
fn bisect_ci_between(cfg: &Config, client: &Client, start: &str, end: &str) -> Result<BisectionResult, Error> {
1404+
fn bisect_ci_via(
1405+
cfg: &Config,
1406+
client: &Client,
1407+
access: &dyn RustRepositoryAccessor,
1408+
start_sha: &str,
1409+
end_sha: &str)
1410+
-> Result<BisectionResult, Error>
1411+
{
1412+
let commits = access.commits(start_sha, end_sha)?;
1413+
1414+
assert_eq!(commits.last().expect("at least one commit").sha, end_sha);
1415+
1416+
commits.iter().zip(commits.iter().skip(1)).all(|(a, b)| {
1417+
let sorted_by_date = a.date <= b.date;
1418+
assert!(sorted_by_date, "commits must chronologically ordered,\
1419+
but {:?} comes after {:?}", a, b);
1420+
sorted_by_date
1421+
});
1422+
1423+
for (j, commit) in commits.iter().enumerate() {
1424+
eprintln!(" commit[{}] {}: {}", j, commit.date.date(),
1425+
commit.summary.split("\n").next().unwrap())
1426+
}
1427+
1428+
bisect_ci_in_commits(cfg, client, &start_sha, &end_sha, commits)
1429+
}
1430+
1431+
fn bisect_ci_in_commits(
1432+
cfg: &Config,
1433+
client: &Client,
1434+
start: &str,
1435+
end: &str,
1436+
mut commits: Vec<Commit>)
1437+
-> Result<BisectionResult, Error>
1438+
{
13941439
let dl_spec = DownloadParams::for_ci(cfg);
1395-
let mut commits = get_commits(start, end)?;
13961440
let now = chrono::Utc::now();
13971441
commits.retain(|c| now.signed_duration_since(c.date).num_days() < 167);
13981442

src/repo_access.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use crate::{Bound, Commit, Error, GitDate};
2+
3+
pub(crate) trait RustRepositoryAccessor {
4+
/// Maps `bound` to its associated date, looking up its commit if necessary.
5+
fn bound_to_date(&self, bound: Bound) -> Result<GitDate, Error> {
6+
match bound {
7+
Bound::Date(date) => Ok(date),
8+
Bound::Commit(ref commit_ref) =>
9+
self.commit(commit_ref).map(|commit| commit.date.date()),
10+
}
11+
}
12+
13+
/// Looks up commit associated with `commit_ref`, which can be either a sha
14+
/// or a more general reference like "origin/master".
15+
fn commit(&self, commit_ref: &str) -> Result<Commit, Error>;
16+
17+
/// Looks up a series of commits ending with `end_sha`; the resulting series
18+
/// should start with `start_sha`. If `start_sha` is not a predecessor of
19+
/// `end_sha` in the history, then the series will cover all commits as far
20+
/// back as the date associated with `start_sha`.
21+
fn commits(&self, start_sha: &str, end_sha: &str) -> Result<Vec<Commit>, Error>;
22+
}
23+
24+
#[path="git.rs"]
25+
mod git;
26+
27+
pub(crate) struct AccessViaLocalGit;
28+
29+
impl RustRepositoryAccessor for AccessViaLocalGit {
30+
fn commit(&self, commit_ref: &str) -> Result<Commit, Error> {
31+
self::git::get_commit(commit_ref)
32+
}
33+
fn commits(&self, start_sha: &str, end_sha: &str) -> Result<Vec<Commit>, Error> {
34+
eprintln!("fetching (via local git) commits from {} to {}", start_sha, end_sha);
35+
git::get_commits_between(start_sha, end_sha)
36+
.map_err(|e| {
37+
failure::format_err!("failed during attempt to create/access local git repository: {}", e)
38+
})
39+
}
40+
}

0 commit comments

Comments
 (0)