File: verifiers.go

package info (click to toggle)
golang-github-azure-azure-sdk-for-go 68.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 556,256 kB
  • sloc: javascript: 196; sh: 96; makefile: 7
file content (97 lines) | stat: -rw-r--r-- 3,037 bytes parent folder | download | duplicates (3)
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
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

package track1

import (
	"fmt"
	"regexp"
	"strings"
	"unicode"

	"github.com/Azure/azure-sdk-for-go/eng/tools/internal/packages"
)

type verifiers []packages.VerifyFunc

func (v verifiers) Verify(pkg packages.Package) []error {
	var errors []error
	for _, verifier := range v {
		if err := verifier(pkg); err != nil {
			errors = append(errors, err)
		}
	}
	return errors
}

// GetDefaultVerifier gets the default track 1 verifiers which verifies the following:
// - verifies that the package name matches the leaf directory name
// - verifies that the package path only consists of lower case letters
// - verifies that the package path must follow the desired directory structure
func GetDefaultVerifier() packages.Verifier {
	return verifiers([]packages.VerifyFunc{
		verifyPkgMatchesDir,
		verifyLowerCase,
		verifyDirectoryStructure,
	})
}

// ensures that the leaf directory name matches the package name
// new to modules: if the last leaf is version suffix, find its parent as leaf folder
func verifyPkgMatchesDir(p packages.Package) error {
	leaf := findPackageFolderInPath(p.FullPath())
	if !strings.EqualFold(leaf, p.Name()) {
		return fmt.Errorf("leaf directory of '%s' doesn't match package name '%s'", p.Path(), p.Name())
	}
	return nil
}

func findPackageFolderInPath(path string) string {
	regex := regexp.MustCompile(`/v\d+$`)
	if regex.MatchString(path) {
		// folder path ends with version suffix
		path = path[:strings.LastIndex(path, "/")]
	}
	result := path[strings.LastIndex(path, "/")+1:]
	return result
}

// ensures that there are no upper-case letters in a package's directory
func verifyLowerCase(p packages.Package) error {
	// walk the package directory looking for upper-case characters
	for _, r := range p.Path() {
		if r == '/' {
			continue
		}
		if unicode.IsUpper(r) {
			return fmt.Errorf("found upper-case character in directory '%s'", p.Path())
		}
	}
	return nil
}

// ensures that the package's directory hierarchy is properly formed
func verifyDirectoryStructure(p packages.Package) error {
	// for ARM the package directory structure is highly deterministic:
	// /redis/mgmt/2015-08-01/redis
	// /resources/mgmt/2017-06-01-preview/policy
	// /preview/signalr/mgmt/2018-03-01-preview/signalr
	// /preview/security/mgmt/v2.0/security (version scheme for composite packages)
	// /network/mgmt/2019-10-01/network/v2 (new with modules)
	if !p.IsARMPackage() {
		return nil
	}
	regexStr := fmt.Sprintf(`^(preview/)?%s/mgmt/%s/%s%s$`, rpNameRegex, apiVersionRegex, nameSpaceRegex, majorSubDirRegex)
	regex := regexp.MustCompile(regexStr)
	if !regex.MatchString(p.Path()) {
		return fmt.Errorf("bad directory structure '%s'", p.Path())
	}
	return nil
}

const (
	rpNameRegex      = `[a-z0-9\-]+`
	apiVersionRegex  = `((?:\d{4}-\d{2}-\d{2}(?:-preview)?)|(?:v\d{1,2}\.\d{1,2}))`
	nameSpaceRegex   = `[a-z0-9]+`
	majorSubDirRegex = `(/v\d+)?`
)