mirror of
https://github.com/deps-rs/deps.rs.git
synced 2024-11-24 11:06:31 +00:00
Support for self-hosted Gitea (#164)
deps.rs is now available for self-hosted Gitea at `/repo/gitea/<DOMAIN>/owner/repo`, e. g. `/repo/gitea/git.example.org/deps-rs/deps.rs`, `/repo/gitea/git.example.org:1234/deps-rs/deps.rs`, `/repo/gitea/http://unsafe-gitea.org/deps-rs/deps.rs`. This _should_ also include support for Gitea hosted in subdirectories, e. g. `www.example.org/gitea`, though I haven't tested this yet. If no protocol (`https://`/`http://`) is specified, `https://` is automatically added to the beginning of the gitea server's URL. However I could also change this to only accept https. Another option might be the use of URL-encoding. I am open for feedback, feel free to suggest changes. Implementation notes: - The Router now matches `/repo/*site/:qual/:name` instead of `/repo/:site/:qual/:name` to allow for an arbitrary number of `/`s before qual and name. - `RepoSite` now has a new variant `Gitea(GiteaDomain)`. - `RepoSite` no longer implements `Copy`. However this should not be problematic because `Copy`ing was only used for `to_base_uri`, `to_usercontent_base_uri` and `to_usercontent_repo_suffix` which now accept `&self` references. - `RepoSite` no longer implements `AsRef` and now uses `Display` instead. - updated test `correct_raw_url_generation` - updated readme Related to #84, #141
This commit is contained in:
parent
a991fa8eb1
commit
ba7647dcff
5 changed files with 88 additions and 28 deletions
|
@ -13,7 +13,7 @@ We currently support projects and crates hosted on crates.io, Github, Gitlab, Bi
|
|||
To analyze the state of your dependencies you can use the following URLs:
|
||||
|
||||
- for projects on crates.io: `https://deps.rs/crate/<NAME>`
|
||||
- for projects on Github, Gitlab, Bitbucket, SourceHut, or Codeberg: `https://deps.rs/repo/<HOSTER>/<USER>/<REPO>` (where `<HOSTER>` is either `github`, `gitlab`, `bitbucket`, `sourcehut`, or `codeberg`)
|
||||
- for projects on Github, Gitlab, Bitbucket, SourceHut, Codeberg, or Gitea: `https://deps.rs/repo/<HOSTER>/<USER>/<REPO>` (where `<HOSTER>` is either `github`, `gitlab`, `bitbucket`, `sourcehut`, `codeberg`, or `gitea/<DOMAIN>`)
|
||||
|
||||
## Badges
|
||||
|
||||
|
|
|
@ -42,49 +42,52 @@ impl fmt::Display for RepoPath {
|
|||
write!(
|
||||
f,
|
||||
"{} => {}/{}",
|
||||
self.site.as_ref(),
|
||||
self.site.to_string(),
|
||||
self.qual.as_ref(),
|
||||
self.name.as_ref()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub enum RepoSite {
|
||||
Github,
|
||||
Gitlab,
|
||||
Bitbucket,
|
||||
Sourcehut,
|
||||
Codeberg,
|
||||
Gitea(GiteaDomain),
|
||||
}
|
||||
|
||||
impl RepoSite {
|
||||
pub fn to_base_uri(self) -> &'static str {
|
||||
pub fn to_base_uri(&self) -> &str {
|
||||
match self {
|
||||
RepoSite::Github => "https://github.com",
|
||||
RepoSite::Gitlab => "https://gitlab.com",
|
||||
RepoSite::Bitbucket => "https://bitbucket.org",
|
||||
RepoSite::Sourcehut => "https://git.sr.ht",
|
||||
RepoSite::Codeberg => "https://codeberg.org",
|
||||
RepoSite::Gitea(domain) => domain.as_ref(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_usercontent_base_uri(self) -> &'static str {
|
||||
pub fn to_usercontent_base_uri(&self) -> &str {
|
||||
match self {
|
||||
RepoSite::Github => "https://raw.githubusercontent.com",
|
||||
RepoSite::Gitlab => "https://gitlab.com",
|
||||
RepoSite::Bitbucket => "https://bitbucket.org",
|
||||
RepoSite::Sourcehut => "https://git.sr.ht",
|
||||
RepoSite::Codeberg => "https://codeberg.org",
|
||||
RepoSite::Gitea(domain) => domain.as_ref(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_usercontent_repo_suffix(self) -> &'static str {
|
||||
pub fn to_usercontent_repo_suffix(&self) -> &'static str {
|
||||
match self {
|
||||
RepoSite::Github => "HEAD",
|
||||
RepoSite::Gitlab | RepoSite::Bitbucket => "raw/HEAD",
|
||||
RepoSite::Sourcehut => "blob/HEAD",
|
||||
RepoSite::Codeberg => "raw",
|
||||
RepoSite::Codeberg | RepoSite::Gitea(_) => "raw",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,6 +96,12 @@ impl FromStr for RepoSite {
|
|||
type Err = Error;
|
||||
|
||||
fn from_str(input: &str) -> Result<RepoSite, Error> {
|
||||
if let Some((site, domain)) = input.split_once("/") {
|
||||
match site {
|
||||
"gitea" => Ok(RepoSite::Gitea(domain.parse()?)),
|
||||
_ => Err(anyhow!("unknown repo site identifier")),
|
||||
}
|
||||
} else {
|
||||
match input {
|
||||
"github" => Ok(RepoSite::Github),
|
||||
"gitlab" => Ok(RepoSite::Gitlab),
|
||||
|
@ -102,16 +111,49 @@ impl FromStr for RepoSite {
|
|||
_ => Err(anyhow!("unknown repo site identifier")),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for RepoSite {
|
||||
fn as_ref(&self) -> &str {
|
||||
impl fmt::Display for RepoSite {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
RepoSite::Github => "github",
|
||||
RepoSite::Gitlab => "gitlab",
|
||||
RepoSite::Bitbucket => "bitbucket",
|
||||
RepoSite::Sourcehut => "sourcehut",
|
||||
RepoSite::Codeberg => "codeberg",
|
||||
RepoSite::Github => write!(f, "github"),
|
||||
RepoSite::Gitlab => write!(f, "gitlab"),
|
||||
RepoSite::Bitbucket => write!(f, "bitbucket"),
|
||||
RepoSite::Sourcehut => write!(f, "sourcehut"),
|
||||
RepoSite::Codeberg => write!(f, "codeberg"),
|
||||
RepoSite::Gitea(s) => write!(f, "gitea/{s}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct GiteaDomain(String);
|
||||
|
||||
impl FromStr for GiteaDomain {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(input: &str) -> Result<GiteaDomain, Error> {
|
||||
if input.starts_with("https://") || input.starts_with("http://") {
|
||||
Ok(GiteaDomain(input.to_string()))
|
||||
} else {
|
||||
Ok(GiteaDomain(format!("https://{input}")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for GiteaDomain {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for GiteaDomain {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if self.0.starts_with("https://") {
|
||||
f.write_str(&self.0["https://".len()..])
|
||||
} else {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -215,5 +257,21 @@ mod tests {
|
|||
let exp = format!("https://codeberg.org/deps-rs/deps.rs/raw/{}", expected);
|
||||
assert_eq!(out.to_string(), exp);
|
||||
}
|
||||
|
||||
for (input, expected) in &paths {
|
||||
let repo = RepoPath::from_parts("gitea/gitea.com", "deps-rs", "deps.rs").unwrap();
|
||||
let out = repo.to_usercontent_file_url(RelativePath::new(input));
|
||||
|
||||
let exp = format!("https://gitea.com/deps-rs/deps.rs/raw/{}", expected);
|
||||
assert_eq!(out.to_string(), exp);
|
||||
}
|
||||
|
||||
for (input, expected) in &paths {
|
||||
let repo = RepoPath::from_parts("gitea/example.com/git", "deps-rs", "deps.rs").unwrap();
|
||||
let out = repo.to_usercontent_file_url(RelativePath::new(input));
|
||||
|
||||
let exp = format!("https://example.com/git/deps-rs/deps.rs/raw/{}", expected);
|
||||
assert_eq!(out.to_string(), exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,11 +58,11 @@ impl App {
|
|||
router.add("/static/logo.svg", Route::Static(StaticFile::FaviconPng));
|
||||
|
||||
router.add(
|
||||
"/repo/:site/:qual/:name",
|
||||
"/repo/*site/:qual/:name",
|
||||
Route::RepoStatus(StatusFormat::Html),
|
||||
);
|
||||
router.add(
|
||||
"/repo/:site/:qual/:name/status.svg",
|
||||
"/repo/*site/:qual/:name/status.svg",
|
||||
Route::RepoStatus(StatusFormat::Svg),
|
||||
);
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@ fn popular_table(popular_repos: Vec<Repository>, popular_crates: Vec<CratePath>)
|
|||
@for repo in popular_repos.into_iter().take(10) {
|
||||
tr {
|
||||
td {
|
||||
a href=(format!("{}/repo/{}/{}/{}", &super::SELF_BASE_URL as &str, repo.path.site.as_ref(), repo.path.qual.as_ref(), repo.path.name.as_ref())) {
|
||||
a href=(format!("{}/repo/{}/{}/{}", &super::SELF_BASE_URL as &str, repo.path.site, repo.path.qual.as_ref(), repo.path.name.as_ref())) {
|
||||
(format!("{} / {}", repo.path.qual.as_ref(), repo.path.name.as_ref()))
|
||||
}
|
||||
}
|
||||
td class="has-text-right" {
|
||||
img src=(format!("{}/repo/{}/{}/{}/status.svg", &super::SELF_BASE_URL as &str, repo.path.site.as_ref(), repo.path.qual.as_ref(), repo.path.name.as_ref()));
|
||||
img src=(format!("{}/repo/{}/{}/{}/status.svg", &super::SELF_BASE_URL as &str, repo.path.site, repo.path.qual.as_ref(), repo.path.name.as_ref()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,9 +127,11 @@ fn get_site_icon(site: &RepoSite) -> (FaType, &'static str) {
|
|||
RepoSite::Github => (FaType::Brands, "github"),
|
||||
RepoSite::Gitlab => (FaType::Brands, "gitlab"),
|
||||
RepoSite::Bitbucket => (FaType::Brands, "bitbucket"),
|
||||
// FIXME: There is no brands/{sourcehut, codeberg} icon, so just use a
|
||||
// FIXME: There is no brands/{sourcehut, codeberg, gitea} icon, so just use a
|
||||
// regular circle which looks close enough.
|
||||
RepoSite::Sourcehut | RepoSite::Codeberg => (FaType::Regular, "circle"),
|
||||
RepoSite::Sourcehut | RepoSite::Codeberg | RepoSite::Gitea(_) => {
|
||||
(FaType::Regular, "circle")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,7 +336,7 @@ fn render_success(
|
|||
let self_path = match subject_path {
|
||||
SubjectPath::Repo(ref repo_path) => format!(
|
||||
"repo/{}/{}/{}",
|
||||
repo_path.site.as_ref(),
|
||||
repo_path.site,
|
||||
repo_path.qual.as_ref(),
|
||||
repo_path.name.as_ref()
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue