Skip to content

Commit bf9f607

Browse files
committed
Improve client migration spacing and errs handling
1 parent d04112f commit bf9f607

File tree

2 files changed

+184
-33
lines changed

2 files changed

+184
-33
lines changed

cmd/internal/migrations/v3/client_usage.go

Lines changed: 70 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ var (
2020
clientErrLenPattern = regexp.MustCompile(`\blen\(errs\)`)
2121
clientErrComparePattern = regexp.MustCompile(`err\s*!=\s*nil\s*>\s*0`)
2222
clientErrMapPattern = regexp.MustCompile(`"errs"\s*:\s*errs`)
23-
clientErrVarPattern = regexp.MustCompile(`\berrs\b`)
24-
clientErrsDeclPattern = regexp.MustCompile(`\berrs\s+\[]error\b`)
23+
clientErrsDeclPattern = regexp.MustCompile(`(?m)^\s*var\s+errs\b`)
2524

2625
// Non-alias-dependent patterns
2726
requestFromAgent = regexp.MustCompile(`^([ \t]*)(\w+)\s*:=\s*(\w+)\.Request\(\)\s*$`)
@@ -236,13 +235,17 @@ func rewriteAcquireAgentBlocksWithAlias(content, alias string) (string, bool) {
236235
structStart := -1
237236
preservedLines := []string{}
238237
preservedIdx := []int{}
238+
blankIdx := []int{}
239+
blankAfterParse := false
239240
for k := parseEnd + 1; k < len(lines); k++ {
240241
if skipLines[k] {
241242
continue
242243
}
243244

244245
trimmed := strings.TrimSpace(lines[k])
245246
if trimmed == "" {
247+
blankAfterParse = true
248+
blankIdx = append(blankIdx, k)
246249
continue
247250
}
248251
if strings.HasPrefix(trimmed, "//") {
@@ -270,18 +273,41 @@ func rewriteAcquireAgentBlocksWithAlias(content, alias string) (string, bool) {
270273
}
271274

272275
if structStart == -1 {
273-
out = append(out, line)
274-
continue
276+
structStart = parseEnd
275277
}
276278

277279
structMatch := structAssignPattern.FindStringSubmatch(lines[structStart])
278280
bytesMatch := bytesAssignPattern.FindStringSubmatch(lines[structStart])
279281
stringMatch := stringAssignPattern.FindStringSubmatch(lines[structStart])
282+
parseOnly := len(structMatch) == 0 && len(bytesMatch) == 0 && len(stringMatch) == 0
283+
284+
addPreserved := func() {
285+
if len(preservedLines) == 0 {
286+
return
287+
}
288+
if blankAfterParse && parseOnly {
289+
out = append(out, "")
290+
for _, idx := range blankIdx {
291+
skipLines[idx] = true
292+
}
293+
blankAfterParse = false
294+
}
295+
296+
out = append(out, preservedLines...)
297+
for _, idx := range preservedIdx {
298+
skipLines[idx] = true
299+
}
300+
}
301+
302+
if len(preservedLines) == 0 && !parseOnly {
303+
for _, idx := range blankIdx {
304+
skipLines[idx] = true
305+
}
306+
blankAfterParse = false
307+
}
280308

281309
if len(structMatch) == 0 && len(bytesMatch) == 0 && len(stringMatch) == 0 {
282310
structStart = parseEnd
283-
preservedLines = nil
284-
preservedIdx = nil
285311
}
286312

287313
errName := chooseErrName(out, lines, i)
@@ -322,12 +348,7 @@ func rewriteAcquireAgentBlocksWithAlias(content, alias string) (string, bool) {
322348

323349
switch {
324350
case len(structMatch) > 0 && structMatch[5] == agentVar:
325-
if len(preservedLines) > 0 {
326-
out = append(out, preservedLines...)
327-
for _, idx := range preservedIdx {
328-
skipLines[idx] = true
329-
}
330-
}
351+
addPreserved()
331352
errAssign := errAssignmentOperator(errName, out, lines, i, "resp")
332353
statusVar := strings.TrimSpace(structMatch[2])
333354
bodyVar := strings.TrimSpace(structMatch[3])
@@ -395,12 +416,7 @@ func rewriteAcquireAgentBlocksWithAlias(content, alias string) (string, bool) {
395416
changed = true
396417
continue
397418
case len(bytesMatch) > 0 && bytesMatch[5] == agentVar:
398-
if len(preservedLines) > 0 {
399-
out = append(out, preservedLines...)
400-
for _, idx := range preservedIdx {
401-
skipLines[idx] = true
402-
}
403-
}
419+
addPreserved()
404420
errAssign := errAssignmentOperator(errName, out, lines, i, "resp")
405421
statusVar := strings.TrimSpace(bytesMatch[2])
406422
bodyVar := strings.TrimSpace(bytesMatch[3])
@@ -442,12 +458,7 @@ func rewriteAcquireAgentBlocksWithAlias(content, alias string) (string, bool) {
442458
changed = true
443459
continue
444460
case len(stringMatch) > 0 && stringMatch[5] == agentVar:
445-
if len(preservedLines) > 0 {
446-
out = append(out, preservedLines...)
447-
for _, idx := range preservedIdx {
448-
skipLines[idx] = true
449-
}
450-
}
461+
addPreserved()
451462
errAssign := errAssignmentOperator(errName, out, lines, i, "resp")
452463
statusVar := strings.TrimSpace(stringMatch[2])
453464
bodyVar := strings.TrimSpace(stringMatch[3])
@@ -489,12 +500,18 @@ func rewriteAcquireAgentBlocksWithAlias(content, alias string) (string, bool) {
489500
changed = true
490501
continue
491502
default:
503+
if !parseOnly {
504+
addPreserved()
505+
}
492506
errAssign := errAssignmentOperator(errName, out, lines, i)
493507
respLine := fmt.Sprintf("%s_, %s %s %s.Send()", indent, errName, errAssign, reqVar)
494508
out = append(out, respLine)
495509
out = append(out, fmt.Sprintf("%sif %s != nil {", parseIndent, errName))
496510
out = append(out, replaceErrIdentifier(parseBody[:len(parseBody)-1], errName, false)...)
497511
out = append(out, parseIndent+"}")
512+
if parseOnly {
513+
addPreserved()
514+
}
498515

499516
i = parseEnd
500517
changed = true
@@ -712,17 +729,18 @@ func identifierDeclaredInLines(lines []string, name string) bool {
712729
}
713730

714731
func declaredInVarBlockLine(name, trimmed string) bool {
715-
if !strings.HasPrefix(trimmed, name) {
732+
fields := strings.Fields(trimmed)
733+
if len(fields) < 2 {
716734
return false
717735
}
718-
719-
remainder := strings.TrimSpace(strings.TrimPrefix(trimmed, name))
720-
if remainder == "" {
736+
if fields[0] != name {
721737
return false
722738
}
723739

724-
if strings.Contains(remainder, ":=") || strings.Contains(remainder, "=") {
725-
return false
740+
for _, f := range fields[1:] {
741+
if strings.Contains(f, ":=") || strings.Contains(f, "=") {
742+
return false
743+
}
726744
}
727745

728746
return true
@@ -1185,7 +1203,14 @@ func ensureClientImport(content string) string {
11851203
func rewriteClientErrorHandling(content string) string {
11861204
// Only rewrite when we see the legacy multi-error usage patterns. This avoids
11871205
// mutating unrelated identifiers such as custom "errs" slices.
1188-
hasLegacyErrs := clientErrIfPattern.MatchString(content) || clientErrLenPattern.MatchString(content) || clientErrComparePattern.MatchString(content) || clientErrMapPattern.MatchString(content)
1206+
baseLegacy := clientErrIfPattern.MatchString(content) || clientErrLenPattern.MatchString(content) || clientErrComparePattern.MatchString(content) || clientErrMapPattern.MatchString(content)
1207+
declaredErrs := clientErrsDeclPattern.MatchString(content)
1208+
if !baseLegacy {
1209+
// Declaration-only cases keep errs slices intact.
1210+
return content
1211+
}
1212+
1213+
hasLegacyErrs := baseLegacy || declaredErrs
11891214
if !hasLegacyErrs {
11901215
return content
11911216
}
@@ -1194,8 +1219,20 @@ func rewriteClientErrorHandling(content string) string {
11941219
updated = clientErrLenPattern.ReplaceAllString(updated, "err != nil")
11951220
updated = clientErrComparePattern.ReplaceAllString(updated, "err != nil")
11961221
updated = clientErrMapPattern.ReplaceAllString(updated, `"err": err`)
1197-
updated = clientErrsDeclPattern.ReplaceAllString(updated, "err error")
1198-
updated = clientErrVarPattern.ReplaceAllString(updated, "err")
1222+
1223+
errToken := regexp.MustCompile(`\berrs\b`)
1224+
lines := strings.Split(updated, "\n")
1225+
for i, line := range lines {
1226+
trimmed := strings.TrimSpace(line)
1227+
if strings.HasPrefix(trimmed, "var errs") || strings.HasPrefix(trimmed, "errs") {
1228+
continue
1229+
}
1230+
1231+
lines[i] = errToken.ReplaceAllString(line, "err")
1232+
}
1233+
1234+
updated = strings.Join(lines, "\n")
1235+
11991236
return updated
12001237
}
12011238

cmd/internal/migrations/v3/client_usage_test.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,120 @@ func handler(code string) {
13111311
assert.Equal(t, expected, content)
13121312
}
13131313

1314+
func Test_MigrateClientUsage_AcquireAgentOnlyParseKeepsTrailingCode(t *testing.T) {
1315+
t.Parallel()
1316+
1317+
dir, err := os.MkdirTemp("", "mclientparsepreserve")
1318+
require.NoError(t, err)
1319+
defer func() { require.NoError(t, os.RemoveAll(dir)) }()
1320+
1321+
file := writeTempFile(t, dir, `package main
1322+
1323+
import (
1324+
"fmt"
1325+
1326+
"github.com/gofiber/fiber/v3"
1327+
)
1328+
1329+
func handler(code string) {
1330+
a := fiber.AcquireAgent()
1331+
req := a.Request()
1332+
req.Header.SetMethod(fiber.MethodPost)
1333+
req.SetRequestURI(fmt.Sprintf("https://example.com/auth?code=%s", code))
1334+
if err := a.Parse(); err != nil {
1335+
fmt.Println(err)
1336+
}
1337+
// keep
1338+
value := 123
1339+
_ = value
1340+
}`)
1341+
1342+
var buf bytes.Buffer
1343+
cmd := newCmd(&buf)
1344+
require.NoError(t, v3.MigrateClientUsage(cmd, dir, nil, nil))
1345+
1346+
content := gofmtSource(t, readFile(t, file))
1347+
expected := gofmtSource(t, `package main
1348+
1349+
import (
1350+
"fmt"
1351+
1352+
"github.com/gofiber/fiber/v3/client"
1353+
)
1354+
1355+
func handler(code string) {
1356+
a := client.New()
1357+
req := a.R()
1358+
req.SetMethod("POST")
1359+
req.SetURL(fmt.Sprintf("https://example.com/auth?code=%s", code))
1360+
_, err := req.Send()
1361+
if err != nil {
1362+
fmt.Println(err)
1363+
}
1364+
// keep
1365+
value := 123
1366+
_ = value
1367+
}`)
1368+
1369+
assert.Equal(t, expected, content)
1370+
}
1371+
1372+
func Test_MigrateClientUsage_AcquireAgentOnlyParseIgnoresErrLikeVarNames(t *testing.T) {
1373+
t.Parallel()
1374+
1375+
dir, err := os.MkdirTemp("", "mclientparsevarblock")
1376+
require.NoError(t, err)
1377+
defer func() { require.NoError(t, os.RemoveAll(dir)) }()
1378+
1379+
file := writeTempFile(t, dir, `package main
1380+
1381+
import (
1382+
"github.com/gofiber/fiber/v3"
1383+
)
1384+
1385+
var (
1386+
errMsg string
1387+
)
1388+
1389+
func handler() {
1390+
a := fiber.AcquireAgent()
1391+
req := a.Request()
1392+
req.Header.SetMethod(fiber.MethodGet)
1393+
req.SetRequestURI("https://example.com")
1394+
if err := a.Parse(); err != nil {
1395+
println(err)
1396+
}
1397+
}`)
1398+
1399+
var buf bytes.Buffer
1400+
cmd := newCmd(&buf)
1401+
require.NoError(t, v3.MigrateClientUsage(cmd, dir, nil, nil))
1402+
1403+
content := gofmtSource(t, readFile(t, file))
1404+
expected := gofmtSource(t, `package main
1405+
1406+
import (
1407+
"github.com/gofiber/fiber/v3/client"
1408+
)
1409+
1410+
var (
1411+
errMsg string
1412+
)
1413+
1414+
func handler() {
1415+
a := client.New()
1416+
req := a.R()
1417+
req.SetMethod("GET")
1418+
req.SetURL("https://example.com")
1419+
_, err := req.Send()
1420+
if err != nil {
1421+
println(err)
1422+
}
1423+
}`)
1424+
1425+
assert.Equal(t, expected, content)
1426+
}
1427+
13141428
func Test_MigrateClientUsage_AcquireAgentOnlyParseIgnoresErrLikeNames(t *testing.T) {
13151429
t.Parallel()
13161430

0 commit comments

Comments
 (0)