5
5
"fmt"
6
6
"os"
7
7
"path/filepath"
8
+ "regexp"
8
9
"runtime"
10
+ "strconv"
9
11
"strings"
10
12
"time"
11
13
@@ -18,6 +20,8 @@ import (
18
20
"go.uber.org/zap"
19
21
"go.uber.org/zap/zapcore"
20
22
exec "golang.org/x/sys/execabs"
23
+
24
+ "vitess.io/vitess/go/mysql"
21
25
)
22
26
23
27
const WarnAuthMessage = "not authenticated yet. Please run 'pscale auth login'"
@@ -166,10 +170,12 @@ func HasHomebrew() bool {
166
170
return err == nil
167
171
}
168
172
173
+ var versionRegex = regexp .MustCompile (`Ver ([0-9]+)\.([0-9]+)\.([0-9]+)` )
174
+
169
175
// MySQLClientPath checks whether the 'mysql' client exists and returns the
170
176
// path to the binary. The returned error contains instructions to install the
171
177
// client.
172
- func MySQLClientPath () (string , error ) {
178
+ func MySQLClientPath () (string , mysql. AuthMethodDescription , error ) {
173
179
// 'brew install mysql-client' installs the client into an unusual path
174
180
// https://docs.brew.sh/FAQ#why-should-i-install-homebrew-in-the-default-location
175
181
var homebrewPrefix string
@@ -183,30 +189,55 @@ func MySQLClientPath() (string, error) {
183
189
homebrewPrefix = "/home/linuxbrew/.linuxbrew"
184
190
}
185
191
192
+ authMethod := mysql .CachingSha2Password
186
193
oldpath := os .Getenv ("PATH" )
187
- newpath := homebrewPrefix + "/opt/mysql-client/bin/" + string (os .PathListSeparator ) + oldpath
194
+ newpath := homebrewPrefix + "/opt/mysql-client/bin/" +
195
+ homebrewPrefix + "/opt/mysql/bin/" +
196
+ string (os .PathListSeparator ) + oldpath
188
197
defer func () {
189
198
if err := os .Setenv ("PATH" , oldpath ); err != nil {
190
199
fmt .Println ("failed to restore PATH" , err )
191
200
}
192
201
}()
193
202
194
203
if err := os .Setenv ("PATH" , newpath ); err != nil {
195
- return "" , err
204
+ return "" , authMethod , err
196
205
}
197
206
198
207
path , err := exec .LookPath ("mysql" )
199
- if err == nil {
200
- return path , nil
208
+ if err != nil {
209
+ return installInstructions ("couldn't find the 'mysql' command-line tool required to run this command." )
210
+ }
211
+
212
+ cmd := exec .Command ("mysql" , "--version" )
213
+ out , err := cmd .Output ()
214
+ if err != nil {
215
+ return "" , authMethod , fmt .Errorf ("failed to run 'mysql --version': %w" , err )
216
+ }
217
+
218
+ v := versionRegex .FindStringSubmatch (string (out ))
219
+ if len (v ) != 4 {
220
+ return "" , authMethod , fmt .Errorf ("could not parse server version from: %s" , string (out ))
221
+ }
222
+ major , err := strconv .Atoi (v [1 ])
223
+ if err != nil {
224
+ return "" , authMethod , fmt .Errorf ("could not parse server version from: %s" , string (out ))
201
225
}
202
226
203
- msg := "couldn't find the 'mysql' command-line tool required to run this command."
227
+ if major < 8 {
228
+ authMethod = mysql .MysqlNativePassword
229
+ }
230
+
231
+ return path , authMethod , nil
232
+ }
233
+
234
+ func installInstructions (msg string ) (string , mysql.AuthMethodDescription , error ) {
204
235
installURL := "https://planetscale.com/docs/reference/planetscale-environment-setup"
205
236
206
237
switch runtime .GOOS {
207
238
case "darwin" :
208
239
if HasHomebrew () {
209
- return "" , fmt .Errorf ("%s\n To install, run: brew install mysql-client" , msg )
240
+ return "" , mysql . CachingSha2Password , fmt .Errorf ("%s\n To install, run: brew install mysql-client@8.4 " , msg )
210
241
}
211
242
212
243
installURL = "https://planetscale.com/docs/reference/planetscale-environment-setup#macos-instructions"
@@ -216,7 +247,7 @@ func MySQLClientPath() (string, error) {
216
247
installURL = "https://planetscale.com/docs/reference/planetscale-environment-setup#windows-instructions"
217
248
}
218
249
219
- return "" , fmt .Errorf ("%s\n To install, follow the instructions: %s" , msg , installURL )
250
+ return "" , mysql . CachingSha2Password , fmt .Errorf ("%s\n To install, follow the instructions: %s" , msg , installURL )
220
251
}
221
252
222
253
func ParseSSLMode (sslMode string ) ps.ExternalDataSourceSSLVerificationMode {
0 commit comments