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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
package model
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"reflect"
"strings"
)
// Options ...
type Options interface {
// Arguments returns the argument defined in this options
Arguments() []Option
// CodeGeneratorVersion returns the code generator version defined in this options
CodeGeneratorVersion() string
// MergeOptions merges the current options with the given options
MergeOptions(other ...Option) Options
}
// MergeOptions will merge the given options and new option slice, and return a new Options instance
func MergeOptions(options Options, other ...Option) Options {
arguments := options.Arguments()
for _, no := range other {
i := indexOfOptions(arguments, no)
if i >= 0 {
arguments[i] = no
} else {
arguments = append(arguments, no)
}
}
return localOptions(arguments)
}
type localOptions []Option
// ParseOptions returns an Options instance by parsing the given raw option strings
func ParseOptions(raw []string) (Options, error) {
var options []Option
for _, r := range raw {
o, err := NewOption(r)
if err != nil {
return nil, err
}
options = append(options, o)
}
return NewOptions(options...), nil
}
// NewOptions returns a new instance of Options with the give slice of Option
func NewOptions(options ...Option) Options {
return localOptions(options)
}
// Arguments ...
func (o localOptions) Arguments() []Option {
return o
}
// CodeGeneratorVersion ...
func (o localOptions) CodeGeneratorVersion() string {
for _, argument := range o.Arguments() {
if v, ok := argument.(KeyValueOption); ok {
if v.Key() == "use" {
return v.Value()
}
}
}
return ""
}
// MergeOptions ...
func (o localOptions) MergeOptions(other ...Option) Options {
return MergeOptions(o, other...)
}
// String ...
func (o localOptions) String() string {
b, _ := json.MarshalIndent(o, "", " ")
return string(b)
}
func indexOfOptions(options []Option, option Option) int {
for i, o := range options {
if matchOption(o, option) {
return i
}
}
return -1
}
func matchOption(left, right Option) bool {
if left.Type() == Argument && right.Type() == Argument {
// we always identify arguments as different entities, even they have the same content.
return false
}
// we identity flags and key value options as map keys therefore they are unique
return getKey(left) == getKey(right)
}
func getKey(o Option) string {
switch n := o.(type) {
case FlagOption:
return n.Flag()
case KeyValueOption:
return n.Key()
case ArgumentOption:
return ""
default:
panic(fmt.Sprintf("unknown type of option %v", reflect.TypeOf(o)))
}
}
type RawOptions struct {
AutorestArguments []string `json:"autorestArguments,omitempty"`
}
func NewRawOptionsFrom(reader io.Reader) (*RawOptions, error) {
b, err := ioutil.ReadAll(reader)
if err != nil {
return nil, err
}
var result RawOptions
if err := json.Unmarshal(b, &result); err != nil {
return nil, err
}
return &result, nil
}
func (r RawOptions) Parse(absSDK string) (Options, error) {
// replace go-sdk-folder value by the absolute path
var argument []Option
for _, v := range r.AutorestArguments {
if strings.HasPrefix(v, "--go-sdk-folder") {
continue
}
if v == "--multiapi" {
continue
}
o, err := NewOption(v)
if err != nil {
return nil, err
}
argument = append(argument, o)
}
argument = append(argument, NewKeyValueOption("go-sdk-folder", absSDK))
o := NewOptions(argument...)
return o, nil
}
|