Skip to content

Commit 4d9b291

Browse files
authored
Refactor reusable code to ensure aws-sdk-go repository (#355)
Signed-off-by: James Park <[email protected]> Issue: [aws-controllers-k8s/community/issues/1358](aws-controllers-k8s/community#1358) Description of changes: - This PR is to refactor reusable code of `EnsureRepo` method and its related methods into the `pkg/` directory of the code-generator repository. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent cb4bca8 commit 4d9b291

File tree

7 files changed

+242
-203
lines changed

7 files changed

+242
-203
lines changed

cmd/ack-generate/command/apis.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
2626
ackmetadata "github.com/aws-controllers-k8s/code-generator/pkg/metadata"
27+
"github.com/aws-controllers-k8s/code-generator/pkg/sdk"
2728
"github.com/aws-controllers-k8s/code-generator/pkg/util"
2829
)
2930

@@ -91,11 +92,13 @@ func generateAPIs(cmd *cobra.Command, args []string) error {
9192
if optOutputPath == "" {
9293
optOutputPath = filepath.Join(optServicesDir, svcAlias)
9394
}
94-
ctx, cancel := contextWithSigterm(context.Background())
95+
ctx, cancel := sdk.ContextWithSigterm(context.Background())
9596
defer cancel()
96-
if err := ensureSDKRepo(ctx, optCacheDir, optRefreshCache); err != nil {
97+
sdkDirPath, err := sdk.EnsureRepo(ctx, optCacheDir, optRefreshCache, optAWSSDKGoVersion, optOutputPath)
98+
if err != nil {
9799
return err
98100
}
101+
sdkDir = sdkDirPath
99102
metadata, err := ackmetadata.NewServiceMetadata(optMetadataConfigPath)
100103
if err != nil {
101104
return err
@@ -122,7 +125,7 @@ func generateAPIs(cmd *cobra.Command, args []string) error {
122125
}
123126
outPath := filepath.Join(apisVersionPath, path)
124127
outDir := filepath.Dir(outPath)
125-
if _, err := ensureDir(outDir); err != nil {
128+
if _, err := sdk.EnsureDir(outDir); err != nil {
126129
return err
127130
}
128131
if err = ioutil.WriteFile(outPath, contents.Bytes(), 0666); err != nil {

cmd/ack-generate/command/common.go

Lines changed: 0 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -14,207 +14,19 @@
1414
package command
1515

1616
import (
17-
"context"
1817
"fmt"
19-
"io/ioutil"
20-
"os"
21-
"os/signal"
22-
"path/filepath"
2318
"sort"
2419
"strings"
25-
"syscall"
26-
"time"
2720

28-
"golang.org/x/mod/modfile"
2921
k8sversion "k8s.io/apimachinery/pkg/version"
3022

3123
ackgenconfig "github.com/aws-controllers-k8s/code-generator/pkg/config"
3224
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
3325
ackmetadata "github.com/aws-controllers-k8s/code-generator/pkg/metadata"
3426
ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model"
3527
acksdk "github.com/aws-controllers-k8s/code-generator/pkg/sdk"
36-
"github.com/aws-controllers-k8s/code-generator/pkg/util"
3728
)
3829

39-
const (
40-
sdkRepoURL = "https://github.com/aws/aws-sdk-go"
41-
defaultGitCloneTimeout = 180 * time.Second
42-
defaultGitFetchTimeout = 30 * time.Second
43-
)
44-
45-
func contextWithSigterm(ctx context.Context) (context.Context, context.CancelFunc) {
46-
ctx, cancel := context.WithCancel(ctx)
47-
signalCh := make(chan os.Signal, 1)
48-
49-
// recreate the context.CancelFunc
50-
cancelFunc := func() {
51-
signal.Stop(signalCh)
52-
cancel()
53-
}
54-
55-
// notify on SIGINT or SIGTERM
56-
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
57-
go func() {
58-
select {
59-
case <-signalCh:
60-
cancel()
61-
case <-ctx.Done():
62-
}
63-
}()
64-
65-
return ctx, cancelFunc
66-
}
67-
68-
// ensureDir makes sure that a supplied directory exists and
69-
// returns whether the directory already existed.
70-
func ensureDir(fp string) (bool, error) {
71-
fi, err := os.Stat(fp)
72-
if err != nil {
73-
if os.IsNotExist(err) {
74-
return false, os.MkdirAll(fp, os.ModePerm)
75-
}
76-
return false, err
77-
}
78-
if !fi.IsDir() {
79-
return false, fmt.Errorf("expected %s to be a directory", fp)
80-
}
81-
if !isDirWriteable(fp) {
82-
return true, fmt.Errorf("%s is not a writeable directory", fp)
83-
}
84-
85-
return true, nil
86-
}
87-
88-
// isDirWriteable returns true if the supplied directory path is writeable,
89-
// false otherwise
90-
func isDirWriteable(fp string) bool {
91-
testPath := filepath.Join(fp, "test")
92-
f, err := os.Create(testPath)
93-
if err != nil {
94-
return false
95-
}
96-
f.Close()
97-
os.Remove(testPath)
98-
return true
99-
}
100-
101-
// ensureSDKRepo ensures that we have a git clone'd copy of the aws-sdk-go
102-
// repository, which we use model JSON files from. Upon successful return of
103-
// this function, the sdkDir global variable will be set to the directory where
104-
// the aws-sdk-go is found. It will also optionally fetch all the remote tags
105-
// and checkout the given tag.
106-
func ensureSDKRepo(
107-
ctx context.Context,
108-
cacheDir string,
109-
// A boolean instructing ensureSDKRepo whether to fetch the remote tags from
110-
// the upstream repository
111-
fetchTags bool,
112-
) error {
113-
var err error
114-
srcPath := filepath.Join(cacheDir, "src")
115-
if err = os.MkdirAll(srcPath, os.ModePerm); err != nil {
116-
return err
117-
}
118-
119-
// Clone repository if it doen't exist
120-
sdkDir = filepath.Join(srcPath, "aws-sdk-go")
121-
if _, err := os.Stat(sdkDir); os.IsNotExist(err) {
122-
123-
ctx, cancel := context.WithTimeout(ctx, defaultGitCloneTimeout)
124-
defer cancel()
125-
err = util.CloneRepository(ctx, sdkDir, sdkRepoURL)
126-
if err != nil {
127-
return fmt.Errorf("canot clone repository: %v", err)
128-
}
129-
}
130-
131-
// Fetch all tags
132-
if fetchTags {
133-
ctx, cancel := context.WithTimeout(ctx, defaultGitFetchTimeout)
134-
defer cancel()
135-
err = util.FetchRepositoryTags(ctx, sdkDir)
136-
if err != nil {
137-
return fmt.Errorf("cannot fetch tags: %v", err)
138-
}
139-
}
140-
141-
// get sdkVersion and ensure it prefix
142-
// TODO(a-hilaly) Parse `ack-generate-metadata.yaml` and pass the aws-sdk-go
143-
// version here.
144-
sdkVersion, err := getSDKVersion("")
145-
if err != nil {
146-
return err
147-
}
148-
sdkVersion = ensureSemverPrefix(sdkVersion)
149-
150-
repo, err := util.LoadRepository(sdkDir)
151-
if err != nil {
152-
return fmt.Errorf("cannot read local repository: %v", err)
153-
}
154-
155-
// Now checkout the local repository.
156-
err = util.CheckoutRepositoryTag(repo, sdkVersion)
157-
if err != nil {
158-
return fmt.Errorf("cannot checkout tag: %v", err)
159-
}
160-
161-
return err
162-
}
163-
164-
// ensureSemverPrefix takes a semver string and tries to append the 'v'
165-
// prefix if it's missing.
166-
func ensureSemverPrefix(s string) string {
167-
// trim all leading 'v' runes (characters)
168-
s = strings.TrimLeft(s, "v")
169-
return fmt.Sprintf("v%s", s)
170-
}
171-
172-
// getSDKVersion returns the github.com/aws/aws-sdk-go version to use. It
173-
// first tries to get the version from the --aws-sdk-go-version flag, then
174-
// from the ack-generate-metadata.yaml and finally look for the service
175-
// go.mod controller.
176-
func getSDKVersion(
177-
lastGenerationVersion string,
178-
) (string, error) {
179-
// First try to get the version from --aws-sdk-go-version flag
180-
if optAWSSDKGoVersion != "" {
181-
return optAWSSDKGoVersion, nil
182-
}
183-
184-
// then, try to use last generation version (from ack-generate-metadata.yaml)
185-
if lastGenerationVersion != "" {
186-
return lastGenerationVersion, nil
187-
}
188-
189-
// then, try to parse the service controller go.mod file
190-
sdkVersion, err := getSDKVersionFromGoMod(filepath.Join(optOutputPath, "go.mod"))
191-
if err == nil {
192-
return sdkVersion, nil
193-
}
194-
195-
return "", err
196-
}
197-
198-
// getSDKVersionFromGoMod parses a given go.mod file and returns
199-
// the aws-sdk-go version in the required modules.
200-
func getSDKVersionFromGoMod(goModPath string) (string, error) {
201-
b, err := ioutil.ReadFile(goModPath)
202-
if err != nil {
203-
return "", err
204-
}
205-
goMod, err := modfile.Parse("", b, nil)
206-
if err != nil {
207-
return "", err
208-
}
209-
sdkModule := strings.TrimPrefix(sdkRepoURL, "https://")
210-
for _, require := range goMod.Require {
211-
if require.Mod.Path == sdkModule {
212-
return require.Mod.Version, nil
213-
}
214-
}
215-
return "", fmt.Errorf("couldn't find %s in the go.mod require block", sdkModule)
216-
}
217-
21830
// loadModelWithLatestAPIVersion finds the AWS SDK for a given service alias and
21931
// creates a new model with the latest API version.
22032
func loadModelWithLatestAPIVersion(svcAlias string, metadata *ackmetadata.ServiceMetadata) (*ackmodel.Model, error) {

cmd/ack-generate/command/controller.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727

2828
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
2929
ackmetadata "github.com/aws-controllers-k8s/code-generator/pkg/metadata"
30+
"github.com/aws-controllers-k8s/code-generator/pkg/sdk"
3031
)
3132

3233
var (
@@ -55,11 +56,13 @@ func generateController(cmd *cobra.Command, args []string) error {
5556
optOutputPath = filepath.Join(optServicesDir, svcAlias)
5657
}
5758

58-
ctx, cancel := contextWithSigterm(context.Background())
59+
ctx, cancel := sdk.ContextWithSigterm(context.Background())
5960
defer cancel()
60-
if err := ensureSDKRepo(ctx, optCacheDir, optRefreshCache); err != nil {
61+
sdkDirPath, err := sdk.EnsureRepo(ctx, optCacheDir, optRefreshCache, optAWSSDKGoVersion, optOutputPath)
62+
if err != nil {
6163
return err
6264
}
65+
sdkDir = sdkDirPath
6366
metadata, err := ackmetadata.NewServiceMetadata(optMetadataConfigPath)
6467
if err != nil {
6568
return err
@@ -89,7 +92,7 @@ func generateController(cmd *cobra.Command, args []string) error {
8992
}
9093
outPath := filepath.Join(optOutputPath, path)
9194
outDir := filepath.Dir(outPath)
92-
if _, err := ensureDir(outDir); err != nil {
95+
if _, err := sdk.EnsureDir(outDir); err != nil {
9396
return err
9497
}
9598
if err = ioutil.WriteFile(outPath, contents.Bytes(), 0666); err != nil {

cmd/ack-generate/command/crossplane.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/spf13/cobra"
2626

2727
cpgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/crossplane"
28+
"github.com/aws-controllers-k8s/code-generator/pkg/sdk"
2829
)
2930

3031
// crossplaneCmd is the command that generates Crossplane API types
@@ -43,11 +44,13 @@ func generateCrossplane(_ *cobra.Command, args []string) error {
4344
return fmt.Errorf("please specify the service alias for the AWS service API to generate")
4445
}
4546

46-
ctx, cancel := contextWithSigterm(context.Background())
47+
ctx, cancel := sdk.ContextWithSigterm(context.Background())
4748
defer cancel()
48-
if err := ensureSDKRepo(ctx, optCacheDir, optRefreshCache); err != nil {
49+
sdkDirPath, err := sdk.EnsureRepo(ctx, optCacheDir, optRefreshCache, optAWSSDKGoVersion, optOutputPath)
50+
if err != nil {
4951
return err
5052
}
53+
sdkDir = sdkDirPath
5154
svcAlias := strings.ToLower(args[0])
5255
if optGeneratorConfigPath == "" {
5356
// default generator configuration file path is now: apis/<service>/<generator-config.yaml>
@@ -77,7 +80,7 @@ func generateCrossplane(_ *cobra.Command, args []string) error {
7780
}
7881
outPath := filepath.Join(optOutputPath, path)
7982
outDir := filepath.Dir(outPath)
80-
if _, err := ensureDir(outDir); err != nil {
83+
if _, err := sdk.EnsureDir(outDir); err != nil {
8184
return err
8285
}
8386
if err = ioutil.WriteFile(outPath, contents.Bytes(), 0666); err != nil {

cmd/ack-generate/command/olm.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525

2626
olmgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/olm"
2727
ackmetadata "github.com/aws-controllers-k8s/code-generator/pkg/metadata"
28+
"github.com/aws-controllers-k8s/code-generator/pkg/sdk"
2829
)
2930

3031
const (
@@ -83,11 +84,13 @@ func generateOLMAssets(cmd *cobra.Command, args []string) error {
8384
version := args[1]
8485

8586
// get the generator inputs
86-
ctx, cancel := contextWithSigterm(context.Background())
87+
ctx, cancel := sdk.ContextWithSigterm(context.Background())
8788
defer cancel()
88-
if err := ensureSDKRepo(ctx, optCacheDir, optRefreshCache); err != nil {
89+
sdkDirPath, err := sdk.EnsureRepo(ctx, optCacheDir, optRefreshCache, optAWSSDKGoVersion, optOutputPath)
90+
if err != nil {
8991
return err
9092
}
93+
sdkDir = sdkDirPath
9194
metadata, err := ackmetadata.NewServiceMetadata(optMetadataConfigPath)
9295
if err != nil {
9396
return err
@@ -144,7 +147,7 @@ func generateOLMAssets(cmd *cobra.Command, args []string) error {
144147
}
145148
outPath := filepath.Join(optOutputPath, path)
146149
outDir := filepath.Dir(outPath)
147-
if _, err := ensureDir(outDir); err != nil {
150+
if _, err := sdk.EnsureDir(outDir); err != nil {
148151
return err
149152
}
150153
if err = ioutil.WriteFile(outPath, contents.Bytes(), 0666); err != nil {

cmd/ack-generate/command/release.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
2626
ackmetadata "github.com/aws-controllers-k8s/code-generator/pkg/metadata"
27+
"github.com/aws-controllers-k8s/code-generator/pkg/sdk"
2728
)
2829

2930
var optReleaseOutputPath string
@@ -58,11 +59,13 @@ func generateRelease(cmd *cobra.Command, args []string) error {
5859
// version supplied hasn't been used (as a Git tag) before...
5960
releaseVersion := strings.ToLower(args[1])
6061

61-
ctx, cancel := contextWithSigterm(context.Background())
62+
ctx, cancel := sdk.ContextWithSigterm(context.Background())
6263
defer cancel()
63-
if err := ensureSDKRepo(ctx, optCacheDir, optRefreshCache); err != nil {
64+
sdkDirPath, err := sdk.EnsureRepo(ctx, optCacheDir, optRefreshCache, optAWSSDKGoVersion, optOutputPath)
65+
if err != nil {
6466
return err
6567
}
68+
sdkDir = sdkDirPath
6669
m, err := loadModel(svcAlias, "", "", ackgenerate.DefaultConfig)
6770
if err != nil {
6871
return err
@@ -93,7 +96,7 @@ func generateRelease(cmd *cobra.Command, args []string) error {
9396
}
9497
outPath := filepath.Join(optReleaseOutputPath, path)
9598
outDir := filepath.Dir(outPath)
96-
if _, err := ensureDir(outDir); err != nil {
99+
if _, err := sdk.EnsureDir(outDir); err != nil {
97100
return err
98101
}
99102
if err = ioutil.WriteFile(outPath, contents.Bytes(), 0666); err != nil {

0 commit comments

Comments
 (0)