Skip to content

Commit

Permalink
Merge pull request #553 from dlang/gitea-support
Browse files Browse the repository at this point in the history
Add Gitea support
  • Loading branch information
s-ludwig committed Oct 7, 2023
2 parents ac5eaef + 2a28612 commit ce84086
Show file tree
Hide file tree
Showing 11 changed files with 565 additions and 96 deletions.
10 changes: 5 additions & 5 deletions dub.selections.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
"botan": "1.12.19",
"botan-math": "1.0.3",
"diet-ng": "1.8.1",
"dub": "1.33.0",
"eventcore": "0.9.25",
"dub": "1.33.1",
"eventcore": "0.9.26",
"libasync": "0.8.6",
"libev": "5.0.0+4.04",
"libevent": "2.0.2+2.0.16",
"memutils": "1.0.9",
"mir-linux-kernel": "1.0.1",
"openssl": "3.3.0",
"openssl": "3.3.3",
"openssl-static": "1.0.2+3.0.8",
"stdx-allocator": "2.77.5",
"taggedalgebraic": "0.11.22",
"uritemplate": "1.0.0",
"userman": "0.4.2",
"vibe-core": "2.2.0",
"vibe-d": "0.9.7-alpha.3"
"vibe-core": "2.2.1",
"vibe-d": "0.9.7"
}
}
12 changes: 8 additions & 4 deletions source/app.d
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import dubregistry.mirror;
import dubregistry.repositories.bitbucket;
import dubregistry.repositories.github;
import dubregistry.repositories.gitlab;
import dubregistry.repositories.gitea;
import dubregistry.registry;
import dubregistry.web;
import dubregistry.api;
Expand Down Expand Up @@ -65,6 +66,8 @@ version (linux) {
// generate dummy data for e.g. Heroku's preview apps
void defaultInit(UserManController userMan, DubRegistry registry)
{
import dubregistry.repositories.repository : parseRepositoryURL;

if (environment.get("GENERATE_DEFAULT_DATA", "0") == "1" &&
registry.getPackageDump().empty && userMan.getUserCount() == 0)
{
Expand All @@ -81,7 +84,7 @@ void defaultInit(UserManController userMan, DubRegistry registry)
foreach (url; packages)
{
DbRepository repo;
repo.parseURL(URL(url));
parseRepositoryURL(URL(url), repo);
registry.addPackage(repo, userId);
}
}
Expand Down Expand Up @@ -129,9 +132,10 @@ void main()
}
}

GithubRepository.register(appConfig.ghauth);
BitbucketRepository.register(appConfig.bbuser, appConfig.bbpassword);
if (appConfig.glurl.length) GitLabRepository.register(appConfig.glauth, appConfig.glurl);
GithubRepositoryProvider.register(appConfig.ghauth);
BitbucketRepositoryProvider.register(appConfig.bbuser, appConfig.bbpassword);
if (appConfig.glurl.length) GitLabRepositoryProvider.register(appConfig.glauth, appConfig.glurl);
if (appConfig.giteaurl.length) GiteaRepositoryProvider.register(appConfig.giteaauth, appConfig.giteaurl);

auto router = new URLRouter;
if (s_mirror.length) router.any("*", (req, res) { req.params["mirror"] = s_mirror; });
Expand Down
4 changes: 4 additions & 0 deletions source/dubregistry/config.d
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public struct AppConfig
string bbuser;
@Name("bitbucket-password") @Optional
string bbpassword;
@Name("gitea-url") @Optional
string giteaurl;
@Name("gitea-auth") @Optional
string giteaauth;
@Name("enforce-certificate-trust")
bool enforceCertificateTrust = false;

Expand Down
52 changes: 1 addition & 51 deletions source/dubregistry/dbcontroller.d
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class DbController {
{
static struct PO {
BsonObjectID owner;
DbPackage.SharedUser[] sharedUsers;
@optional DbPackage.SharedUser[] sharedUsers;
}

auto p = m_packages.findOne!PO(["name": package_name], ["owner": 1, "sharedUsers": 1]);
Expand Down Expand Up @@ -543,56 +543,6 @@ struct DbRepository {
string kind;
string owner;
string project;

void parseURL(URL url)
{
string host = url.host;
if (!url.schema.among!("http", "https"))
throw new Exception("Invalid Repository Schema (only supports http and https)");
if (host.endsWith(".github.com") || host == "github.com" || host == "github") {
kind = "github";
} else if (host.endsWith(".gitlab.com") || host == "gitlab.com" || host == "gitlab") {
kind = "gitlab";
} else if (host.endsWith(".bitbucket.org") || host == "bitbucket.org" || host == "bitbucket") {
kind = "bitbucket";
} else {
throw new Exception("Please input a valid project URL to a GitHub, GitLab or BitBucket project.");
}
auto path = url.path.relativeTo(InetPath("/")).bySegment;
if (path.empty)
throw new Exception("Invalid Repository URL (no path)");
if (path.empty || path.front.name.empty)
throw new Exception("Invalid Repository URL (missing owner)");
owner = path.front.name.to!string;
path.popFront;
if (path.empty || path.front.name.empty)
throw new Exception("Invalid Repository URL (missing project)");

if(kind == "gitlab") // Allow any number of segments, as GitLab's subgroups can be nested
project = path.map!"a.name".join("/");
else
project = path.front.name.to!string;
path.popFront;
if (!path.empty && kind != "gitlab")
throw new Exception("Invalid Repository URL (got more than owner and project)");
}

unittest {
DbRepository r;
r.parseURL(URL("https://github.com/foo/bar"));
assert(r == DbRepository("github", "foo", "bar"));
r.parseURL(URL("http://bitbucket.org/bar/baz/"));
assert(r == DbRepository("bitbucket", "bar", "baz"));
r.parseURL(URL("https://gitlab.com/foo/bar"));
assert(r == DbRepository("gitlab", "foo", "bar"));
r.parseURL(URL("https://gitlab.com/group/subgroup/subsubgroup/project"));
assert(r == DbRepository("gitlab", "group", "subgroup/subsubgroup/project"));
assertThrown(r.parseURL(URL("ftp://github.com/foo/bar")));
assertThrown(r.parseURL(URL("ftp://github.com/foo/bar")));
assertThrown(r.parseURL(URL("http://github.com/foo/")));
assertThrown(r.parseURL(URL("http://github.com/")));
assertThrown(r.parseURL(URL("http://github.com/foo/bar/baz")));
}
}

struct DbPackageFile {
Expand Down
71 changes: 63 additions & 8 deletions source/dubregistry/repositories/bitbucket.d
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,69 @@ import vibe.core.stream;
import vibe.data.json;
import vibe.inet.url;

class BitbucketRepositoryProvider : RepositoryProvider {
private {
string m_user, m_password;
}
@safe:
private this(string user, string password)
{
m_user = user;
m_password = password;
}

static void register(string user, string password)
{
addRepositoryProvider("bitbucket", new BitbucketRepositoryProvider(user, password));
}

bool parseRepositoryURL(URL url, out DbRepository repo)
@safe {
import std.algorithm.searching : endsWith;
import std.conv : to;

string host = url.host;
if (!host.endsWith(".bitbucket.org") && host != "bitbucket.org" && host != "bitbucket")
return false;

repo.kind = "bitbucket";

auto path = url.path.relativeTo(InetPath("/")).bySegment;
if (path.empty)
throw new Exception("Invalid Repository URL (no path)");
if (path.front.name.empty)
throw new Exception("Invalid Repository URL (missing owner)");
repo.owner = path.front.name.to!string;
path.popFront;
if (path.empty || path.front.name.empty)
throw new Exception("Invalid Repository URL (missing project)");

repo.project = path.front.name.to!string;
path.popFront;
if (!path.empty)
throw new Exception("Invalid Repository URL (got more than owner and project)");

return true;
}

unittest {
import std.exception : assertThrown;

auto h = new BitbucketRepositoryProvider(null, null);
DbRepository r;
assert(!h.parseRepositoryURL(URL("https://github.com/foo/bar"), r));
assert(h.parseRepositoryURL(URL("http://bitbucket.org/bar/baz/"), r));
assert(r == DbRepository("bitbucket", "bar", "baz"));
assertThrown(h.parseRepositoryURL(URL("http://bitbucket.org/foo/"), r));
assertThrown(h.parseRepositoryURL(URL("http://bitbucket.org/"), r));
assertThrown(h.parseRepositoryURL(URL("http://bitbucket.org/foo/bar/baz"), r));
}

Repository getRepository(DbRepository repo)
@safe {
return new BitbucketRepository(repo.owner, repo.project, m_user, m_password);
}
}

class BitbucketRepository : Repository {
@safe:
Expand All @@ -27,14 +90,6 @@ class BitbucketRepository : Repository {
string m_authPassword;
}

static void register(string user, string password)
{
Repository factory(DbRepository info) @safe {
return new BitbucketRepository(info.owner, info.project, user, password);
}
addRepositoryFactory("bitbucket", &factory);
}

this(string owner, string project, string auth_user, string auth_password)
{
m_owner = owner;
Expand Down
Loading

0 comments on commit ce84086

Please sign in to comment.