1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
package validate
import (
"context"
"fmt"
"strings"
"github.com/Azure/azure-sdk-for-go/eng/tools/generator/cmd/issue/query"
"github.com/Azure/azure-sdk-for-go/eng/tools/generator/config"
"github.com/ahmetb/go-linq/v3"
"github.com/google/go-github/v32/github"
"github.com/hashicorp/go-multierror"
)
type remoteValidator struct {
ctx context.Context
client *query.Client
}
func (v *remoteValidator) Validate(cfg config.Config) error {
var errResult error
for readme, infoMap := range cfg.Track1Requests {
// first we validate whether the readme exists
file, err := v.validateReadmeExistence(readme)
if err != nil {
errResult = multierror.Append(errResult, err)
continue // readme file does not exist, we could just skip all of the other steps of validations
}
// get content of the readme
contentOfReadme, err := file.GetContent()
if err != nil {
errResult = multierror.Append(errResult, fmt.Errorf("cannot get readme.md content: %+v", err))
continue
}
// validate the existence of readme.go.md
fileGo, err := v.validateReadmeExistence(getReadmeGoFromReadme(readme))
if err != nil {
errResult = multierror.Append(errResult, err)
continue // readme.go.md is mandatory
}
// get content of the readme.go.md
contentOfReadmeGo, err := fileGo.GetContent()
if err != nil {
errResult = multierror.Append(errResult, fmt.Errorf("cannot get readme.go.md content: %+v", err))
continue
}
// get the keys from infoMap, which is the tags
var tags []string
linq.From(infoMap).Select(func(item interface{}) interface{} {
return item.(linq.KeyValue).Key
}).ToSlice(&tags)
// check the tags one by one
if err := validateTagsInReadme([]byte(contentOfReadme), readme, tags...); err != nil {
errResult = multierror.Append(errResult, err)
}
if err := validateTagsInReadmeGo([]byte(contentOfReadmeGo), readme, tags...); err != nil {
errResult = multierror.Append(errResult, err)
}
}
return errResult
}
func (v *remoteValidator) validateReadmeExistence(readme string) (*github.RepositoryContent, error) {
file, _, _, err := v.client.Repositories.GetContents(v.ctx, SpecOwner, SpecRepo, readme, nil)
if err != nil {
return nil, fmt.Errorf("cannot get readme file '%s' on remote: %+v", readme, err)
}
return file, nil
}
func validateTagsInReadme(content []byte, readme string, tags ...string) error {
var notFoundTags []string
for _, t := range tags {
if !findTagInReadme(content, t) {
notFoundTags = append(notFoundTags, t)
}
}
if len(notFoundTags) > 0 {
return fmt.Errorf("%d tag(s) not defined in readme.md '%s': %s", len(notFoundTags), readme, strings.Join(notFoundTags, ", "))
}
return nil
}
func validateTagsInReadmeGo(content []byte, readme string, tags ...string) error {
var notFoundTags []string
for _, t := range tags {
if !findTagInGo(content, t) {
notFoundTags = append(notFoundTags, t)
}
}
if len(notFoundTags) > 0 {
return fmt.Errorf("%d tag(s) not found in readme.go.md '%s': %s", len(notFoundTags), getReadmeGoFromReadme(readme), strings.Join(notFoundTags, ", "))
}
return nil
}
const (
SpecOwner = "Azure"
SpecRepo = "azure-rest-api-specs"
)
|