Skip to content

Commit ca391b9

Browse files
chore: prepare for parallelization
1 parent ec0a077 commit ca391b9

File tree

3 files changed

+305
-254
lines changed

3 files changed

+305
-254
lines changed

src/git.rs

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::{
22
cmp::Ordering,
33
collections::BTreeSet,
4+
fmt::{self, Display},
45
path::{Path, PathBuf},
56
process::Command,
67
str,
@@ -12,6 +13,9 @@ use url::Url;
1213

1314
use crate::package::Package;
1415

16+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
17+
pub struct GitUrl(Url);
18+
1519
#[derive(Debug)]
1620
pub struct GitRepository {
1721
repo_dir: PathBuf,
@@ -32,21 +36,15 @@ pub struct GitTag<'a> {
3236
}
3337

3438
impl GitRepository {
35-
pub fn obtain(dir: &Path, url: Url) -> Result<Self> {
36-
let normalized_url = normalize_url(url)?;
37-
38-
let name = format!(
39-
"{}-{}",
40-
normalized_url.host().unwrap(),
41-
normalized_url.path().replace('/', "-")
42-
);
39+
pub fn obtain(dir: &Path, GitUrl(url): GitUrl) -> Result<Self> {
40+
let name = format!("{}-{}", url.host().unwrap(), url.path().replace('/', "-"));
4341
let repo_dir = dir.join(name);
4442
if !repo_dir.try_exists()? {
4543
let out = Command::new("git")
4644
.arg("clone")
4745
.arg("--filter=blob:none")
4846
.arg("--")
49-
.arg(normalized_url.to_string())
47+
.arg(url.to_string())
5048
.arg(&repo_dir)
5149
.env("GIT_TERMINAL_PROMPT", "0")
5250
.output()?;
@@ -228,28 +226,40 @@ impl<'a> Ord for GitTag<'a> {
228226
}
229227
}
230228

231-
fn normalize_url(url: Url) -> Result<Url> {
232-
ensure!(
233-
matches!(url.scheme(), "http" | "https"),
234-
"Bad repository scheme"
235-
);
236-
let host = url
237-
.host()
238-
.context("repository doesn't have a `host`")?
239-
.to_string();
240-
241-
Ok(if host == "github.com" || host.starts_with("gitlab.") {
242-
let mut url = url;
243-
let mut path = url.path().strip_prefix('/').unwrap().split('/');
244-
url.set_path(&format!(
245-
"/{}/{}.git",
246-
path.next().context("repository is missing user/org")?,
247-
path.next()
248-
.context("repository is missing repo name")?
249-
.trim_end_matches(".git")
250-
));
251-
url
252-
} else {
253-
url
254-
})
229+
impl TryFrom<Url> for GitUrl {
230+
type Error = anyhow::Error;
231+
232+
fn try_from(url: Url) -> Result<Self, Self::Error> {
233+
ensure!(
234+
matches!(url.scheme(), "http" | "https"),
235+
"Bad repository scheme"
236+
);
237+
let host = url
238+
.host()
239+
.context("repository doesn't have a `host`")?
240+
.to_string();
241+
242+
Ok(Self(
243+
if host == "github.com" || host.starts_with("gitlab.") {
244+
let mut url = url;
245+
let mut path = url.path().strip_prefix('/').unwrap().split('/');
246+
url.set_path(&format!(
247+
"/{}/{}.git",
248+
path.next().context("repository is missing user/org")?,
249+
path.next()
250+
.context("repository is missing repo name")?
251+
.trim_end_matches(".git")
252+
));
253+
url
254+
} else {
255+
url
256+
},
257+
))
258+
}
259+
}
260+
261+
impl Display for GitUrl {
262+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
263+
Display::fmt(&self.0, f)
264+
}
255265
}

0 commit comments

Comments
 (0)