Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refine sdk automation tool #23959

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
110 changes: 49 additions & 61 deletions eng/tools/generator/cmd/v2/automation/automationCmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,69 +115,57 @@ func (ctx *automationContext) generate(input *pipeline.GenerateInput) (*pipeline
continue
}

if ok := tsc.ExistEmitOption(string(typespec.TypeSpec_GO)); ok {
log.Printf("Start to process typespec project: %s", tspProjectFolder)
generateCtx := common.GenerateContext{
SDKPath: sdkRepo.Root(),
SDKRepo: &sdkRepo,
SpecPath: ctx.specRoot,
SpecCommitHash: ctx.commitHash,
SpecRepoURL: input.RepoHTTPSURL,
TypeSpecConfig: tsc,
}

module, err := tsc.GetModuleName()
if err != nil {
errorBuilder.add(err)
continue
}
packageModuleRelativePath := tsc.GetPackageModuleRelativePath()
if packageModuleRelativePath == "" {
errorBuilder.add(fmt.Errorf("package module relative path not found in %s", tspconfigPath))
continue
}
namespaceResult, err := generateCtx.GenerateForTypeSpec(&common.GenerateParam{
RPName: module[0],
NamespaceName: module[1],
SkipGenerateExample: true,
GoVersion: ctx.goVersion,
TspClientOptions: []string{"--debug"},
}, packageModuleRelativePath)
if err != nil {
errorBuilder.add(err)
continue
} else {
content := namespaceResult.ChangelogMD
breaking := namespaceResult.Changelog.HasBreakingChanges()
breakingChangeItems := namespaceResult.Changelog.GetBreakingChangeItems()

srcFolder := filepath.Join(sdkRepo.Root(), packageModuleRelativePath)
apiViewArtifact := filepath.Join(sdkRepo.Root(), packageModuleRelativePath+".gosource")
err := zipDirectory(srcFolder, apiViewArtifact)
if err != nil {
fmt.Println(err)
}

results = append(results, pipeline.PackageResult{
Version: namespaceResult.Version,
PackageName: packageModuleRelativePath,
Path: []string{packageModuleRelativePath},
PackageFolder: packageModuleRelativePath,
TypespecProject: []string{tspProjectFolder},
Changelog: &pipeline.Changelog{
Content: &content,
HasBreakingChange: &breaking,
BreakingChangeItems: &breakingChangeItems,
},
APIViewArtifact: packageModuleRelativePath + ".gosource",
Language: "Go",
})

log.Printf("Finish processing typespec file: %s", tspconfigPath)
}
} else {
if ok := tsc.ExistEmitOption(string(typespec.TypeSpec_GO)); !ok {
errorBuilder.add(fmt.Errorf("`@azure-tools/typespec-go` option not found in %s, it is required, please refer to `https://aka.ms/azsdk/tspconfig-sample-mpg` to configure it", tspconfigPath))
continue
}
log.Printf("Start to process typespec project: %s", tspProjectFolder)
generateCtx := common.GenerateContext{
SDKPath: sdkRepo.Root(),
SDKRepo: &sdkRepo,
SpecPath: ctx.specRoot,
SpecCommitHash: ctx.commitHash,
SpecRepoURL: input.RepoHTTPSURL,
TypeSpecConfig: tsc,
}

namespaceResult, err := generateCtx.GenerateForTypeSpec(&common.GenerateParam{
SkipGenerateExample: true,
GoVersion: ctx.goVersion,
TspClientOptions: []string{"--debug"},
})
if err != nil {
errorBuilder.add(err)
continue
}
content := namespaceResult.ChangelogMD
breaking := namespaceResult.Changelog.HasBreakingChanges()
breakingChangeItems := namespaceResult.Changelog.GetBreakingChangeItems()
packageRelativePath := namespaceResult.PackageRelativePath

srcFolder := filepath.Join(sdkRepo.Root(), packageRelativePath)
apiViewArtifact := filepath.Join(sdkRepo.Root(), packageRelativePath+".gosource")
err = zipDirectory(srcFolder, apiViewArtifact)
if err != nil {
fmt.Println(err)
}

results = append(results, pipeline.PackageResult{
Version: namespaceResult.Version,
PackageName: packageRelativePath,
Path: []string{packageRelativePath},
PackageFolder: packageRelativePath,
TypespecProject: []string{tspProjectFolder},
Changelog: &pipeline.Changelog{
Content: &content,
HasBreakingChange: &breaking,
BreakingChangeItems: &breakingChangeItems,
},
APIViewArtifact: packageRelativePath + ".gosource",
Language: "Go",
})

log.Printf("Finish processing typespec file: %s", tspconfigPath)
}

// autorest
Expand Down
9 changes: 5 additions & 4 deletions eng/tools/generator/cmd/v2/common/changelogProcessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ const (
sdk_remote_url = "https://github.com/Azure/azure-sdk-for-go.git"
)

func GetAllVersionTags(packageModuleRelativePath string) ([]string, error) {
arr := strings.Split(packageModuleRelativePath, "/")
func GetAllVersionTags(moduleRelativePath string) ([]string, error) {
arr := strings.Split(moduleRelativePath, "/")
log.Printf("Fetching all release tags from GitHub for RP: '%s' Package: '%s' ...", arr[len(arr)-2], arr[len(arr)-1])
client := http.Client{}
res, err := client.Get(sdk_tag_fetch_url)
Expand All @@ -52,7 +52,7 @@ func GetAllVersionTags(packageModuleRelativePath string) ([]string, error) {
versionTag := make(map[string]string)
for _, tag := range result {
tagName := tag["ref"].(string)
if strings.Contains(tagName, packageModuleRelativePath+"/v") {
if strings.Contains(tagName, moduleRelativePath+"/v") {
m := regexp.MustCompile(semver.SemVerRegex).FindString(tagName)
versions = append(versions, m)
versionTag[m] = tagName
Expand Down Expand Up @@ -168,7 +168,8 @@ func GetExportsFromTag(sdkRepo repo.SDKRepository, packagePath, tag string) (*ex

// get exports
result, err := exports.Get(packagePath)
if err != nil {
// bypass the error if the package doesn't contain any exports, return nil
if err != nil && !strings.Contains(err.Error(), "doesn't contain any exports") {
return nil, err
}

Expand Down
2 changes: 2 additions & 0 deletions eng/tools/generator/cmd/v2/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ package common

const (
ChangelogFileName = "CHANGELOG.md"
GoModFileName = "go.mod"
SdkRootPath = "sdk"
)
50 changes: 48 additions & 2 deletions eng/tools/generator/cmd/v2/common/fileProcessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ func ReadV2ModuleNameToGetNamespace(path string) (map[string][]PackageInfo, erro

// remove all sdk generated files in given path
func CleanSDKGeneratedFiles(path string) error {
if _, err := os.Stat(path); os.IsNotExist(err) {
return nil
}
log.Printf("Removing all sdk generated files in '%s'...", path)
return filepath.Walk(path, func(path string, info fs.FileInfo, err error) error {
if err != nil {
Expand Down Expand Up @@ -397,7 +400,6 @@ func AddChangelogToFile(changelog *Changelog, version *semver.Version, packageRo

// replace `{{NewClientName}}` placeholder in README.md by first func name according to `^New.+Method$` pattern
func ReplaceNewClientNamePlaceholder(packageRootPath string, exports exports.Content) error {
path := filepath.Join(packageRootPath, "README.md")
var clientName string
for _, k := range SortFuncItem(exports.Funcs) {
v := exports.Funcs[k]
Expand All @@ -407,6 +409,12 @@ func ReplaceNewClientNamePlaceholder(packageRootPath string, exports exports.Con
}
}

path := filepath.Join(packageRootPath, "README.md")

if _, err := os.Stat(path); os.IsNotExist(err) {
return nil
}

b, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("cannot read from file '%s': %+v", path, err)
Expand All @@ -420,9 +428,13 @@ func UpdateModuleDefinition(packageRootPath, packageModuleRelativePath string, v
if version.Major() > 1 {
path := filepath.Join(packageRootPath, "go.mod")

if _, err := os.Stat(path); os.IsNotExist(err) {
return nil
}

b, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("cannot parse version from changelog")
return fmt.Errorf("cannot read go.mod")
}

lines := strings.Split(string(b), "\n")
Expand Down Expand Up @@ -691,6 +703,11 @@ func ReplaceReadmeNewClientName(packageRootPath string, exports exports.Content)

func ReplaceConstModuleVersion(packagePath string, newVersion string) error {
path := filepath.Join(packagePath, "constants.go")

if _, err := os.Stat(path); os.IsNotExist(err) {
return nil
}

data, err := os.ReadFile(path)
if err != nil {
return err
Expand Down Expand Up @@ -789,3 +806,32 @@ func importPath(s *ast.ImportSpec) string {
}
return t
}

// Walks the sdk directory to find module based on a go.mod file
func FindModuleDirByGoMod(root string) (string, error) {
path := root
curLevel := 0
maxLevel := 5
for !strings.HasSuffix(path, SdkRootPath) && curLevel < maxLevel {
if _, err := os.Stat(path); os.IsNotExist(err) {
path = filepath.Dir(path)
curLevel++
continue
}
entries, err := os.ReadDir(path)
if err != nil {
return "", err
}
for _, entry := range entries {
if entry.IsDir() {
continue
}
if entry.Name() == GoModFileName {
return path, nil
}
}
path = filepath.Dir(path)
curLevel++
}
return "", fmt.Errorf("not found module, package path:%s", root)
}
18 changes: 18 additions & 0 deletions eng/tools/generator/cmd/v2/common/fileProcessor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@
package common

import (
"fmt"
"os"
"path/filepath"
"testing"

"github.com/Azure/azure-sdk-for-go/eng/tools/generator/repo"
"github.com/Azure/azure-sdk-for-go/eng/tools/internal/delta"
"github.com/Azure/azure-sdk-for-go/eng/tools/internal/exports"
"github.com/Azure/azure-sdk-for-go/eng/tools/internal/report"
"github.com/Azure/azure-sdk-for-go/eng/tools/internal/utils"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -122,3 +127,16 @@ func TestCalculateNewVersion(t *testing.T) {
assert.Equal(t, newVersion.String(), "1.2.0-beta.2")
assert.Equal(t, BetaLabel, prl)
}

func TestFindModule(t *testing.T) {
cwd, err := os.Getwd()
assert.NoError(t, err)
sdkRoot := utils.NormalizePath(cwd)
sdkRepo, err := repo.OpenSDKRepository(sdkRoot)
assert.NoError(t, err)
module, err := FindModuleDirByGoMod(fmt.Sprintf("%s/%s", filepath.ToSlash(sdkRepo.Root()), "sdk/security/keyvault/azadmin/settings"))
assert.NoError(t, err)
moduleRelativePath, err := filepath.Rel(sdkRepo.Root(), module)
assert.NoError(t, err)
assert.Equal(t, "sdk/security/keyvault/azadmin", filepath.ToSlash(moduleRelativePath))
}
Loading
Loading