package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"regexp"
"sort"
"text/template"
codegen "github.com/aws/aws-sdk-go-v2/internal/codegen/defaults"
)
var jsonFile string
var outputFile string
var outputPackage string
func init() {
flag.StringVar(&jsonFile, "json", "", "The JSON defaults configuration file.")
flag.StringVar(&outputFile, "output", "defaults.go", "The output filename.")
flag.StringVar(&outputPackage, "package", "aws", "The output file package.")
}
type Configuration struct {
Version int64 `json:"version"`
Modes map[string]struct{} `json:"modes"`
Documentation struct {
Modes map[string]string `json:"modes"`
} `json:"documentation"`
}
var reFixDocLeadIn = regexp.MustCompile(`^
(?PThe \S+ mode)`)
func main() {
flag.Parse()
if len(jsonFile) == 0 || len(outputFile) == 0 {
log.Fatal("-json and -output arguments are required")
}
jsonBytes, err := ioutil.ReadFile(jsonFile)
if err != nil {
log.Fatalf("failed to read json file: %v", err)
}
var config Configuration
if err := json.Unmarshal(jsonBytes, &config); err != nil {
log.Fatalf("failed to unmarshal json: %v", err)
}
for mode := range config.Documentation.Modes {
doc := config.Documentation.Modes[mode]
if reFixDocLeadIn.MatchString(doc) {
submatchIndex := reFixDocLeadIn.FindStringSubmatchIndex(doc)
doc = doc[:submatchIndex[2]] + modeConstant(mode) + doc[submatchIndex[3]:]
}
config.Documentation.Modes[mode] = doc
}
var modes []string
for mode := range config.Modes {
modes = append(modes, mode)
}
const legacyStr = "legacy"
if _, ok := config.Modes[legacyStr]; ok {
log.Fatalf("expect %s to not be defined", legacyStr)
}
modes = append(modes, legacyStr)
const autoStr = "auto"
if _, ok := config.Modes[autoStr]; ok {
log.Fatalf("expect %s to not be defined", autoStr)
}
modes = append(modes, autoStr)
sort.Strings(modes)
buff := bytes.NewBuffer(nil)
err = template.Must(template.
New("generate").
Funcs(map[string]interface{}{
"modeConstant": modeConstant,
"docify": func(v string) string {
return codegen.ToGoDoc(v)
},
}).
Parse(`
{{- block "root" $ -}}
// Code generated by github.com/aws/aws-sdk-go-v2/internal/codegen/cmd/defaultsmode. DO NOT EDIT.
package {{ $.PackageName }}
import (
"strings"
)
// DefaultsMode is the SDK defaults mode setting.
type DefaultsMode string
// The DefaultsMode constants.
const (
{{- range $_, $mode := $.Modes }}
{{- $doc := (index $.Documentation $mode) }}
{{ docify $doc }}
{{ modeConstant $mode }} DefaultsMode = {{ printf "%q" $mode }}
{{ end }}
)
// SetFromString sets the DefaultsMode value to one of the pre-defined constants that matches
// the provided string when compared using EqualFold. If the value does not match a known
// constant it will be set to as-is and the function will return false. As a special case, if the
// provided value is a zero-length string, the mode will be set to LegacyDefaultsMode.
func (d *DefaultsMode) SetFromString(v string) (ok bool) {
switch {
{{- range $_, $mode := $.Modes }}
case strings.EqualFold(v, string({{ modeConstant $mode }})):
*d = {{ modeConstant $mode }}
ok = true
{{- end }}
case len(v) == 0:
*d = {{ modeConstant "legacy" }}
ok = true
default:
*d = DefaultsMode(v)
}
return ok
}
{{- end }}
`)).Execute(buff, struct {
PackageName string
AliasTarget string
Modes []string
Documentation map[string]string
WithAutoMode bool
}{
PackageName: outputPackage,
Modes: modes,
Documentation: config.Documentation.Modes,
})
if err != nil {
log.Fatalf("failed to execute template: %v", err)
}
if err := writeToFile(outputFile, buff); err != nil {
log.Fatalf("failed to write output file: %v", err)
}
}
func modeConstant(v string) string {
return fmt.Sprintf("DefaultsMode%s", codegen.SymbolizeExport(v))
}
func writeToFile(fileName string, content io.Reader) (err error) {
var ow *os.File
ow, err = os.OpenFile(fileName, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil {
log.Fatalf("failed to open output file: %v", err)
}
defer func() {
if cErr := ow.Close(); err == nil && cErr != nil {
err = fmt.Errorf("failed to close output file: %v", err)
}
}()
_, err = io.Copy(ow, content)
return err
}