-
Notifications
You must be signed in to change notification settings - Fork 797
/
generationMetadata.go
133 lines (116 loc) · 4.84 KB
/
generationMetadata.go
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
package autorest
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"github.com/Azure/azure-sdk-for-go/eng/tools/generator/autorest/model"
"github.com/Azure/azure-sdk-for-go/eng/tools/internal/packages/track1"
)
// GenerationMetadata contains all the metadata that has been used when generating a track 1 package
type GenerationMetadata struct {
// AutorestVersion is the version of autorest.core
AutorestVersion string `json:"autorest,omitempty"`
// CommitHash is the commit hash of azure-rest-api-specs from which this SDK package is generated
CommitHash string `json:"commit,omitempty"`
// Readme is the normalized path of the readme file from which this SDK package is generated. It should be in this pattern: /_/azure-rest-api-specs/{relative_path}
Readme string `json:"readme,omitempty"`
// Tag is the tag from which this SDK package is generated
Tag string `json:"tag,omitempty"`
// CodeGenVersion is the version of autorest.go using when this package is generated
CodeGenVersion string `json:"use,omitempty"`
// RepositoryURL is the URL of the azure-rest-api-specs. This should always be a constant "https://github.com/Azure/azure-rest-api-specs.git"
RepositoryURL string `json:"repository_url,omitempty"`
// AutorestCommand is the full command that generates this package
AutorestCommand string `json:"autorest_command,omitempty"`
// AdditionalProperties is a map of addition information in this metadata
AdditionalProperties GenerationMetadataAdditionalProperties `json:"additional_properties,omitempty"`
}
// GenerationMetadataAdditionalProperties contains all the additional options other than go-sdk-foler, tag, multiapi, use or the readme path
type GenerationMetadataAdditionalProperties struct {
AdditionalOptions string `json:"additional_options,omitempty"`
}
// RelativeReadme returns the relative readme path
func (meta *GenerationMetadata) RelativeReadme() string {
return strings.TrimPrefix(meta.Readme, NormalizedSpecRoot)
}
// CollectGenerationMetadata iterates every track 1 go sdk package under root, and collect all the GenerationMetadata into a map
// using the absolute path of the package as keys
func CollectGenerationMetadata(root string) (map[string]GenerationMetadata, error) {
pkgs, err := track1.List(root)
if err != nil {
return nil, fmt.Errorf("failed to get track 1 package list under root '%s': %+v", root, err)
}
result := make(map[string]GenerationMetadata)
for _, pkg := range pkgs {
m, err := GetGenerationMetadata(pkg)
if err != nil {
return nil, err
}
if m != nil {
result[pkg.FullPath()] = *m
}
}
return result, nil
}
// GetGenerationMetadata gets the GenerationMetadata in one specific package
func GetGenerationMetadata(pkg track1.Package) (*GenerationMetadata, error) {
metadataFilepath := filepath.Join(pkg.FullPath(), MetadataFilename)
// some classical package might not have a changelog, therefore we need to identify whether the changelog file exist or not
if _, err := os.Stat(metadataFilepath); os.IsNotExist(err) {
log.Printf("package '%s' does not have a metadata file", pkg.Path())
return nil, nil
}
b, err := ioutil.ReadFile(metadataFilepath)
if err != nil {
return nil, fmt.Errorf("cannot read file %s: %+v", metadataFilepath, err)
}
var metadata GenerationMetadata
if err := json.Unmarshal(b, &metadata); err != nil {
return nil, fmt.Errorf("cannot unmarshal metadata: %+v", err)
}
return &metadata, nil
}
// AdditionalOptions removes flags that may change over scenarios
func AdditionalOptions(arguments []model.Option) []model.Option {
var transformed []model.Option
for _, argument := range arguments {
switch o := argument.(type) {
case model.ArgumentOption: // omit the readme path argument
continue
case model.FlagOption:
if o.Flag() == "multiapi" { // omit the multiapi flag or use
continue
}
case model.KeyValueOption:
// omit go-sdk-folder, use, tag and metadata-output-folder
if o.Key() == "go-sdk-folder" || o.Key() == "use" || o.Key() == "tag" || o.Key() == "metadata-output-folder" {
continue
}
}
transformed = append(transformed, argument)
}
return transformed
}
// AdditionalOptionsToString removes flags that may change over scenarios and cast them to strings
func AdditionalOptionsToString(arguments []model.Option) []string {
transformed := AdditionalOptions(arguments)
result := make([]string, len(transformed))
for i, o := range transformed {
result[i] = o.Format()
}
return result
}
const (
// NormalizedSpecRoot this is the prefix for readme
NormalizedSpecRoot = "/_/azure-rest-api-specs/"
// NormalizedSDKRoot this is the prefix for readme
NormalizedSDKRoot = "/_/azure-sdk-for-go/"
// MetadataFilename ...
MetadataFilename = "_meta.json"
)