Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Forgejo #95

Merged
merged 7 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ OPTIONS:

SUBCOMMANDS:
channel Track a Nix channel
forgejo Track a Forgejo repository
git Track a git repository
github Track a GitHub repository
gitlab Track a GitLab repository
Expand Down
60 changes: 59 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::io::Write;
use anyhow::{Context, Result};
use structopt::StructOpt;

use url::Url;
use url::{ParseError, Url};

const DEFAULT_NIX: &'static str = include_str!("default.nix");

Expand Down Expand Up @@ -140,6 +140,60 @@ impl GitHubAddOpts {
}
}

#[derive(Debug, StructOpt)]
pub struct ForgejoAddOpts {
pub server: String,
pub owner: String,
pub repository: String,

#[structopt(flatten)]
pub more: GenericGitAddOpts,
}
impl ForgejoAddOpts {
pub fn add(&self) -> Result<(String, Pin)> {
let server_url = Url::parse(&self.server).or_else(|err| match err {
ParseError::RelativeUrlWithoutBase => {
Url::parse(&("https://".to_string() + self.server.as_str()))
},
_ => Err(err),
})?;

Ok((
self.repository.clone(),
match &self.more.branch {
Some(branch) => {
let pin = git::GitPin::forgejo(
server_url,
&self.owner,
&self.repository,
branch.clone(),
self.more.submodules,
);
let version = self.more.at.as_ref().map(|at| git::GitRevision {
revision: at.clone(),
});
(pin, version).into()
},
None => {
let pin = git::GitReleasePin::forgejo(
server_url,
&self.owner,
&self.repository,
self.more.pre_releases,
self.more.version_upper_bound.clone(),
self.more.release_prefix.clone(),
self.more.submodules,
);
let version = self.more.at.as_ref().map(|at| GenericVersion {
version: at.clone(),
});
(pin, version).into()
},
},
))
}
}

#[derive(Debug, StructOpt)]
pub struct GitLabAddOpts {
/// Usually just `"owner" "repository"`, but GitLab allows arbitrary folder-like structures.
Expand Down Expand Up @@ -308,6 +362,9 @@ pub enum AddCommands {
/// Track a GitHub repository
#[structopt(name = "github")]
GitHub(GitHubAddOpts),
/// Track a Forgejo repository
#[structopt(name = "forgejo")]
Forgejo(ForgejoAddOpts),
/// Track a GitLab repository
#[structopt(name = "gitlab")]
GitLab(GitLabAddOpts),
Expand Down Expand Up @@ -338,6 +395,7 @@ impl AddOpts {
AddCommands::Channel(c) => c.add()?,
AddCommands::Git(g) => g.add()?,
AddCommands::GitHub(gh) => gh.add()?,
AddCommands::Forgejo(fg) => fg.add()?,
AddCommands::GitLab(gl) => gl.add()?,
AddCommands::PyPi(p) => p.add()?,
};
Expand Down
125 changes: 125 additions & 0 deletions src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ pub enum Repository {
/// URL to the Git repository
url: Url,
},
Forgejo {
server: Url,
owner: String,
repo: String,
},
GitHub {
/// "owner/repo"
owner: String,
Expand Down Expand Up @@ -111,6 +116,11 @@ impl Repository {
Repository::GitHub { owner, repo } => {
format!("{}/{}/{}.git", get_github_url(), owner, repo).parse()?
},
Repository::Forgejo {
server,
owner,
repo,
} => format!("{}/{}/{}.git", server, owner, repo).parse()?,
Repository::GitLab {
repo_path,
server,
Expand Down Expand Up @@ -143,6 +153,11 @@ impl Repository {
)
.parse()?,
),
Repository::Forgejo {
server,
owner,
repo,
} => Some(format!("{server}{owner}/{repo}/archive/{revision}.tar.gz",).parse()?),
Repository::GitLab {
repo_path,
server,
Expand Down Expand Up @@ -185,6 +200,13 @@ impl Repository {
)
.parse()?,
),
Repository::Forgejo {
server,
owner,
repo,
} => {
Some(format!("{server}api/v1/repos/{owner}/{repo}/archive/{tag}.tar.gz",).parse()?)
},
Repository::GitLab {
repo_path,
server,
Expand Down Expand Up @@ -262,6 +284,24 @@ impl GitPin {
}
}

pub fn forgejo(
server: Url,
owner: impl Into<String>,
repo: impl Into<String>,
branch: String,
submodules: bool,
) -> Self {
Self {
repository: Repository::Forgejo {
server,
owner: owner.into(),
repo: repo.into(),
},
branch,
submodules,
}
}

pub fn gitlab(
repo_path: String,
branch: String,
Expand Down Expand Up @@ -413,6 +453,28 @@ impl GitReleasePin {
}
}

pub fn forgejo(
server: Url,
owner: impl Into<String>,
repo: impl Into<String>,
pre_releases: bool,
version_upper_bound: Option<String>,
release_prefix: Option<String>,
submodules: bool,
) -> Self {
Self {
repository: Repository::Forgejo {
server,
owner: owner.into(),
repo: repo.into(),
},
pre_releases,
version_upper_bound,
release_prefix,
submodules,
}
}

pub fn gitlab(
repo_path: String,
server: Option<Url>,
Expand Down Expand Up @@ -943,6 +1005,69 @@ mod test {
Ok(())
}

#[tokio::test]
async fn test_forgejo_update() -> Result<()> {
let pin = GitPin {
repository: Repository::Forgejo {
server: "https://git.lix.systems".parse().unwrap(),
owner: "lix-project".into(),
repo: "lix".into(),
},
branch: "release-2.90".into(),
submodules: false,
};
let version = pin.update(None).await?;
assert_eq!(
version,
GitRevision {
revision: "4bbdb2f5564b9b42bcaf0e1eec28325300f31c72".into(),
}
);
assert_eq!(
pin.fetch(&version).await?,
OptionalUrlHashes {
url: Some("https://git.lix.systems/lix-project/lix/archive/4bbdb2f5564b9b42bcaf0e1eec28325300f31c72.tar.gz".parse().unwrap()),
hash: "03rygh7i9wzl6mhha6cv5q26iyzwy8l59d5cq4r6j5kpss9l1hn3".into(),
}
);
Ok(())
}

#[tokio::test]
async fn test_forgejo_release_update() -> Result<()> {
let pin = GitReleasePin {
repository: Repository::Forgejo {
server: "https://git.lix.systems".parse().unwrap(),
owner: "lix-project".into(),
repo: "lix".into(),
},
pre_releases: false,
version_upper_bound: Some("2.90.1".to_string()),
release_prefix: None,
submodules: false,
};
let version = pin.update(None).await?;
assert_eq!(
version,
GenericVersion {
version: "2.90.0".into(),
}
);
assert_eq!(
pin.fetch(&version).await?,
ReleasePinHashes {
revision: "2a4376be20d70feaa2b0e640c5041fb66ddc67ed".into(),
url: Some(
"https://git.lix.systems/api/v1/repos/lix-project/lix/archive/2.90.0.tar.gz"
.parse()
.unwrap()
),
hash: "1iyylsiv1n6mf6rbi4k4fm5nv24a940cwfz92gk9fx6axh2kxjbz".into(),
}
);
Ok(())
}

#[tokio::test]
async fn test_gitlab_update() -> Result<()> {
let pin = GitPin {
Expand Down
Loading