From 5cd1d6c93ba9b8399f826e671b8940eb5294b872 Mon Sep 17 00:00:00 2001 From: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com> Date: Tue, 28 Mar 2023 19:55:03 +0200 Subject: Set repository link based on the url in package.json for npm packages (#20379) automatically set repository link for package based on the repository url present inside package.json closes #20146 --- models/repo/repo.go | 43 +++++++++++++++++++++++++++++++++ models/repo/repo_test.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) (limited to 'models') diff --git a/models/repo/repo.go b/models/repo/repo.go index dcffb63fd1..3653dae015 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -658,6 +658,49 @@ func GetRepositoryByName(ownerID int64, name string) (*Repository, error) { return repo, err } +// getRepositoryURLPathSegments returns segments (owner, reponame) extracted from a url +func getRepositoryURLPathSegments(repoURL string) []string { + if strings.HasPrefix(repoURL, setting.AppURL) { + return strings.Split(strings.TrimPrefix(repoURL, setting.AppURL), "/") + } + + sshURLVariants := [4]string{ + setting.SSH.Domain + ":", + setting.SSH.User + "@" + setting.SSH.Domain + ":", + "git+ssh://" + setting.SSH.Domain + "/", + "git+ssh://" + setting.SSH.User + "@" + setting.SSH.Domain + "/", + } + + for _, sshURL := range sshURLVariants { + if strings.HasPrefix(repoURL, sshURL) { + return strings.Split(strings.TrimPrefix(repoURL, sshURL), "/") + } + } + + return nil +} + +// GetRepositoryByURL returns the repository by given url +func GetRepositoryByURL(ctx context.Context, repoURL string) (*Repository, error) { + // possible urls for git: + // https://my.domain/sub-path//.git + // https://my.domain/sub-path// + // git+ssh://user@my.domain//.git + // git+ssh://user@my.domain// + // user@my.domain:/.git + // user@my.domain:/ + + pathSegments := getRepositoryURLPathSegments(repoURL) + + if len(pathSegments) != 2 { + return nil, fmt.Errorf("unknown or malformed repository URL") + } + + ownerName := pathSegments[0] + repoName := strings.TrimSuffix(pathSegments[1], ".git") + return GetRepositoryByOwnerAndName(ctx, ownerName, repoName) +} + // GetRepositoryByID returns the repository by given id if exists. func GetRepositoryByID(ctx context.Context, id int64) (*Repository, error) { repo := new(Repository) diff --git a/models/repo/repo_test.go b/models/repo/repo_test.go index fb473151eb..92a58ea3f9 100644 --- a/models/repo/repo_test.go +++ b/models/repo/repo_test.go @@ -124,3 +124,65 @@ func TestMetas(t *testing.T) { assert.Equal(t, "user3", metas["org"]) assert.Equal(t, ",owners,team1,", metas["teams"]) } + +func TestGetRepositoryByURL(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + t.Run("InvalidPath", func(t *testing.T) { + repo, err := repo_model.GetRepositoryByURL(db.DefaultContext, "something") + + assert.Nil(t, repo) + assert.Error(t, err) + }) + + t.Run("ValidHttpURL", func(t *testing.T) { + test := func(t *testing.T, url string) { + repo, err := repo_model.GetRepositoryByURL(db.DefaultContext, url) + + assert.NotNil(t, repo) + assert.NoError(t, err) + + assert.Equal(t, repo.ID, int64(2)) + assert.Equal(t, repo.OwnerID, int64(2)) + } + + test(t, "https://try.gitea.io/user2/repo2") + test(t, "https://try.gitea.io/user2/repo2.git") + }) + + t.Run("ValidGitSshURL", func(t *testing.T) { + test := func(t *testing.T, url string) { + repo, err := repo_model.GetRepositoryByURL(db.DefaultContext, url) + + assert.NotNil(t, repo) + assert.NoError(t, err) + + assert.Equal(t, repo.ID, int64(2)) + assert.Equal(t, repo.OwnerID, int64(2)) + } + + test(t, "git+ssh://sshuser@try.gitea.io/user2/repo2") + test(t, "git+ssh://sshuser@try.gitea.io/user2/repo2.git") + + test(t, "git+ssh://try.gitea.io/user2/repo2") + test(t, "git+ssh://try.gitea.io/user2/repo2.git") + }) + + t.Run("ValidImplicitSshURL", func(t *testing.T) { + test := func(t *testing.T, url string) { + repo, err := repo_model.GetRepositoryByURL(db.DefaultContext, url) + + assert.NotNil(t, repo) + assert.NoError(t, err) + + assert.Equal(t, repo.ID, int64(2)) + assert.Equal(t, repo.OwnerID, int64(2)) + } + + test(t, "sshuser@try.gitea.io:user2/repo2") + test(t, "sshuser@try.gitea.io:user2/repo2.git") + + test(t, "try.gitea.io:user2/repo2") + test(t, "try.gitea.io:user2/repo2.git") + }) +} -- cgit v1.2.3