Skip to content
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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ mpd:
per: student
startercode:
url: git@gitlab.example.org:mpd/startercode/blatt-01.git
fromBranch: template
fromBranch: startercode
template: true
templateMessage: Initial Commit
```

### 3) Validate config and generate repos
Expand Down
9 changes: 9 additions & 0 deletions config/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ func startercode(assignmentKey string) *Startercode {
fromBranch = fB
}

template := viper.GetBool(assignmentKey + ".startercode.template")

templateMessage := "Initial"
if tM := viper.GetString(assignmentKey + ".startercode.templateMessage"); len(tM) > 0 {
templateMessage = tM
}

toBranch := "main"
if tB := viper.GetString(assignmentKey + ".startercode.toBranch"); len(tB) > 0 {
toBranch = tB
Expand All @@ -37,6 +44,8 @@ func startercode(assignmentKey string) *Startercode {
return &Startercode{
URL: url,
FromBranch: fromBranch,
Template: template,
TemplateMessage: templateMessage,
ToBranch: toBranch,
AdditionalBranches: additionalBranches,
}
Expand Down
2 changes: 2 additions & 0 deletions config/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ func (cfg *AssignmentConfig) Show() {
} else {
writeSectionField("URL", cfg.Startercode.URL)
writeSectionField("FromBranch", cfg.Startercode.FromBranch)
writeSectionField("Template", cfg.Startercode.Template)
writeSectionField("TemplateMessage", cfg.Startercode.TemplateMessage)
writeSectionField("ToBranch", cfg.Startercode.ToBranch)
writeSectionField("AdditionalBranches", cfg.Startercode.AdditionalBranches)
}
Expand Down
2 changes: 2 additions & 0 deletions config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ type Seeder struct {
type Startercode struct {
URL string
FromBranch string
Template bool
TemplateMessage string
ToBranch string
AdditionalBranches []string
}
Expand Down
4 changes: 3 additions & 1 deletion docs/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ mpd:
blatt02:
startercode:
url: git@gitlab.lrz.de:mpd/starter.git
fromBranch: template
fromBranch: startercode
toBranch: main
template: true
templateMessage: Initial Startercode

branches:
- name: main
Expand Down
8 changes: 7 additions & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,13 @@ mpd:
per: student
startercode:
url: git@gitlab.example.org:mpd/startercode/blatt-01.git
fromBranch: template
fromBranch: startercode
template: true
```

If you set `template: true` all commits in startercode will be squashed to just
one commit using the `templateMessage`.

## Important defaults at a glance

| Area | Key | Default |
Expand All @@ -84,6 +88,8 @@ mpd:
| Assignment | `mergeRequest.allThreadsMustBeResolved` | `false` |
| Assignment | `mergeRequest.statusChecksMustSucceed` | `false` |
| Startercode | `fromBranch` | `main` |
| Startercode | `template` | `false` |
| Startercode | `templateMessage` | `Initial` |
| Startercode | `toBranch` | `main` |
| Startercode | `additionalBranches` | `[]` |
| Branches | first `branches[].default` | `true` on first branch |
Expand Down
82 changes: 39 additions & 43 deletions git/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
gitlab "gitlab.com/gitlab-org/api/client-go/v2"
)

func CloneBranch(url, fromBranch string, orphan bool, orphanMessage string) (*git.Repository, plumbing.ReferenceName, error) {
func CloneBranch(url, fromBranch string, singleCommit bool, commitMessage string) (*SourceRepo, error) {
cfg := yacspin.Config{
Frequency: 100 * time.Millisecond,
CharSet: yacspin.CharSets[69],
Expand Down Expand Up @@ -46,7 +46,7 @@ func CloneBranch(url, fromBranch string, orphan bool, orphanMessage string) (*gi
auth, err := GetAuth()
if err != nil {
fmt.Printf("error: %v", err)
return nil, "", err
return nil, err
}

storer := memory.NewStorage()
Expand All @@ -67,7 +67,7 @@ func CloneBranch(url, fromBranch string, orphan bool, orphanMessage string) (*gi
if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}
return nil, "", err
return nil, err
}

wt, err := repo.Worktree()
Expand All @@ -78,7 +78,7 @@ func CloneBranch(url, fromBranch string, orphan bool, orphanMessage string) (*gi
if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}
return nil, "", err
return nil, err
}

if err := wt.Checkout(&git.CheckoutOptions{
Expand All @@ -91,11 +91,15 @@ func CloneBranch(url, fromBranch string, orphan bool, orphanMessage string) (*gi
if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}
return nil, "", err
return nil, err
}

if !orphan {
return repo, sourceRef, nil
if !singleCommit {
return &SourceRepo{
Repo: repo,
Ref: sourceRef,
Auth: auth,
}, nil
}

headRef, err := repo.Head()
Expand All @@ -106,7 +110,7 @@ func CloneBranch(url, fromBranch string, orphan bool, orphanMessage string) (*gi
if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}
return nil, "", err
return nil, err
}

headCommit, err := repo.CommitObject(headRef.Hash())
Expand All @@ -117,7 +121,7 @@ func CloneBranch(url, fromBranch string, orphan bool, orphanMessage string) (*gi
if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}
return nil, "", err
return nil, err
}

tree, err := headCommit.Tree()
Expand All @@ -128,11 +132,11 @@ func CloneBranch(url, fromBranch string, orphan bool, orphanMessage string) (*gi
if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}
return nil, "", err
return nil, err
}

orphanBranchName := fmt.Sprintf("orphan-%s-%d", fromBranch, time.Now().UnixNano())
orphanRef := plumbing.NewBranchReferenceName(orphanBranchName)
singleCommitBranchName := fmt.Sprintf("orphan-%s-%d", fromBranch, time.Now().UnixNano())
refName := plumbing.NewBranchReferenceName(singleCommitBranchName)

committerName := "glabs"
committerEmail := "glabs-bot@noreply.example.com"
Expand All @@ -154,7 +158,7 @@ func CloneBranch(url, fromBranch string, orphan bool, orphanMessage string) (*gi
Email: committerEmail,
When: now,
},
Message: orphanMessage,
Message: commitMessage,
TreeHash: tree.Hash,
}

Expand All @@ -166,7 +170,7 @@ func CloneBranch(url, fromBranch string, orphan bool, orphanMessage string) (*gi
if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}
return nil, "", err
return nil, err
}

commitHash, err := repo.Storer.SetEncodedObject(encoded)
Expand All @@ -177,34 +181,34 @@ func CloneBranch(url, fromBranch string, orphan bool, orphanMessage string) (*gi
if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}
return nil, "", err
return nil, err
}

if err := repo.Storer.SetReference(plumbing.NewHashReference(orphanRef, commitHash)); err != nil {
if err := repo.Storer.SetReference(plumbing.NewHashReference(refName, commitHash)); err != nil {
spinner.StopFailMessage(fmt.Sprintf("problem: %v", err))

err := spinner.StopFail()
if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}
return nil, "", err
return nil, err
}

if err := repo.CreateBranch(&gitconfig.Branch{
Name: orphanRef.Short(),
Merge: orphanRef,
Name: refName.Short(),
Merge: refName,
}); err != nil && err != git.ErrBranchExists {
spinner.StopFailMessage(fmt.Sprintf("problem: %v", err))

err := spinner.StopFail()
if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}
return nil, "", err
return nil, err
}

if err := wt.Checkout(&git.CheckoutOptions{
Branch: orphanRef,
Branch: refName,
Force: true,
}); err != nil {
spinner.StopFailMessage(fmt.Sprintf("problem: %v", err))
Expand All @@ -213,26 +217,30 @@ func CloneBranch(url, fromBranch string, orphan bool, orphanMessage string) (*gi
if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}
return nil, "", err
return nil, err
}

if orphan {
spinner.StopMessage(fmt.Sprintf("using branch '%s' with single commit '%s'", orphanRef.Short(), orphanMessage))
if singleCommit {
spinner.StopMessage(fmt.Sprintf("using branch '%s' with single commit '%s'", refName.Short(), commitMessage))
}
errs := spinner.Stop()
if errs != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}

return repo, orphanRef, nil
return &SourceRepo{
Repo: repo,
Ref: refName,
Auth: auth,
}, nil
}

func PushBranch(assignmentCfg *config.AssignmentConfig, projectname string, repo *git.Repository, localRef plumbing.ReferenceName, toBranch string, force bool, project *gitlab.Project) error {
func PushBranch(assignmentCfg *config.AssignmentConfig, projectname string, sourceRepo *SourceRepo, toBranch string, force bool, project *gitlab.Project) error {
cfg := yacspin.Config{
Frequency: 100 * time.Millisecond,
CharSet: yacspin.CharSets[69],
Suffix: aurora.Sprintf(aurora.Cyan(" pushing branch %s to project %s / branch %s"),
aurora.Yellow(localRef.Short()),
aurora.Yellow(sourceRepo.Ref.Short()),
aurora.Magenta(assignmentCfg.URL+"/"+project.Name),
aurora.Magenta(toBranch),
),
Expand All @@ -258,7 +266,7 @@ func PushBranch(assignmentCfg *config.AssignmentConfig, projectname string, repo
URLs: []string{project.SSHURLToRepo},
}

remote, err := repo.CreateRemote(conf)
remote, err := sourceRepo.Repo.CreateRemote(conf)
if err != nil {
spinner.StopFailMessage(fmt.Sprintf("problem: %v", err))

Expand All @@ -272,30 +280,18 @@ func PushBranch(assignmentCfg *config.AssignmentConfig, projectname string, repo
return fmt.Errorf("cannot create remote: %w", err)
}

auth, err := GetAuth()
if err != nil {
spinner.StopFailMessage(fmt.Sprintf("problem: %v", err))

err := spinner.StopFail()
if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}
fmt.Printf("error: %v", err)
return err
}

spec := localRef.String() + ":" + plumbing.NewBranchReferenceName(toBranch).String()
spec := sourceRepo.Ref.String() + ":" + plumbing.NewBranchReferenceName(toBranch).String()
if force {
spec = "+" + spec
}

pushOpts := &git.PushOptions{
RemoteName: remote.Config().Name,
RefSpecs: []gitconfig.RefSpec{gitconfig.RefSpec(spec)},
Auth: auth,
Auth: sourceRepo.Auth,
}

err = repo.Push(pushOpts)
err = sourceRepo.Repo.Push(pushOpts)
if err != nil {
spinner.StopFailMessage(fmt.Sprintf("problem: %v", err))

Expand Down
7 changes: 1 addition & 6 deletions git/starterrepo.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,12 @@ import (

git "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
"github.com/go-git/go-git/v5/storage/memory"
"github.com/logrusorgru/aurora"
"github.com/rs/zerolog/log"
"github.com/theckman/yacspin"
)

type SourceRepo struct {
Repo *git.Repository
Auth ssh.AuthMethod
}

func PrepareSourceRepo(url, fromBranch string) (*SourceRepo, error) {
cfg := yacspin.Config{
Frequency: 100 * time.Millisecond,
Expand Down Expand Up @@ -71,6 +65,7 @@ func PrepareSourceRepo(url, fromBranch string) (*SourceRepo, error) {

return &SourceRepo{
Repo: r,
Ref: plumbing.ReferenceName("refs/heads/" + fromBranch),
Auth: auth,
}, nil
}
13 changes: 13 additions & 0 deletions git/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package git

import (
git "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
)

type SourceRepo struct {
Repo *git.Repository
Ref plumbing.ReferenceName
Auth ssh.AuthMethod
}
2 changes: 1 addition & 1 deletion gitlab/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (c *Client) Generate(assignmentCfg *config.AssignmentConfig) {
var starterrepo *git.SourceRepo

if assignmentCfg.Startercode != nil {
starterrepo, err = git.PrepareSourceRepo(assignmentCfg.Startercode.URL, assignmentCfg.Startercode.FromBranch)
starterrepo, err = git.CloneBranch(assignmentCfg.Startercode.URL, assignmentCfg.Startercode.FromBranch, assignmentCfg.Startercode.Template, assignmentCfg.Startercode.TemplateMessage)

if err != nil {
fmt.Println(err)
Expand Down
4 changes: 2 additions & 2 deletions gitlab/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func (c *Client) Push(assignmentCfg *config.AssignmentConfig, branchname string)
return fmt.Errorf("error: no config for deferred branch \"%s\" found\n", branchname)
}

repo, branchRef, err := git.CloneBranch(branch.URL, branch.FromBranch, branch.Orphan, branch.OrphanMessage)
sourceRepo, err := git.CloneBranch(branch.URL, branch.FromBranch, branch.Orphan, branch.OrphanMessage)
if err != nil {
return err
}
Expand All @@ -39,7 +39,7 @@ func (c *Client) Push(assignmentCfg *config.AssignmentConfig, branchname string)
return err
}

err = git.PushBranch(assignmentCfg, projectname, repo, branchRef, branch.ToBranch, true, project)
err = git.PushBranch(assignmentCfg, projectname, sourceRepo, branch.ToBranch, true, project)
if err != nil {
return err
}
Expand Down
Loading
Loading