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
|
// 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 (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/Azure/azure-sdk-for-go/eng/tools/generator/config"
"github.com/ahmetb/go-linq/v3"
"github.com/hashicorp/go-multierror"
)
type localValidator struct {
specRoot string
}
func (v *localValidator) Validate(cfg config.Config) error {
var errResult error
for readme, infoMap := range cfg.Track1Requests {
if err := v.validateReadmeExistence(readme); err != nil {
errResult = multierror.Append(errResult, err)
continue // readme file cannot pass validation, we just skip the validations
}
// get content of the readme
contentOfReadme, err := v.getReadmeContent(readme)
if err != nil {
errResult = multierror.Append(errResult, fmt.Errorf("cannot get readme.md content: %+v", err))
continue
}
// validate the existence of readme.go.md
if err := v.validateReadmeExistence(getReadmeGoFromReadme(readme)); err != nil {
errResult = multierror.Append(errResult, err)
continue // readme.go.md is mandatory
}
// get content of the readme.go.md
contentOfReadmeGo, err := v.getReadmeContent(getReadmeGoFromReadme(readme))
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(contentOfReadme, readme, tags...); err != nil {
errResult = multierror.Append(errResult, err)
}
if err := validateTagsInReadmeGo(contentOfReadmeGo, readme, tags...); err != nil {
errResult = multierror.Append(errResult, err)
}
}
return errResult
}
func (v *localValidator) validateReadmeExistence(readme string) error {
full := filepath.Join(v.specRoot, readme)
if _, err := os.Stat(full); os.IsNotExist(err) {
return fmt.Errorf("readme file %q does not exist", readme)
}
return nil
}
func (v *localValidator) getReadmeContent(readme string) ([]byte, error) {
full := filepath.Join(v.specRoot, readme)
return ioutil.ReadFile(full)
}
func findTagInReadme(content []byte, tag string) bool {
return regexp.MustCompile(fmt.Sprintf(tagDefinedInReadmeRegex, tag)).Match(content)
}
func findTagInGo(content []byte, tag string) bool {
return regexp.MustCompile(tagInBatchRegex + tag + `\s+`).Match(content)
}
func getReadmeGoFromReadme(readme string) string {
return strings.ReplaceAll(readme, readmeFilename, goReadmeFilename)
}
const (
tagDefinedInReadmeRegex = `\$\(tag\)\s*==\s*'%s'`
tagInBatchRegex = `-\s*tag\s*:\s*`
readmeFilename = "readme.md"
goReadmeFilename = "readme.go.md"
)
|