Verified Commit 399b2070 authored by Loïc Dachary's avatar Loïc Dachary
Browse files

implement repositories

parent 86986aab
......@@ -41,6 +41,7 @@ func migrate(ctx context.Context, downloader, uploader abstract.ForgeInterface,
util.MaybeTerminate(ctx)
uploader.CreateProject(downloader.GetProject())
uploader.CreateRepositories(downloader.GetRepositories()...)
if options.Issues {
util.MaybeTerminate(ctx)
issues := downloader.GetIssues()
......
......@@ -24,6 +24,7 @@ type ForgeInterface interface {
Context(context.Context)
GetProject() *format.Project
GetRepositories() []*format.Repository
GetTopics() []string
GetMilestones() []*format.Milestone
GetReleases() []*format.Release
......@@ -36,6 +37,7 @@ type ForgeInterface interface {
GetReviews(reviewable format.Reviewable) []*format.Review
CreateProject(projects *format.Project)
CreateRepositories(repositories ...*format.Repository)
DeleteProject() *format.Project
CreateTopics(topic ...string)
CreateMilestones(milestones ...*format.Milestone)
......
......@@ -21,6 +21,7 @@ import (
"lab.forgefriends.org/friendlyforgeformat/gofff/forges/null"
"lab.forgefriends.org/friendlyforgeformat/gofff/format"
"lab.forgefriends.org/friendlyforgeformat/gofff/util"
)
type Options struct {
......@@ -51,6 +52,30 @@ func (f *File) Init(options Options) {
f.commentsPath = "comments"
}
func (f *File) GetDirectory() string {
return f.options.GetDirectory()
}
func (f *File) GetRepositories() []*format.Repository {
return []*format.Repository{
{
Directory: filepath.Join(f.options.Directory, "repository"+format.RepositoryNameDefault),
Name: format.RepositoryNameDefault,
},
}
}
func (f *File) CreateRepositories(repositories ...*format.Repository) {
for _, repository := range repositories {
origin := repository.Directory
destination := filepath.Join(f.options.Directory, "repository"+repository.Name)
if !util.FileExists(destination) {
util.Command("git", "clone", "--bare", origin, destination)
}
util.Command("git", "-C", destination, "fetch")
}
}
func (f *File) GetIssues() []*format.Issue {
return GetBeans[format.Issue](f, "issue.json")
}
......
......@@ -35,6 +35,9 @@ func TestFile(t *testing.T) {
copy.CreateReleases(original.GetReleases()...)
assert.EqualValues(t, original.GetReleases(), copy.GetReleases())
assert.NotEmpty(t, original.GetRepositories())
copy.CreateRepositories(original.GetRepositories()...)
copy.CreateProject(original.GetProject())
assert.EqualValues(t, original.GetProject(), copy.GetProject())
......
......@@ -53,17 +53,77 @@ func (f *Fixture) CopyFile() *File {
}
func (f *Fixture) AssertEquals(a, b *File) {
cmd := exec.Command("diff", "-r", a.options.Directory, b.options.Directory)
var out bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &out
assert.NoError(f.t, cmd.Run(), out.String())
_ = util.Command("diff", "--exclude=repository", "-r", a.options.Directory, b.options.Directory)
repository_a := filepath.Join(a.options.Directory, "repository")
repository_b := filepath.Join(b.options.Directory, "repository")
assert.EqualValues(f.t, util.FileExists(repository_a), util.FileExists(repository_b), fmt.Sprintf("(FileExists(%v) == %v) != (FileExists(%v) == %v)", repository_a, util.FileExists(repository_a), repository_b, util.FileExists(repository_b)))
if util.FileExists(repository_a) && util.FileExists(repository_b) {
assert.EqualValues(f.t,
util.Command("git", "-C", repository_a, "ls-tree", "--full-tree", "HEAD"),
util.Command("git", "-C", repository_b, "ls-tree", "--full-tree", "HEAD"),
)
}
}
func (f *Fixture) GetFile() *File {
return f.f
}
func (f *Fixture) GetDirectory() string {
return f.d
}
func (f *Fixture) CreateRepositories() {
directory := f.GetDefaultRepositoryDirectory()
assert.NoError(f.t, os.Mkdir(directory, 0o700))
util.Command("git", "-C", directory, "init")
}
func (f *Fixture) GetDefaultRepositoryDirectory() string {
for _, repository := range f.f.GetRepositories() {
if repository.Name == format.RepositoryNameDefault {
assert.NotEqual(f.t, repository.Directory, "")
return repository.Directory
}
}
panic("no default repository")
}
func (f *Fixture) CreateRepositoryContent(directory string) (ref, sha string) {
assert.NotEmpty(f.t, directory)
f.SetRepositoryConfig(directory)
return f.CommitREADMEConfig(directory)
}
func (f *Fixture) SetRepositoryConfig(directory string) {
util.Command("git", "-C", directory, "config", "user.email", "author@example.com")
util.Command("git", "-C", directory, "config", "user.name", "Author")
}
func (f *Fixture) CommitREADMEConfig(directory string) (ref, sha string) {
readme := fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", directory)
assert.NoError(f.t, os.WriteFile(filepath.Join(directory, "README.md"), []byte(readme), 0o644))
util.Command("git", "-C", directory, "add", "README.md")
util.Command("git", "-C", directory, "commit", "-m", "Add README", "README.md")
sha = util.Command("git", "-C", directory, "rev-parse", "HEAD")
return "master", sha
}
func (f *Fixture) BranchRepositoryFeature(directory string) (ref, sha string) {
branch := "feature"
util.Command("git", "-C", directory, "checkout", "-b", branch, "master")
assert.NoError(f.t, os.WriteFile(filepath.Join(directory, "README.md"), []byte("feature content"), 0o644))
util.Command("git", "-C", directory, "add", "README.md")
util.Command("git", "-C", directory, "commit", "-m", "feature README", "README.md")
sha = util.Command("git", "-C", directory, "rev-parse", "HEAD")
//
// back to master branch
//
util.Command("git", "-C", directory, "checkout", "master")
return branch, sha
}
func (f *Fixture) CreateProject() {
project := &format.Project{
Index: 1,
......
......@@ -39,6 +39,8 @@ type IOConstraint[IO any, Options OptionsConstraint, ProjectProviderPtr any, Pro
Init(Options)
Context(context.Context)
Finish()
GetRepository(format.Repository)
CreateRepository(format.Repository)
GetProjectProvider() ProjectProviderPtr
GetIssueProvider(ProjectPtr) IssueProviderPtr
GetCommentProvider(ProjectPtr) CommentProviderPtr
......@@ -183,6 +185,21 @@ func (f *Forge[Options, IO, Project, ProjectProvider, Issue, IssueProvider, _, _
return nil
}
func (f *Forge[Options, IO, Project, ProjectProvider, Issue, IssueProvider, Comment, CommentProvider, PullRequest, PullRequestProvider, IOPtr, ProjectPtr, ProjectProviderPtr, IssuePtr, IssueProviderPtr, CommentPtr, CommentProviderPtr, PullRequestPtr, PullRequestProviderPtr]) GetRepositories() []*format.Repository {
repository := &format.Repository{
Directory: filepath.Join(f.options.GetDirectory(), "repository"),
Name: "",
}
f.io.GetRepository(*repository)
return []*format.Repository{repository}
}
func (f *Forge[Options, IO, Project, ProjectProvider, Issue, IssueProvider, Comment, CommentProvider, PullRequest, PullRequestProvider, IOPtr, ProjectPtr, ProjectProviderPtr, IssuePtr, IssueProviderPtr, CommentPtr, CommentProviderPtr, PullRequestPtr, PullRequestProviderPtr]) CreateRepositories(repositories ...*format.Repository) {
for _, repository := range repositories {
f.io.CreateRepository(*repository)
}
}
type ForeignTranslatable interface {
GetID() int64
SetID(int64)
......
......@@ -108,6 +108,17 @@ func (g *Gitea) Context(ctx context.Context) {
g.client.SetContext(ctx)
}
func (g *Gitea) GetRepository(repository format.Repository) {
if !util.FileExists(repository.Directory) {
util.Command("git", "clone", "--bare", g.options.CloneAddr, repository.Directory)
}
util.Command("git", "-C", repository.Directory, "fetch")
}
func (g *Gitea) CreateRepository(repository format.Repository) {
util.Command("git", "-C", repository.Directory, "push", "--mirror", g.options.GetPushURL())
}
func (g Gitea) GetProjectProvider() *ProjectProvider {
return g.projectProvider
}
......
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package gitea
import (
"path/filepath"
"testing"
"lab.forgefriends.org/friendlyforgeformat/gofff/forges/file"
"lab.forgefriends.org/friendlyforgeformat/gofff/format"
"github.com/stretchr/testify/assert"
)
func TestRepository(t *testing.T) {
gi := newTestGitea(t)
project := newTestProject(gi)
assert.NotNil(t, project)
defer gi.g.GetProjectProvider().DeleteProject(gi.repoPath)
fixture := file.NewFixture(t)
fixture.CreateRepositories()
repository := fixture.GetDefaultRepositoryDirectory()
_, _ = fixture.CreateRepositoryContent(repository)
f1 := fixture.GetFile()
gi.g.CreateRepository(format.Repository{
Directory: filepath.Join(f1.GetDirectory(), "repository"),
})
f2 := fixture.CopyFile()
gi.g.GetRepository(format.Repository{
Directory: filepath.Join(f2.GetDirectory(), "repository"),
})
fixture.AssertEquals(f1, f2)
}
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
package format
const (
RepositoryNameDefault = ""
RepositoryNameWiki = ".wiki"
)
type Repository struct {
Directory string `json:"directory"`
Name string `json:"name"`
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment