-
Notifications
You must be signed in to change notification settings - Fork 57
/
args.go
142 lines (123 loc) · 4.02 KB
/
args.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
134
135
136
137
138
139
140
141
142
package testutil
import (
"io"
"net/http"
"regexp"
"strings"
"time"
"github.com/hashicorp/cap/oidc"
"github.com/fastly/cli/pkg/app"
"github.com/fastly/cli/pkg/auth"
"github.com/fastly/cli/pkg/config"
"github.com/fastly/cli/pkg/errors"
"github.com/fastly/cli/pkg/manifest"
"github.com/fastly/cli/pkg/mock"
"github.com/fastly/cli/pkg/runtime"
)
var argsPattern = regexp.MustCompile("`.+`")
// Args is a simple wrapper function designed to accept a CLI command
// (including flags) and return it as a slice for consumption by app.Run().
//
// NOTE: One test file (TestBigQueryCreate) passes RSA content inline into the
// args string which means it has to escape the double quotes (used to infer
// the content should be considered a single argument) with a backtick. This
// causes problems when trying to split the args string by a space (as the RSA
// content has spaces) and so we need to be able to identify when backticks are
// used and ensure the backtick argument is considered a single argument (i.e.
// don't incorrectly split by the spaces within the RSA content when converting
// the arg string into a slice).
//
// The logic checks for backticks, and then replaces the content that is
// surrounded by backticks with --- and then splits the resulting string by
// spaces. Afterwards if there was a backtick matched, then we re-insert the
// backticked content into the slice where --- is found.
func Args(args string) []string {
var backtickMatch []string
if strings.Contains(args, "`") {
backtickMatch = argsPattern.FindStringSubmatch(args)
args = argsPattern.ReplaceAllString(args, "---")
}
s := strings.Split(args, " ")
if len(backtickMatch) > 0 {
for i, v := range s {
if v == "---" {
s[i] = backtickMatch[0]
}
}
}
return s
}
// MockAuthServer is used to no-op the authentication server.
type MockAuthServer struct {
auth.Starter
Result chan auth.AuthorizationResult
}
// GetResult returns the results channel
func (s MockAuthServer) GetResult() chan auth.AuthorizationResult {
return s.Result
}
// SetAccountEndpoint sets the account endpoint.
func (s MockAuthServer) SetAccountEndpoint(_ string) {
// no-op
}
// SetAPIEndpoint sets the API endpoint.
func (s MockAuthServer) SetAPIEndpoint(_ string) {
// no-op
}
// SetVerifier sets the code verifier.
func (s MockAuthServer) SetVerifier(_ *oidc.S256Verifier) {
// no-op
}
// Start starts a local server for handling authentication processing.
func (s MockAuthServer) Start() error {
return nil // no-op
}
// NewRunOpts returns a struct that can be used to populate a call to app.Run()
// while the majority of fields will be pre-populated and only those fields
// commonly changed for testing purposes will need to be provided.
func NewRunOpts(args []string, stdout io.Writer) app.RunOpts {
var md manifest.Data
md.File.Args = args
md.File.SetErrLog(errors.Log)
md.File.SetOutput(stdout)
_ = md.File.Read(manifest.Filename)
configPath := "/dev/null"
if runtime.Windows {
configPath = "NUL"
}
return app.RunOpts{
ConfigPath: configPath,
Args: args,
APIClient: mock.APIClient(mock.API{}),
AuthServer: &MockAuthServer{},
Env: config.Environment{},
ErrLog: errors.Log,
ConfigFile: config.File{
Profiles: TokenProfile(),
},
HTTPClient: &http.Client{Timeout: time.Second * 5},
Manifest: &md,
Opener: func(input string) error {
return nil // no-op
},
Stdout: stdout,
}
}
// TokenProfile generates a mock profile token.
func TokenProfile() config.Profiles {
return config.Profiles{
// IMPORTANT: Tests mock the token to prevent runtime panics.
//
// Tokens are now interactively handled unless a token is provided
// directly via the --token flag or the FASTLY_API_TOKEN env variable.
//
// We force the CLI to skip the interactive prompts by setting a default
// user profile and making sure the timestamp is not expired.
"user": &config.Profile{
AccessTokenCreated: 9999999999, // Year: 2286
Default: true,
Email: "test@example.com",
Token: "mock-token",
},
}
}