Skip to content
This repository was archived by the owner on Aug 24, 2024. It is now read-only.

Commit 3f03704

Browse files
committed
Refactor repository
This commit re-arranges everything so that migration code is in the corresponding migration folder. It also adds support for executing the code from the command line and infrastructure to add flags later.
1 parent 6d016ab commit 3f03704

File tree

10 files changed

+237
-196
lines changed

10 files changed

+237
-196
lines changed

commands/migrate.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package commands
2+
3+
import (
4+
mg1 "github.com/MichaelMure/git-bug-migration/migration1"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
func runMigrateCmd(_ *cobra.Command, _ []string) error {
9+
return mg1.Migrate01(repo)
10+
}
11+
12+
var migrateCmd = &cobra.Command{
13+
Use: "migrate",
14+
Short: "Migrate the repository to the newest version.",
15+
Long: `Migrate the repository from the current version to the newest available, bridging over breaking changes.
16+
17+
If the repository is already at the latest version, this will leave it as is. If it detects legacy features, it
18+
will update them accordingly.`,
19+
20+
PreRunE: loadRepo,
21+
RunE: runMigrateCmd,
22+
}

commands/root.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Package commands contains the CLI commands
2+
package commands
3+
4+
// Imported from git-bug and edited accordingly
5+
6+
import (
7+
"fmt"
8+
"os"
9+
10+
"github.com/spf13/cobra"
11+
12+
mg1b "github.com/MichaelMure/git-bug-migration/migration1/bug"
13+
mg1r "github.com/MichaelMure/git-bug-migration/migration1/repository"
14+
)
15+
16+
const rootCommandName = "git-bug-migration"
17+
18+
var repo mg1r.ClockedRepo
19+
20+
// RootCmd represents the base command when called without any subcommands
21+
var RootCmd = &cobra.Command{
22+
Use: rootCommandName,
23+
Short: "A migratory tool for git-bug",
24+
Long: `git-bug-migration is a tool to migrate git-bug data stored in git repository to a newer format when breaking
25+
changes are made in git-bug.
26+
27+
`,
28+
29+
// For the root command, force the execution of the PreRun
30+
// even if we just display the help. This is to make sure that we check
31+
// the repository and give the user early feedback.
32+
PreRunE: loadRepo,
33+
RunE: runMigrateCmd,
34+
35+
SilenceUsage: true,
36+
DisableAutoGenTag: true,
37+
38+
// Custom bash code to connect the git completion for "git bug migration" to the
39+
// git-bug-migration completion for "git-bug-migration"
40+
BashCompletionFunction: `
41+
_git_bug_migration() {
42+
__start_git-bug-migration "$@"
43+
}
44+
`,
45+
}
46+
47+
// loadRepo is a pre-run function that load the repository for use in a command
48+
func loadRepo(_ *cobra.Command, _ []string) error {
49+
cwd, err := os.Getwd()
50+
51+
if err != nil {
52+
panic(fmt.Errorf("unable to get the current working directory: %q", err))
53+
}
54+
55+
repo, err = mg1r.NewGitRepo(cwd, []mg1r.ClockLoader{mg1b.ClockLoader})
56+
if err == mg1r.ErrNotARepo {
57+
return fmt.Errorf("%s must be run from within a git repo", rootCommandName)
58+
} else if err != nil {
59+
return err
60+
}
61+
62+
return nil
63+
}
64+
65+
func Execute() {
66+
if err := RootCmd.Execute(); err != nil {
67+
os.Exit(1)
68+
}
69+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ require (
77
github.com/dustin/go-humanize v1.0.0
88
github.com/fatih/color v1.9.0
99
github.com/pkg/errors v0.9.1
10+
github.com/spf13/cobra v1.0.0
1011
github.com/stretchr/testify v1.6.1
1112
golang.org/x/text v0.3.3
1213
)

go.sum

Lines changed: 5 additions & 77 deletions
Large diffs are not rendered by default.

main.go

Lines changed: 2 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,7 @@
11
package main
22

3-
import (
4-
"fmt"
5-
"os"
6-
7-
mg1b "github.com/MichaelMure/git-bug-migration/migration1/bug"
8-
mg1i "github.com/MichaelMure/git-bug-migration/migration1/identity"
9-
mg1r "github.com/MichaelMure/git-bug-migration/migration1/repository"
10-
)
11-
12-
const rootCommandName = "git-bug-migration"
13-
14-
var repo mg1r.ClockedRepo
3+
import "github.com/MichaelMure/git-bug-migration/commands"
154

165
func main() {
17-
Migrate01()
18-
}
19-
20-
func Migrate01() {
21-
cwd, err := os.Getwd()
22-
if err != nil {
23-
panic(fmt.Errorf("unable to get the current working directory: %q", err))
24-
}
25-
26-
repo, err = mg1r.NewGitRepo(cwd, []mg1r.ClockLoader{mg1b.ClockLoader})
27-
if err == mg1r.ErrNotARepo {
28-
panic(fmt.Errorf("%s must be run from within a git repo", rootCommandName))
29-
}
30-
31-
identities := []*mg1i.Identity{}
32-
for streamedIdentity := range mg1i.ReadAllLocalIdentities(repo) {
33-
if streamedIdentity.Err != nil {
34-
fmt.Print(fmt.Errorf("Got error when reading identity: %q\n", err))
35-
continue
36-
}
37-
identities = append(identities, streamedIdentity.Identity)
38-
}
39-
40-
if err != nil {
41-
panic(err)
42-
}
43-
44-
// Iterating through all the bugs in the repo
45-
for streamedBug := range mg1b.ReadAllLocalBugs(repo) {
46-
if streamedBug.Err != nil {
47-
fmt.Print(fmt.Errorf("Got error when reading bug: %q\n", err))
48-
continue
49-
}
50-
51-
// Getting the old bug
52-
oldBug := streamedBug.Bug
53-
54-
b := mg1b.NewBug()
55-
bugChange := false
56-
57-
// Iterating over each operation in the bug
58-
it := mg1b.NewOperationIterator(oldBug)
59-
for it.Next() {
60-
operation := it.Value()
61-
oldAuthor := operation.GetAuthor()
62-
63-
// Checking if the author is of the legacy (bare) type
64-
switch oldAuthor.(type) {
65-
case *mg1i.Bare:
66-
fmt.Print("Detected legacyAuthor!\n")
67-
68-
bugChange = true
69-
70-
// Search existing identities for any traces of this old identity
71-
var newAuthor *mg1i.Identity = nil
72-
for _, identity := range identities {
73-
if oldAuthor.Name() == identity.Name() {
74-
newAuthor = identity
75-
}
76-
}
77-
78-
// If no existing identity is found, create a new one
79-
if newAuthor == nil {
80-
newAuthor = mg1i.NewIdentityFull(
81-
oldAuthor.Name(),
82-
oldAuthor.Email(),
83-
oldAuthor.Login(),
84-
oldAuthor.AvatarUrl(),
85-
)
86-
}
87-
88-
// Set the author of the operation to the new identity
89-
operation.SetAuthor(newAuthor)
90-
b.Append(operation)
91-
continue
92-
93-
// If the author's identity is a new identity type, its fine. Just append it to the cache
94-
case *mg1i.Identity:
95-
b.Append(operation)
96-
continue
97-
98-
// This should not be reached
99-
default:
100-
fmt.Printf("Unknown author type: %T\n", operation.GetAuthor())
101-
}
102-
}
103-
104-
// If the bug has been changed, remove the old bug and commit the new one
105-
if bugChange {
106-
err = b.Commit(repo)
107-
if err != nil {
108-
fmt.Printf("Got error when attempting to commit new bug: %q\n", err)
109-
}
110-
111-
err = mg1b.RemoveLocalBug(repo, oldBug.Id())
112-
if err != nil {
113-
fmt.Printf("Got error when attempting to remove bug: %q\n", err)
114-
}
115-
}
116-
}
6+
commands.Execute()
1177
}

migration0/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
### Vendor Information
2+
git-bug v0.4.0
3+
4+
Changes: N/A
5+
6+
Usage: This version is only used to generate a repository with legacy identities for testing purposes. It is not used in
7+
the actual migrations.

migration1/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
### Vendor Information
2+
git-bug v0.7.0
3+
4+
Changes:
5+
- Added functionality to delete bugs
6+
- Added functionality to set the author of a bug
7+
8+
Usage: This version is used to migrate the legacyAuthor from older versions to the newer versions of git-bug.

migration1/bug/operation.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ type Operation interface {
5050
AllMetadata() map[string]string
5151
// GetAuthor return the author identity
5252
GetAuthor() identity.Interface
53-
// GetAuthor sets the author identity
53+
// SetAuthor sets the author identity
5454
SetAuthor(identity.Interface)
5555

5656
// sign-post method for gqlgen

migration1/migration1.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package migration1
2+
3+
import (
4+
"fmt"
5+
6+
mg1b "github.com/MichaelMure/git-bug-migration/migration1/bug"
7+
mg1i "github.com/MichaelMure/git-bug-migration/migration1/identity"
8+
mg1r "github.com/MichaelMure/git-bug-migration/migration1/repository"
9+
)
10+
11+
var identities1 []*mg1i.Identity
12+
13+
func readIdentities(repo mg1r.ClockedRepo) {
14+
for streamedIdentity := range mg1i.ReadAllLocalIdentities(repo) {
15+
if streamedIdentity.Err != nil {
16+
fmt.Printf("Got error when reading identity: %q", streamedIdentity.Err)
17+
continue
18+
}
19+
identities1 = append(identities1, streamedIdentity.Identity)
20+
}
21+
}
22+
23+
func Migrate01(repo mg1r.ClockedRepo) error {
24+
readIdentities(repo)
25+
26+
// Iterating through all the bugs in the repo
27+
for streamedBug := range mg1b.ReadAllLocalBugs(repo) {
28+
if streamedBug.Err != nil {
29+
fmt.Printf("Got error when reading bug: %q\n", streamedBug.Err)
30+
continue
31+
}
32+
33+
oldBug := streamedBug.Bug
34+
newBug, changed, err := migrateBug01(oldBug)
35+
if err != nil {
36+
fmt.Printf("Got error when parsing bug: %q", err)
37+
}
38+
39+
// If the bug has been changed, remove the old bug and commit the new one
40+
if changed {
41+
err = newBug.Commit(repo)
42+
if err != nil {
43+
fmt.Printf("Got error when attempting to commit new bug: %q\n", err)
44+
continue
45+
}
46+
47+
err = mg1b.RemoveLocalBug(repo, oldBug.Id())
48+
if err != nil {
49+
fmt.Printf("Got error when attempting to remove bug: %q\n", err)
50+
continue
51+
}
52+
}
53+
}
54+
55+
return nil
56+
}
57+
58+
func migrateBug01(oldBug *mg1b.Bug) (*mg1b.Bug, bool, error) {
59+
// Making a new bug
60+
newBug := mg1b.NewBug()
61+
bugChange := false
62+
63+
// Iterating over each operation in the bug
64+
it := mg1b.NewOperationIterator(oldBug)
65+
for it.Next() {
66+
operation := it.Value()
67+
oldAuthor := operation.GetAuthor()
68+
69+
// Checking if the author is of the legacy (bare) type
70+
switch oldAuthor.(type) {
71+
case *mg1i.Bare:
72+
bugChange = true
73+
74+
// Search existing identities for any traces of this old identity
75+
var newAuthor *mg1i.Identity = nil
76+
for _, identity := range identities1 {
77+
if oldAuthor.Name() == identity.Name() {
78+
newAuthor = identity
79+
}
80+
}
81+
82+
// If no existing identity is found, create a new one
83+
if newAuthor == nil {
84+
newAuthor = mg1i.NewIdentityFull(
85+
oldAuthor.Name(),
86+
oldAuthor.Email(),
87+
oldAuthor.Login(),
88+
oldAuthor.AvatarUrl(),
89+
)
90+
}
91+
92+
// Set the author of the operation to the new identity
93+
operation.SetAuthor(newAuthor)
94+
newBug.Append(operation)
95+
continue
96+
97+
// If the author's identity is a new identity type, its fine. Just append it to the cache
98+
case *mg1i.Identity:
99+
newBug.Append(operation)
100+
continue
101+
102+
// This should not be reached
103+
default:
104+
return newBug, false, fmt.Errorf("Unknown author type: %T\n", operation.GetAuthor())
105+
}
106+
}
107+
108+
return newBug, bugChange, nil
109+
}

0 commit comments

Comments
 (0)