Skip to content

Commit 6371c7b

Browse files
committed
Use go-git for common git operations instead of calling the git
command using `os/exec` This patch updates all the helper functions to use `go-git` library instead of having to call `os/exec.Command`/`os/exec.CombinedOutput` in order to clone repository, fetch tags... These changes brings more dependencies to our `go.mod` but in exchange it simplifies the way we interact with git repositories and improves errors handling and readability. Future changes will also benefit from this patch, especially conversation webhook generator that will need to checkout multiple version tags.
1 parent 32c9216 commit 6371c7b

File tree

9 files changed

+221
-43
lines changed

9 files changed

+221
-43
lines changed

cmd/ack-generate/command/apis.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func generateAPIs(cmd *cobra.Command, args []string) error {
7878
if optOutputPath == "" {
7979
optOutputPath = filepath.Join(optServicesDir, svcAlias)
8080
}
81-
if err := ensureSDKRepo(optCacheDir); err != nil {
81+
if err := ensureSDKRepo(optCacheDir, optRefreshCache); err != nil {
8282
return err
8383
}
8484
sdkHelper := model.NewSDKHelper(sdkDir)

cmd/ack-generate/command/common.go

Lines changed: 66 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@
1414
package command
1515

1616
import (
17+
"context"
1718
"fmt"
1819
"io/ioutil"
1920
"os"
20-
"os/exec"
2121
"path/filepath"
2222
"strings"
2323

2424
"golang.org/x/mod/modfile"
25+
26+
"github.com/aws-controllers-k8s/code-generator/pkg/util"
2527
)
2628

2729
const (
@@ -64,67 +66,93 @@ func isDirWriteable(fp string) bool {
6466
// ensureSDKRepo ensures that we have a git clone'd copy of the aws-sdk-go
6567
// repository, which we use model JSON files from. Upon successful return of
6668
// this function, the sdkDir global variable will be set to the directory where
67-
// the aws-sdk-go is found
68-
func ensureSDKRepo(cacheDir string) error {
69+
// the aws-sdk-go is found. It will also optionally fetch all the remote tags
70+
// and checkout the given tag.
71+
func ensureSDKRepo(
72+
cacheDir string,
73+
// A boolean instructing ensureSDKRepo whether to fetch the remote tags from
74+
// the upstream repository
75+
fetchTags bool,
76+
) error {
6977
var err error
7078
srcPath := filepath.Join(cacheDir, "src")
7179
if err = os.MkdirAll(srcPath, os.ModePerm); err != nil {
7280
return err
7381
}
74-
// clone the aws-sdk-go repository locally so we can query for API
75-
// information in the models/apis/ directories
76-
sdkDir, err = cloneSDKRepo(srcPath)
77-
return err
78-
}
7982

80-
// cloneSDKRepo git clone's the aws-sdk-go source repo into the cache and
81-
// returns the filepath to the clone'd repo. If the aws-sdk-go repository
82-
// already exists in the cache, it will checkout the current sdk-go version
83-
// mentionned in 'go.mod' file.
84-
func cloneSDKRepo(srcPath string) (string, error) {
85-
sdkVersion, err := getSDKVersion()
86-
if err != nil {
87-
return "", err
83+
// Clone repository if it doen't exist
84+
sdkDir = filepath.Join(srcPath, "aws-sdk-go")
85+
if _, err := os.Stat(sdkDir); os.IsNotExist(err) {
86+
err = util.CloneRepository(context.Background(), sdkDir, sdkRepoURL)
87+
if err != nil {
88+
return fmt.Errorf("canot clone repository: %v", err)
89+
}
8890
}
89-
clonePath := filepath.Join(srcPath, "aws-sdk-go")
90-
if optRefreshCache {
91-
if _, err := os.Stat(filepath.Join(clonePath, ".git")); !os.IsNotExist(err) {
92-
cmd := exec.Command("git", "-C", clonePath, "fetch", "--all", "--tags")
93-
if err = cmd.Run(); err != nil {
94-
return "", err
95-
}
96-
cmd = exec.Command("git", "-C", clonePath, "checkout", "tags/"+sdkVersion)
97-
return clonePath, cmd.Run()
91+
92+
// Fetch all tags
93+
if fetchTags {
94+
err = util.FetchRepositoryTags(context.Background(), sdkDir)
95+
if err != nil {
96+
return fmt.Errorf("cannot fetch tags: %v", err)
9897
}
9998
}
100-
if _, err := os.Stat(clonePath); os.IsNotExist(err) {
101-
cmd := exec.Command("git", "clone", "-b", sdkVersion, sdkRepoURL, clonePath)
102-
return clonePath, cmd.Run()
99+
100+
// get sdkVersion and correct it (adds missing 'v')
101+
sdkVersion, err := getSDKVersion("")
102+
if err != nil {
103+
return err
104+
}
105+
sdkVersion = correctSemanticVersion(sdkVersion)
106+
107+
// Now checkout the local repository.
108+
repo, err := util.LoadRepository(sdkDir)
109+
if err != nil {
110+
return fmt.Errorf("cannot read local repository: %v", err)
111+
}
112+
113+
err = util.CheckoutRepositoryTag(repo, sdkVersion)
114+
if err != nil {
115+
return fmt.Errorf("cannot checkout tag: %v", err)
103116
}
104-
return clonePath, nil
117+
118+
return err
119+
}
120+
121+
// correctSemanticVersion takes a semver string and tries to append the 'v'
122+
// prefix if it's missing.
123+
func correctSemanticVersion(s string) string {
124+
if strings.HasPrefix(s, "v") {
125+
return s
126+
}
127+
return fmt.Sprintf("v%s", s)
105128
}
106129

107130
// getSDKVersion returns the github.com/aws/aws-sdk-go version to use. It
108-
// first tries to get return version from the --aws-sdk-go-version flag, then
109-
// look for the service controller and local go.mod files.
110-
func getSDKVersion() (string, error) {
131+
// first tries to get the version from the --aws-sdk-go-version flag, then
132+
// from the ack-generate-metadata.yaml and finally look for the service
133+
// go.mod controller.
134+
func getSDKVersion(
135+
//TODO(a-hilaly) Parse ack-generate-metadata.yaml and pass the aws-sdk-go
136+
// version here.
137+
lastGenerationVersion string,
138+
) (string, error) {
111139
// First try to get the version from --aws-sdk-go-version flag
112140
if optAWSSDKGoVersion != "" {
113141
return optAWSSDKGoVersion, nil
114142
}
115143

144+
// then, try to use last generation version (from ack-generate-metadata.yaml)
145+
if lastGenerationVersion != "" {
146+
return lastGenerationVersion, nil
147+
}
148+
116149
// then, try to parse the service controller go.mod file
117150
sdkVersion, err := getSDKVersionFromGoMod(filepath.Join(optOutputPath, "go.mod"))
118151
if err == nil {
119152
return sdkVersion, nil
120153
}
121154

122-
// then try to parse a local go.mod
123-
sdkVersion, err = getSDKVersionFromGoMod("go.mod")
124-
if err != nil {
125-
return "", err
126-
}
127-
return sdkVersion, nil
155+
return "", err
128156
}
129157

130158
// getSDKVersionFromGoMod parses a given go.mod file and returns

cmd/ack-generate/command/controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func generateController(cmd *cobra.Command, args []string) error {
5757
optOutputPath = filepath.Join(optServicesDir, svcAlias)
5858
}
5959

60-
if err := ensureSDKRepo(optCacheDir); err != nil {
60+
if err := ensureSDKRepo(optCacheDir, optRefreshCache); err != nil {
6161
return err
6262
}
6363
sdkHelper := ackmodel.NewSDKHelper(sdkDir)

cmd/ack-generate/command/crossplane.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func generateCrossplane(_ *cobra.Command, args []string) error {
5050
if len(args) != 1 {
5151
return fmt.Errorf("please specify the service alias for the AWS service API to generate")
5252
}
53-
if err := ensureSDKRepo(optCacheDir); err != nil {
53+
if err := ensureSDKRepo(optCacheDir, optRefreshCache); err != nil {
5454
return err
5555
}
5656
svcAlias := strings.ToLower(args[0])

cmd/ack-generate/command/olm.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func generateOLMAssets(cmd *cobra.Command, args []string) error {
8181
version := args[1]
8282

8383
// get the generator inputs
84-
if err := ensureSDKRepo(optCacheDir); err != nil {
84+
if err := ensureSDKRepo(optCacheDir, optRefreshCache); err != nil {
8585
return err
8686
}
8787
sdkHelper := ackmodel.NewSDKHelper(sdkDir)

cmd/ack-generate/command/release.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func generateRelease(cmd *cobra.Command, args []string) error {
6565
// version supplied hasn't been used (as a Git tag) before...
6666
releaseVersion := strings.ToLower(args[1])
6767

68-
if err := ensureSDKRepo(optCacheDir); err != nil {
68+
if err := ensureSDKRepo(optCacheDir, optRefreshCache); err != nil {
6969
return err
7070
}
7171
sdkHelper := ackmodel.NewSDKHelper(sdkDir)

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ require (
1515
github.com/spf13/cobra v1.1.1
1616
github.com/stretchr/testify v1.7.0
1717
golang.org/x/mod v0.4.1
18+
gopkg.in/src-d/go-git.v4 v4.13.1
1819
k8s.io/apimachinery v0.20.1
1920
)

0 commit comments

Comments
 (0)