[tools] gpls/internal/golang: check conditions for package move

13 views
Skip to first unread message

Madeline Kalil (Gerrit)

unread,
Oct 27, 2025, 1:35:41 PMOct 27
to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
Attention needed from Robert Findley

Madeline Kalil voted and added 1 comment

Votes added by Madeline Kalil

Commit-Queue+1

1 comment

Patchset-level comments
File-level comment, Patchset 13 (Latest):
Robert Findley . resolved

Hi! Do you want me to review this? It's marked as WIP but I'm happy to take an initial pass.

Madeline Kalil

Yes, it would be great if you can do an initial pass of review. Thanks!

Open in Gerrit

Related details

Attention is currently required from:
  • Robert Findley
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
Gerrit-Change-Number: 712160
Gerrit-PatchSet: 13
Gerrit-Owner: Madeline Kalil <mka...@google.com>
Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
Gerrit-Reviewer: Robert Findley <rfin...@google.com>
Gerrit-Attention: Robert Findley <rfin...@google.com>
Gerrit-Comment-Date: Mon, 27 Oct 2025 17:35:36 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Comment-In-Reply-To: Robert Findley <rfin...@google.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Robert Findley (Gerrit)

unread,
Oct 27, 2025, 2:27:30 PMOct 27
to Madeline Kalil, goph...@pubsubhelper.golang.org, Go LUCI, golang-co...@googlegroups.com
Attention needed from Madeline Kalil

Robert Findley added 7 comments

Patchset-level comments
Robert Findley . resolved

Nice. Took a quick pass through this and it generally LGTM, but we should try to clarify as much as possible while we're looking at this code.

Will probably have more comments after the initial comments are addressed.

File gopls/internal/golang/rename.go
Line 462, Patchset 13 (Latest): var isPkgPath bool
Robert Findley . unresolved
```
var (
isPkgPath bool
err error
)
```

It may be convenient to use the err in scope, but that is action at a distance that should be avoided. If your only goal is to inspect the local error value, use a local variable.

Line 938, Patchset 13 (Latest):func renamePackageName(ctx context.Context, s *cache.Snapshot, pkg *cache.Package, f file.Handle, newName PackageName, newPath PackagePath) (map[protocol.DocumentURI][]diff.Edit, error) {
Robert Findley . unresolved

Call this just 'movePackage' or 'moveAndRenamePackage', since it's doing more than just renaming?

Line 945, Patchset 13 (Latest): oldBase := f.URI().DirPath()
Robert Findley . unresolved

Shouldn't this be 'oldDir'?

A basename is the last component, not the dir, so this is confusing. (I know it's preexisting, but we should clarify while we're looking at it).

Line 948, Patchset 13 (Latest): // package move
Robert Findley . unresolved

Both of these are package moves though.

Line 1049, Patchset 13 (Latest):func renamePackage(ctx context.Context, s *cache.Snapshot, f file.Handle, newName PackageName, newPkgPath PackagePath) (map[protocol.DocumentURI][]diff.Edit, error) {
Robert Findley . unresolved

Now I'm confused as to what to call this, and why it would differ from 'movePackage' above. Maybe we should unify them? WDYT?

File gopls/internal/golang/rename_check.go
Line 936, Patchset 13 (Latest):func isValidPackagePath(curPkg *cache.Package, f file.Handle, newName string) (isPkgPath bool, err error) {
Robert Findley . unresolved

It was a little unclear to me how to use this from reading its usage above.

How about refactoring this slightly, to return a pkgPath and name, and then you don't need getNewPkgDir, which is called in multiple places.

Or am I missing something?

```
// checkPackageRename returns the effective new package directory and name
// resulting from renaming the current package to newName, which may be an
// identifier or a package path.
//
// An error is returned if the renaming is invalid.
func checkPackageRename(curPkg *cache.Package, f file.Handle, newName) (dir string, name PkgName, err error)
```

Open in Gerrit

Related details

Attention is currently required from:
  • Madeline Kalil
Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: tools
    Gerrit-Branch: master
    Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
    Gerrit-Change-Number: 712160
    Gerrit-PatchSet: 13
    Gerrit-Owner: Madeline Kalil <mka...@google.com>
    Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
    Gerrit-Reviewer: Robert Findley <rfin...@google.com>
    Gerrit-Attention: Madeline Kalil <mka...@google.com>
    Gerrit-Comment-Date: Mon, 27 Oct 2025 18:27:27 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy

    Madeline Kalil (Gerrit)

    unread,
    Oct 28, 2025, 2:44:40 PMOct 28
    to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
    Attention needed from Madeline Kalil

    Madeline Kalil uploaded new patchset

    Madeline Kalil uploaded patch set #14 to this change.
    Following approvals got outdated and were removed:
    • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
    Open in Gerrit

    Related details

    Attention is currently required from:
    • Madeline Kalil
    Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: newpatchset
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 14
      unsatisfied_requirement
      open
      diffy

      Madeline Kalil (Gerrit)

      unread,
      Oct 28, 2025, 2:53:52 PMOct 28
      to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
      Attention needed from Madeline Kalil

      Madeline Kalil uploaded new patchset

      Madeline Kalil uploaded patch set #15 to this change.
      Open in Gerrit

      Related details

      Attention is currently required from:
      • Madeline Kalil
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: newpatchset
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 15
      unsatisfied_requirement
      open
      diffy

      Madeline Kalil (Gerrit)

      unread,
      Oct 28, 2025, 3:05:19 PMOct 28
      to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
      Attention needed from Madeline Kalil

      Madeline Kalil uploaded new patchset

      Madeline Kalil uploaded patch set #16 to this change.
      Open in Gerrit

      Related details

      Attention is currently required from:
      • Madeline Kalil
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: newpatchset
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 16
      unsatisfied_requirement
      open
      diffy

      Madeline Kalil (Gerrit)

      unread,
      Oct 28, 2025, 3:05:30 PMOct 28
      to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
      Attention needed from Robert Findley

      Madeline Kalil voted and added 6 comments

      Votes added by Madeline Kalil

      Commit-Queue+1

      6 comments

      File gopls/internal/golang/rename.go
      Line 462, Patchset 13: var isPkgPath bool
      Robert Findley . resolved
      ```
      var (
      isPkgPath bool
      err error
      )
      ```

      It may be convenient to use the err in scope, but that is action at a distance that should be avoided. If your only goal is to inspect the local error value, use a local variable.

      Madeline Kalil

      Done

      Line 938, Patchset 13:func renamePackageName(ctx context.Context, s *cache.Snapshot, pkg *cache.Package, f file.Handle, newName PackageName, newPath PackagePath) (map[protocol.DocumentURI][]diff.Edit, error) {
      Robert Findley . resolved

      Call this just 'movePackage' or 'moveAndRenamePackage', since it's doing more than just renaming?

      Madeline Kalil

      Went with moveAndRenamePackage

      Line 945, Patchset 13: oldBase := f.URI().DirPath()
      Robert Findley . resolved

      Shouldn't this be 'oldDir'?

      A basename is the last component, not the dir, so this is confusing. (I know it's preexisting, but we should clarify while we're looking at it).

      Madeline Kalil

      Good catch, thanks.

      Line 948, Patchset 13: // package move
      Robert Findley . unresolved

      Both of these are package moves though.

      Madeline Kalil

      But in the second case, the package directory stays the same. We pass PackagePath("") for the newPath if we determine that just the package name is changing, not the package directory. I'll update the comment

      EDIT: Nevermind - this part got removed now that checkPackageName returns the effective new package directory and we always pass a value for newPath

      Line 1049, Patchset 13:func renamePackage(ctx context.Context, s *cache.Snapshot, f file.Handle, newName PackageName, newPkgPath PackagePath) (map[protocol.DocumentURI][]diff.Edit, error) {
      Robert Findley . unresolved

      Now I'm confused as to what to call this, and why it would differ from 'movePackage' above. Maybe we should unify them? WDYT?

      Madeline Kalil

      Yeah, the names are rather confusing.
      moveAndRenamePackage seems like a good outer function name.
      renamePackage updates package and import declarations in all affected packages, so maybe we should call it updateImportsAndPackageDecls or just updatePackageDecls?
      moveAndRenamePackage itself just updates replace directives in go.mod files, which I'll extract to its own function.

      File gopls/internal/golang/rename_check.go
      Line 936, Patchset 13:func isValidPackagePath(curPkg *cache.Package, f file.Handle, newName string) (isPkgPath bool, err error) {
      Robert Findley . unresolved

      It was a little unclear to me how to use this from reading its usage above.

      How about refactoring this slightly, to return a pkgPath and name, and then you don't need getNewPkgDir, which is called in multiple places.

      Or am I missing something?

      ```
      // checkPackageRename returns the effective new package directory and name
      // resulting from renaming the current package to newName, which may be an
      // identifier or a package path.
      //
      // An error is returned if the renaming is invalid.
      func checkPackageRename(curPkg *cache.Package, f file.Handle, newName) (dir string, name PkgName, err error)
      ```

      Madeline Kalil

      Sounds good, I agree about de-duplicating the work in getNewPkgDir. We still need to know if the user entered a string that would constitute a package move because if package move is disabled we shouldn't allow this

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Robert Findley
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 16
      Gerrit-Owner: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Robert Findley <rfin...@google.com>
      Gerrit-Attention: Robert Findley <rfin...@google.com>
      Gerrit-Comment-Date: Tue, 28 Oct 2025 19:05:25 +0000
      unsatisfied_requirement
      open
      diffy

      Robert Findley (Gerrit)

      unread,
      Oct 29, 2025, 12:36:07 PMOct 29
      to Madeline Kalil, goph...@pubsubhelper.golang.org, Go LUCI, golang-co...@googlegroups.com
      Attention needed from Madeline Kalil

      Robert Findley added 9 comments

      Patchset-level comments
      File-level comment, Patchset 16 (Latest):
      Robert Findley . unresolved

      The test failures look related.

      File gopls/internal/golang/rename.go
      Line 463, Patchset 16 (Latest): if isPkgPath && !snapshot.Options().PackageMove {
      return nil, fmt.Errorf("a full package path is specified but internal setting 'packageMove' is not enabled")
      }
      Robert Findley . unresolved

      If err is non-nil, do we need to handle isPkgPath? Generally speaking, when a non-nil error is returned, other results are undefined.

      Line 470, Patchset 16 (Latest): editMap, err = moveAndRenamePackage(ctx, snapshot, f, PackageName(newPkgName), PackagePath(newName), newPkgDir)
      Robert Findley . unresolved

      We don't actually need to call 'moveAndRenamePackage' twice here: the only difference is the package path argument. If you refactor into one call, then the surrounding logic can be pushed down into that function (which I suggest renaming back to just 'renamePackage'), simplifying the call site here.

      Line 486, Patchset 16 (Latest): } else {
      Robert Findley . unresolved

      I got rather confused by the multiple nested 'elses' here.

      We already factor out 'renameOrdinary', perhaps we should factor out the above clause into 'renamePackage', now that it's gotten more complicated.

      I understand the factoring is getting very confusing, which multiple things that look like 'rename package'. Let me go through and see if I can suggest further improvements.

      Line 941, Patchset 16 (Latest):func moveAndRenamePackage(ctx context.Context, s *cache.Snapshot, f file.Handle, newName PackageName, newPath PackagePath, newPkgDir string) (map[protocol.DocumentURI][]diff.Edit, error) {
      Robert Findley . unresolved

      Let's just call this 'renamePackage', to be the analog of 'renameOrdinary', and push down the logic from the call site here.

      Sorry if this is conflicting with earlier advice--the pre-existing factoring of this control flow was already confusing, and I'm slowly starting to understand it again. Happy to sit down and pair on this if it would help.

      File gopls/internal/golang/rename_check.go
      Line 923, Patchset 16 (Latest):// identifier or a package path. It also returns a bool that is true when
      // the newName is a package path.
      Robert Findley . unresolved

      I think it may be clearer to pass in the snapshot here (or snapshot.Options()) and avoid returning isPkgPath, so that the call site doesn't need to know about whether or not package path renaming is supported.

      Line 940, Patchset 16 (Latest): isPkgPath = fs.ValidPath(newName) && !validIdent
      Robert Findley . unresolved

      If you flip the ordering of these two operands, you can avoid the call to ValidPath when the name is an identifier.

      Line 959, Patchset 16 (Latest): } else if validIdent {
      // Not an attempted move. Check if a directory already exists at that
      // path, in which case we should not allow renaming.
      newPkgDir = filepath.Join(filepath.Dir(f.URI().DirPath()), newName)
      newPkgName = PackageName(newName)
      _, err := os.Stat(newPkgDir)
      if err == nil {
      // Directory already exists, return an error.
      return "", "", false, fmt.Errorf("invalid package identifier: %q already exists", newName)
      }
      Robert Findley . unresolved

      ...or better, just handle the validIdent early, before you even compute isPkgPath, with an early return.

      The nested control flow increases cyclomatic complexity, and can make the code harder to read. By handling the isValidIdent early, you eliminate the relationship between isValidIdent and isPkgPath, and reduce nesting.

      Line 969, Patchset 16 (Latest): } else {
      return "", "", false, fmt.Errorf("invalid package path or identifier %q", newName)
      }
      Robert Findley . unresolved

      Similar to other suggestion, this also can be handled with an early return, to reduce nesting.
      https://go.dev/wiki/CodeReviewComments#indent-error-flow

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Madeline Kalil
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 16
      Gerrit-Owner: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Robert Findley <rfin...@google.com>
      Gerrit-Attention: Madeline Kalil <mka...@google.com>
      Gerrit-Comment-Date: Wed, 29 Oct 2025 16:36:04 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      unsatisfied_requirement
      open
      diffy

      Madeline Kalil (Gerrit)

      unread,
      Oct 30, 2025, 11:14:31 AM (13 days ago) Oct 30
      to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
      Attention needed from Madeline Kalil

      Madeline Kalil uploaded new patchset

      Madeline Kalil uploaded patch set #17 to this change.
      Following approvals got outdated and were removed:
      • TryBots-Pass: LUCI-TryBot-Result-1 by Go LUCI
      Open in Gerrit

      Related details

      Attention is currently required from:
      • Madeline Kalil
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: newpatchset
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 17
      unsatisfied_requirement
      open
      diffy

      Madeline Kalil (Gerrit)

      unread,
      Oct 30, 2025, 11:15:21 AM (13 days ago) Oct 30
      to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
      Attention needed from Robert Findley

      Madeline Kalil voted and added 12 comments

      Votes added by Madeline Kalil

      Commit-Queue+1

      12 comments

      Patchset-level comments
      Robert Findley . unresolved

      The test failures look related.

      Madeline Kalil

      Yeah, windows :( trying to figure it out
      Also still need to add tests for import cycles and nested directories that don't exist

      File gopls/internal/golang/rename.go
      Line 463, Patchset 16: if isPkgPath && !snapshot.Options().PackageMove {

      return nil, fmt.Errorf("a full package path is specified but internal setting 'packageMove' is not enabled")
      }
      Robert Findley . resolved

      If err is non-nil, do we need to handle isPkgPath? Generally speaking, when a non-nil error is returned, other results are undefined.

      Madeline Kalil

      Refactored this part

      Line 470, Patchset 16: editMap, err = moveAndRenamePackage(ctx, snapshot, f, PackageName(newPkgName), PackagePath(newName), newPkgDir)
      Robert Findley . resolved

      We don't actually need to call 'moveAndRenamePackage' twice here: the only difference is the package path argument. If you refactor into one call, then the surrounding logic can be pushed down into that function (which I suggest renaming back to just 'renamePackage'), simplifying the call site here.

      Madeline Kalil

      I think this works well with having checkRenamePackage return newPkgDir, newPkgName, newPkgPath and err, so the caller doesn't have to worry about the settings

      Line 486, Patchset 16: } else {
      Robert Findley . resolved

      I got rather confused by the multiple nested 'elses' here.

      We already factor out 'renameOrdinary', perhaps we should factor out the above clause into 'renamePackage', now that it's gotten more complicated.

      I understand the factoring is getting very confusing, which multiple things that look like 'rename package'. Let me go through and see if I can suggest further improvements.

      Madeline Kalil

      Acknowledged

      Line 941, Patchset 16:func moveAndRenamePackage(ctx context.Context, s *cache.Snapshot, f file.Handle, newName PackageName, newPath PackagePath, newPkgDir string) (map[protocol.DocumentURI][]diff.Edit, error) {
      Robert Findley . resolved

      Let's just call this 'renamePackage', to be the analog of 'renameOrdinary', and push down the logic from the call site here.

      Sorry if this is conflicting with earlier advice--the pre-existing factoring of this control flow was already confusing, and I'm slowly starting to understand it again. Happy to sit down and pair on this if it would help.

      Madeline Kalil

      Done

      Line 948, Patchset 13: // package move
      Robert Findley . resolved

      Both of these are package moves though.

      Madeline Kalil

      But in the second case, the package directory stays the same. We pass PackagePath("") for the newPath if we determine that just the package name is changing, not the package directory. I'll update the comment

      EDIT: Nevermind - this part got removed now that checkPackageName returns the effective new package directory and we always pass a value for newPath

      Madeline Kalil

      Acknowledged

      Line 1049, Patchset 13:func renamePackage(ctx context.Context, s *cache.Snapshot, f file.Handle, newName PackageName, newPkgPath PackagePath) (map[protocol.DocumentURI][]diff.Edit, error) {
      Robert Findley . resolved

      Now I'm confused as to what to call this, and why it would differ from 'movePackage' above. Maybe we should unify them? WDYT?

      Madeline Kalil

      Yeah, the names are rather confusing.
      moveAndRenamePackage seems like a good outer function name.
      renamePackage updates package and import declarations in all affected packages, so maybe we should call it updateImportsAndPackageDecls or just updatePackageDecls?
      moveAndRenamePackage itself just updates replace directives in go.mod files, which I'll extract to its own function.

      Madeline Kalil

      Acknowledged

      File gopls/internal/golang/rename_check.go
      Line 923, Patchset 16:// identifier or a package path. It also returns a bool that is true when

      // the newName is a package path.
      Robert Findley . resolved

      I think it may be clearer to pass in the snapshot here (or snapshot.Options()) and avoid returning isPkgPath, so that the call site doesn't need to know about whether or not package path renaming is supported.

      Madeline Kalil

      Done

      Line 936, Patchset 13:func isValidPackagePath(curPkg *cache.Package, f file.Handle, newName string) (isPkgPath bool, err error) {
      Robert Findley . resolved

      It was a little unclear to me how to use this from reading its usage above.

      How about refactoring this slightly, to return a pkgPath and name, and then you don't need getNewPkgDir, which is called in multiple places.

      Or am I missing something?

      ```
      // checkPackageRename returns the effective new package directory and name
      // resulting from renaming the current package to newName, which may be an

      // identifier or a package path.

      //
      // An error is returned if the renaming is invalid.
      func checkPackageRename(curPkg *cache.Package, f file.Handle, newName) (dir string, name PkgName, err error)
      ```

      Madeline Kalil

      Sounds good, I agree about de-duplicating the work in getNewPkgDir. We still need to know if the user entered a string that would constitute a package move because if package move is disabled we shouldn't allow this

      Madeline Kalil

      Done

      Line 940, Patchset 16: isPkgPath = fs.ValidPath(newName) && !validIdent
      Robert Findley . resolved

      If you flip the ordering of these two operands, you can avoid the call to ValidPath when the name is an identifier.

      Madeline Kalil

      Done

      Line 959, Patchset 16: } else if validIdent {

      // Not an attempted move. Check if a directory already exists at that
      // path, in which case we should not allow renaming.
      newPkgDir = filepath.Join(filepath.Dir(f.URI().DirPath()), newName)
      newPkgName = PackageName(newName)
      _, err := os.Stat(newPkgDir)
      if err == nil {
      // Directory already exists, return an error.
      return "", "", false, fmt.Errorf("invalid package identifier: %q already exists", newName)
      }
      Robert Findley . resolved

      ...or better, just handle the validIdent early, before you even compute isPkgPath, with an early return.

      The nested control flow increases cyclomatic complexity, and can make the code harder to read. By handling the isValidIdent early, you eliminate the relationship between isValidIdent and isPkgPath, and reduce nesting.

      Madeline Kalil

      Thanks, it's cleaner with the early returns


      return "", "", false, fmt.Errorf("invalid package path or identifier %q", newName)
      }
      Robert Findley . resolved

      Similar to other suggestion, this also can be handled with an early return, to reduce nesting.
      https://go.dev/wiki/CodeReviewComments#indent-error-flow

      Madeline Kalil

      Done

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Robert Findley
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 17
      Gerrit-Owner: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Robert Findley <rfin...@google.com>
      Gerrit-Attention: Robert Findley <rfin...@google.com>
      Gerrit-Comment-Date: Thu, 30 Oct 2025 15:15:17 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes
      Comment-In-Reply-To: Madeline Kalil <mka...@google.com>
      Comment-In-Reply-To: Robert Findley <rfin...@google.com>
      unsatisfied_requirement
      open
      diffy

      Madeline Kalil (Gerrit)

      unread,
      Oct 30, 2025, 3:16:31 PM (13 days ago) Oct 30
      to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
      Attention needed from Madeline Kalil and Robert Findley

      Madeline Kalil uploaded new patchset

      Madeline Kalil uploaded patch set #18 to this change.
      Following approvals got outdated and were removed:
      • TryBots-Pass: LUCI-TryBot-Result-1 by Go LUCI
      Open in Gerrit

      Related details

      Attention is currently required from:
      • Madeline Kalil
      • Robert Findley
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: newpatchset
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 18
      Gerrit-Owner: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Robert Findley <rfin...@google.com>
      Gerrit-Attention: Madeline Kalil <mka...@google.com>
      Gerrit-Attention: Robert Findley <rfin...@google.com>
      unsatisfied_requirement
      open
      diffy

      Madeline Kalil (Gerrit)

      unread,
      Oct 30, 2025, 3:17:00 PM (13 days ago) Oct 30
      to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
      Attention needed from Robert Findley

      Madeline Kalil voted Commit-Queue+1

      Commit-Queue+1
      Open in Gerrit

      Related details

      Attention is currently required from:
      • Robert Findley
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 18
      Gerrit-Owner: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Robert Findley <rfin...@google.com>
      Gerrit-Attention: Robert Findley <rfin...@google.com>
      Gerrit-Comment-Date: Thu, 30 Oct 2025 19:16:57 +0000
      Gerrit-HasComments: No
      Gerrit-Has-Labels: Yes
      unsatisfied_requirement
      open
      diffy

      Madeline Kalil (Gerrit)

      unread,
      Oct 30, 2025, 4:12:42 PM (13 days ago) Oct 30
      to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
      Attention needed from Madeline Kalil and Robert Findley

      Madeline Kalil uploaded new patchset

      Madeline Kalil uploaded patch set #19 to this change.
      Following approvals got outdated and were removed:
      • TryBots-Pass: LUCI-TryBot-Result-1 by Go LUCI
      Open in Gerrit

      Related details

      Attention is currently required from:
      • Madeline Kalil
      • Robert Findley
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: newpatchset
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 19
      Gerrit-Owner: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Robert Findley <rfin...@google.com>
      unsatisfied_requirement
      open
      diffy

      Madeline Kalil (Gerrit)

      unread,
      Oct 30, 2025, 4:13:10 PM (13 days ago) Oct 30
      to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com

      Madeline Kalil voted Commit-Queue+1

      Commit-Queue+1
      Open in Gerrit

      Related details

      Attention set is empty
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 19
      Gerrit-Owner: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Robert Findley <rfin...@google.com>
      Gerrit-Comment-Date: Thu, 30 Oct 2025 20:13:07 +0000
      Gerrit-HasComments: No
      Gerrit-Has-Labels: Yes
      unsatisfied_requirement
      open
      diffy

      Madeline Kalil (Gerrit)

      unread,
      Oct 30, 2025, 4:41:41 PM (13 days ago) Oct 30
      to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
      Attention needed from Madeline Kalil

      Madeline Kalil uploaded new patchset

      Madeline Kalil uploaded patch set #20 to this change.
      Following approvals got outdated and were removed:
      • TryBots-Pass: LUCI-TryBot-Result-1 by Go LUCI
      Open in Gerrit

      Related details

      Attention is currently required from:
      • Madeline Kalil
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: newpatchset
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 20
      Gerrit-Owner: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Robert Findley <rfin...@google.com>
      Gerrit-Attention: Madeline Kalil <mka...@google.com>
      unsatisfied_requirement
      open
      diffy

      Madeline Kalil (Gerrit)

      unread,
      Oct 30, 2025, 4:42:29 PM (13 days ago) Oct 30
      to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com

      Madeline Kalil voted Commit-Queue+1

      Commit-Queue+1
      Open in Gerrit

      Related details

      Attention set is empty
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
      Gerrit-Change-Number: 712160
      Gerrit-PatchSet: 20
      Gerrit-Owner: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
      Gerrit-Reviewer: Robert Findley <rfin...@google.com>
      Gerrit-Comment-Date: Thu, 30 Oct 2025 20:42:26 +0000
      Gerrit-HasComments: No
      Gerrit-Has-Labels: Yes
      unsatisfied_requirement
      open
      diffy

      Robert Findley (Gerrit)

      unread,
      Oct 31, 2025, 12:36:50 PM (12 days ago) Oct 31
      to Madeline Kalil, goph...@pubsubhelper.golang.org, Go LUCI, golang-co...@googlegroups.com

      Robert Findley added 12 comments

      File gopls/internal/golang/rename.go
      Line 457, Patchset 20 (Latest): var (
      newPkgName PackageName
      newPkgPath PackagePath
      err error
      )
      if newPkgDir, newPkgName, newPkgPath, err = checkPackageRename(snapshot.Options(), pkg, f, newName); err != nil {
      Robert Findley . unresolved

      Looks like these can now be declared with a short variable declaration.

      newPkgDir, newPkgName, newPkgPath, err := ...
      if err != nil {
      ...
      }
      Line 524, Patchset 20 (Latest): if inPackageName {
      Robert Findley . unresolved

      Can you remind me why we can't just do this in 'renamePackage'? Is it because we don't have the ability to specify a rename document change?

      I think that's it. In that case, leave an explanatory comment? The factoring sticks out as not-quite-right, and while I don't think we should work on improving it now, let's at least record why it is the way it is.

      Line 525, Patchset 20 (Latest): oldDir := f.URI().DirPath()
      Robert Findley . unresolved

      Nit: call this 'oldPkgDir' for symmetry, or just inline below.

      Line 526, Patchset 17: changes = append(changes,
      protocol.DocumentChangeRename(
      protocol.URIFromPath(oldDir),
      protocol.URIFromPath(newPkgDir)))
      Robert Findley . unresolved

      So, this actually looks wrong.

      What if we're renaming a/b, and there's an a/b/c. Doesn't this implicitly move the 'c' directory as well?

      What if we're renaming a/b to a, and there are no `go` files in `a`. Can't we support that, by just moving the files?

      I think we need to...
      1. Check that there are no go files in newPkgDir (or newPkgDir is missing).
      2. Create newPkgDir if it doesn't exist.
      3. Move each file from oldPkgDir.
      4. Delete oldPkgDir if it's now empty.

      Line 923, Patchset 20 (Latest):// renamePackage renames package declarations, imports, and go.mod files.
      Robert Findley . unresolved

      Add:
      ```
      //
      // f is the file originating the rename, and therefore f.URI().Dir() is the
      // package directory. newName, newPath, and newDir describe the renaming.
      ```

      Line 924, Patchset 20 (Latest):func renamePackage(ctx context.Context, s *cache.Snapshot, f file.Handle, newName PackageName, newPath PackagePath, newPkgDir string) (map[protocol.DocumentURI][]diff.Edit, error) {
      Robert Findley . unresolved

      We don't say 'newPkgPath', so this should just be 'newDir'. The pkg is implied.

      Line 926, Patchset 20 (Latest): renamingEdits, err := updatePackageDeclsAndImports(ctx, s, f, newName, newPath)
      Robert Findley . unresolved

      Nit: 'renamingEdits' is unnecessarily long, since the function name is 'renamePackage'. How about just 'edits'?

      Line 931, Patchset 20 (Latest): renamingEdits, err = updateModFiles(ctx, s, f.URI().DirPath(), newPkgDir, renamingEdits)
      Robert Findley . unresolved

      No need to return renamingEdits here.

      How about just passing in the edits map to both updatePackageDeclsAndImports, and to updateModFiles?

      Line 1148, Patchset 20 (Latest): moveToInternal := snapshot.Options().PackageMove && (strings.Contains(string(newName), "internal") || strings.Contains(string(newPath), "internal"))
      Robert Findley . unresolved

      This doesn't look quite right.

      1. validating whether a renaming is valid shouldn't depend on the PackageMove option: at this point, we've already handled PackageMove, and whether the move is valid is independent of how we got to it.
      2. The condition on importers should be a function of dep path and import path. We shouldn't allow the move if the new import is invalid. See `metadata.IsValidImport`.

      File gopls/internal/golang/rename_check.go
      Line 926, Patchset 17:func checkPackageRename(opts *settings.Options, curPkg *cache.Package, f file.Handle, newName string) (newPkgDir string, newPkgName PackageName, newPkgPath PackagePath, err error) {
      Robert Findley . unresolved

      We can only perform the package rename if curPkg holds ALL Go files in its directory. If there are any other Go files present, the rename may result in a broken build.

      We can do better by trying to find builds that cover all go files, but for now let's just be conservative.

      Line 946, Patchset 20 (Latest): // Directory already exists, return an error.
      Robert Findley . unresolved

      "Directory or file already exists at this path; return an error."?

      Line 952, Patchset 17: if !strings.Contains(newName, string(os.PathSeparator)) {
      Robert Findley . unresolved

      I don't understand this: doesn't PrepareRename prompt with the package path?

      If newName is not an identifier, is it a directory or package path? I thought the latter.

      I think the logic here needs to check:
      1. That modPath+"/" is a prefix of the new path.
      2. That filepath.Join(modDir, filepath.FromSlash(strings.TrimPrefix(newName, modPath+"/"))) is a valid path.
      3. That the new path creates a new package.

      Open in Gerrit

      Related details

      Attention set is empty
      Submit Requirements:
        • requirement is not satisfiedCode-Review
        • requirement is not satisfiedNo-Unresolved-Comments
        • requirement is not satisfiedReview-Enforcement
        • requirement satisfiedTryBots-Pass
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: tools
        Gerrit-Branch: master
        Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
        Gerrit-Change-Number: 712160
        Gerrit-PatchSet: 17
        Gerrit-Owner: Madeline Kalil <mka...@google.com>
        Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
        Gerrit-Reviewer: Robert Findley <rfin...@google.com>
        Gerrit-Comment-Date: Fri, 31 Oct 2025 16:36:46 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        unsatisfied_requirement
        satisfied_requirement
        open
        diffy

        Madeline Kalil (Gerrit)

        unread,
        Nov 4, 2025, 5:19:51 PM (8 days ago) Nov 4
        to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
        Attention needed from Madeline Kalil

        Madeline Kalil uploaded new patchset

        Madeline Kalil uploaded patch set #21 to this change.
        Following approvals got outdated and were removed:
        • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
        Open in Gerrit

        Related details

        Attention is currently required from:
        • Madeline Kalil
        Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: newpatchset
          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
          Gerrit-Change-Number: 712160
          Gerrit-PatchSet: 21
          Gerrit-Owner: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Robert Findley <rfin...@google.com>
          Gerrit-Attention: Madeline Kalil <mka...@google.com>
          unsatisfied_requirement
          open
          diffy

          Madeline Kalil (Gerrit)

          unread,
          Nov 4, 2025, 5:20:03 PM (8 days ago) Nov 4
          to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
          Attention needed from Robert Findley

          Madeline Kalil added 13 comments

          Patchset-level comments
          Robert Findley . unresolved

          The test failures look related.

          Madeline Kalil

          Yeah, windows :( trying to figure it out
          Also still need to add tests for import cycles and nested directories that don't exist

          Madeline Kalil

          Turns out you don't need to explicitly create directories that don't exist, you can just use RenameFile in a DocumentChange and it will create the directories. Still need to add a test for an import cycle

          File gopls/internal/golang/rename.go

          newPkgName PackageName
          newPkgPath PackagePath
          err error
          )
          if newPkgDir, newPkgName, newPkgPath, err = checkPackageRename(snapshot.Options(), pkg, f, newName); err != nil {
          Robert Findley . unresolved

          Looks like these can now be declared with a short variable declaration.

          newPkgDir, newPkgName, newPkgPath, err := ...
          if err != nil {
          ...
          }
          Madeline Kalil

          I think we still need them declared like this since we use newPkgDir at the end of this function to move the files to the new package directory, and only if inPackageName.

          Line 524, Patchset 20: if inPackageName {
          Robert Findley . resolved

          Can you remind me why we can't just do this in 'renamePackage'? Is it because we don't have the ability to specify a rename document change?

          I think that's it. In that case, leave an explanatory comment? The factoring sticks out as not-quite-right, and while I don't think we should work on improving it now, let's at least record why it is the way it is.

          Madeline Kalil

          I agree it's a little clunky - renamePackage calculates only text edits in individual files, which then need to be sorted (L481) and converted to doc changes, and then finally we add the DocumentChangeRename edit. Added a comment.

          Line 525, Patchset 20: oldDir := f.URI().DirPath()
          Robert Findley . resolved

          Nit: call this 'oldPkgDir' for symmetry, or just inline below.

          Madeline Kalil

          Done

          Line 526, Patchset 17: changes = append(changes,
          protocol.DocumentChangeRename(
          protocol.URIFromPath(oldDir),
          protocol.URIFromPath(newPkgDir)))
          Robert Findley . unresolved

          So, this actually looks wrong.

          What if we're renaming a/b, and there's an a/b/c. Doesn't this implicitly move the 'c' directory as well?

          What if we're renaming a/b to a, and there are no `go` files in `a`. Can't we support that, by just moving the files?

          I think we need to...
          1. Check that there are no go files in newPkgDir (or newPkgDir is missing).
          2. Create newPkgDir if it doesn't exist.
          3. Move each file from oldPkgDir.
          4. Delete oldPkgDir if it's now empty.

          Madeline Kalil

          Yeah thinking about it more, it doesn't make sense that nested packages would be also moved. But there is a test TestRenamePackage_NestedModule that asserts that renaming package "foo" in foo/ to "foox" will result in renaming the file "foo/bar/bar.go" which is in package "bar" to "foox/bar/bar.go". Should we change this test expectation?

          Also, not sure about the best way to implement (4) so I'll ask you tomorrow.

          Line 923, Patchset 20:// renamePackage renames package declarations, imports, and go.mod files.
          Robert Findley . resolved

          Add:
          ```
          //
          // f is the file originating the rename, and therefore f.URI().Dir() is the
          // package directory. newName, newPath, and newDir describe the renaming.
          ```

          Madeline Kalil

          Done

          Line 924, Patchset 20:func renamePackage(ctx context.Context, s *cache.Snapshot, f file.Handle, newName PackageName, newPath PackagePath, newPkgDir string) (map[protocol.DocumentURI][]diff.Edit, error) {
          Robert Findley . resolved

          We don't say 'newPkgPath', so this should just be 'newDir'. The pkg is implied.

          Madeline Kalil

          Done

          Line 926, Patchset 20: renamingEdits, err := updatePackageDeclsAndImports(ctx, s, f, newName, newPath)
          Robert Findley . resolved

          Nit: 'renamingEdits' is unnecessarily long, since the function name is 'renamePackage'. How about just 'edits'?

          Madeline Kalil

          Done

          Line 931, Patchset 20: renamingEdits, err = updateModFiles(ctx, s, f.URI().DirPath(), newPkgDir, renamingEdits)
          Robert Findley . resolved

          No need to return renamingEdits here.

          How about just passing in the edits map to both updatePackageDeclsAndImports, and to updateModFiles?

          Madeline Kalil

          Done

          Line 1148, Patchset 20: moveToInternal := snapshot.Options().PackageMove && (strings.Contains(string(newName), "internal") || strings.Contains(string(newPath), "internal"))
          Robert Findley . unresolved

          This doesn't look quite right.

          1. validating whether a renaming is valid shouldn't depend on the PackageMove option: at this point, we've already handled PackageMove, and whether the move is valid is independent of how we got to it.
          2. The condition on importers should be a function of dep path and import path. We shouldn't allow the move if the new import is invalid. See `metadata.IsValidImport`.

          Madeline Kalil

          metadata.IsValidImport has several TODOs saying that the functionality is incorrect, so maybe I should fix that in a separate CL.
          I've handled the case where we are moving from a non-internal to an internal package so that we detect illegal internal imports.

          File gopls/internal/golang/rename_check.go
          Line 926, Patchset 17:func checkPackageRename(opts *settings.Options, curPkg *cache.Package, f file.Handle, newName string) (newPkgDir string, newPkgName PackageName, newPkgPath PackagePath, err error) {
          Robert Findley . unresolved

          We can only perform the package rename if curPkg holds ALL Go files in its directory. If there are any other Go files present, the rename may result in a broken build.

          We can do better by trying to find builds that cover all go files, but for now let's just be conservative.

          Madeline Kalil

          Sorry I'm not sure if I understand - are you describing a scenario where we have files for package a located in "root/a" and files for package a also located in "root/b"?

          Line 946, Patchset 20: // Directory already exists, return an error.
          Robert Findley . resolved

          "Directory or file already exists at this path; return an error."?

          Madeline Kalil

          Right thanks, it could conflict with an existing file too

          Line 952, Patchset 17: if !strings.Contains(newName, string(os.PathSeparator)) {
          Robert Findley . unresolved

          I don't understand this: doesn't PrepareRename prompt with the package path?

          If newName is not an identifier, is it a directory or package path? I thought the latter.

          I think the logic here needs to check:
          1. That modPath+"/" is a prefix of the new path.
          2. That filepath.Join(modDir, filepath.FromSlash(strings.TrimPrefix(newName, modPath+"/"))) is a valid path.
          3. That the new path creates a new package.

          Madeline Kalil

          I should have used "/" instead of os.PathSeparator since forward slash is always used in package paths. But anyways, this check is redundant. It was meant to catch cases like "$$$" which are not valid package identifiers but do pass the fs.ValidPath check. This will actually be rejected when we check case (2) a few lines below.

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Robert Findley
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
          Gerrit-Change-Number: 712160
          Gerrit-PatchSet: 21
          Gerrit-Owner: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Robert Findley <rfin...@google.com>
          Gerrit-Attention: Robert Findley <rfin...@google.com>
          Gerrit-Comment-Date: Tue, 04 Nov 2025 22:19:59 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: No
          unsatisfied_requirement
          open
          diffy

          Madeline Kalil (Gerrit)

          unread,
          Nov 5, 2025, 10:03:31 AM (7 days ago) Nov 5
          to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
          Attention needed from Robert Findley

          Madeline Kalil uploaded new patchset

          Madeline Kalil uploaded patch set #22 to this change.
          Open in Gerrit

          Related details

          Attention is currently required from:
          • Robert Findley
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: newpatchset
          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
          Gerrit-Change-Number: 712160
          Gerrit-PatchSet: 22
          unsatisfied_requirement
          open
          diffy

          Madeline Kalil (Gerrit)

          unread,
          Nov 5, 2025, 10:08:26 AM (7 days ago) Nov 5
          to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
          Attention needed from Robert Findley

          Madeline Kalil voted and added 2 comments

          Votes added by Madeline Kalil

          Commit-Queue+1

          2 comments

          Patchset-level comments
          File-level comment, Patchset 16:
          Robert Findley . resolved

          The test failures look related.

          Madeline Kalil

          Yeah, windows :( trying to figure it out
          Also still need to add tests for import cycles and nested directories that don't exist

          Madeline Kalil

          Turns out you don't need to explicitly create directories that don't exist, you can just use RenameFile in a DocumentChange and it will create the directories. Still need to add a test for an import cycle

          Madeline Kalil

          Actually, I don't believe it is possible to create an import cycle via a package move alone because we don't allow merging packages.

          File gopls/internal/golang/rename_check.go
          Line 952, Patchset 17: if !strings.Contains(newName, string(os.PathSeparator)) {
          Robert Findley . resolved

          I don't understand this: doesn't PrepareRename prompt with the package path?

          If newName is not an identifier, is it a directory or package path? I thought the latter.

          I think the logic here needs to check:
          1. That modPath+"/" is a prefix of the new path.
          2. That filepath.Join(modDir, filepath.FromSlash(strings.TrimPrefix(newName, modPath+"/"))) is a valid path.
          3. That the new path creates a new package.

          Madeline Kalil

          I should have used "/" instead of os.PathSeparator since forward slash is always used in package paths. But anyways, this check is redundant. It was meant to catch cases like "$$$" which are not valid package identifiers but do pass the fs.ValidPath check. This will actually be rejected when we check case (2) a few lines below.

          Madeline Kalil

          Done

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Robert Findley
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
          Gerrit-Change-Number: 712160
          Gerrit-PatchSet: 22
          Gerrit-Owner: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Robert Findley <rfin...@google.com>
          Gerrit-Attention: Robert Findley <rfin...@google.com>
          Gerrit-Comment-Date: Wed, 05 Nov 2025 15:08:22 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: Yes
          unsatisfied_requirement
          open
          diffy

          Madeline Kalil (Gerrit)

          unread,
          Nov 5, 2025, 11:14:30 AM (7 days ago) Nov 5
          to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
          Attention needed from Madeline Kalil and Robert Findley

          Madeline Kalil uploaded new patchset

          Madeline Kalil uploaded patch set #23 to this change.
          Following approvals got outdated and were removed:
          • TryBots-Pass: LUCI-TryBot-Result-1 by Go LUCI
          Open in Gerrit

          Related details

          Attention is currently required from:
          • Madeline Kalil
          • Robert Findley
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: newpatchset
          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
          Gerrit-Change-Number: 712160
          Gerrit-PatchSet: 23
          Gerrit-Owner: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Robert Findley <rfin...@google.com>
          unsatisfied_requirement
          open
          diffy

          Madeline Kalil (Gerrit)

          unread,
          Nov 5, 2025, 11:14:44 AM (7 days ago) Nov 5
          to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
          Attention needed from Robert Findley

          Madeline Kalil added 1 comment

          File gopls/internal/golang/rename.go
          Line 526, Patchset 17: changes = append(changes,
          protocol.DocumentChangeRename(
          protocol.URIFromPath(oldDir),
          protocol.URIFromPath(newPkgDir)))
          Robert Findley . unresolved

          So, this actually looks wrong.

          What if we're renaming a/b, and there's an a/b/c. Doesn't this implicitly move the 'c' directory as well?

          What if we're renaming a/b to a, and there are no `go` files in `a`. Can't we support that, by just moving the files?

          I think we need to...
          1. Check that there are no go files in newPkgDir (or newPkgDir is missing).
          2. Create newPkgDir if it doesn't exist.
          3. Move each file from oldPkgDir.
          4. Delete oldPkgDir if it's now empty.

          Madeline Kalil

          Yeah thinking about it more, it doesn't make sense that nested packages would be also moved. But there is a test TestRenamePackage_NestedModule that asserts that renaming package "foo" in foo/ to "foox" will result in renaming the file "foo/bar/bar.go" which is in package "bar" to "foox/bar/bar.go". Should we change this test expectation?

          Also, not sure about the best way to implement (4) so I'll ask you tomorrow.

          Madeline Kalil

          For (4), looks like we can use a DeleteFile operation to remove the old directory, because it will only delete the directory if it is empty (https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#deleteFileOptions). I also updated the marker test's apply edit functionality to match what LSP says.

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Robert Findley
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
          Gerrit-Change-Number: 712160
          Gerrit-PatchSet: 23
          Gerrit-Owner: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Robert Findley <rfin...@google.com>
          Gerrit-Attention: Robert Findley <rfin...@google.com>
          Gerrit-Comment-Date: Wed, 05 Nov 2025 16:14:41 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: No
          unsatisfied_requirement
          open
          diffy

          Madeline Kalil (Gerrit)

          unread,
          Nov 5, 2025, 4:58:28 PM (7 days ago) Nov 5
          to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
          Attention needed from Robert Findley

          Madeline Kalil uploaded new patchset

          Madeline Kalil uploaded patch set #24 to this change.
          Open in Gerrit

          Related details

          Attention is currently required from:
          • Robert Findley
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: newpatchset
          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
          Gerrit-Change-Number: 712160
          Gerrit-PatchSet: 24
          unsatisfied_requirement
          open
          diffy

          Robert Findley (Gerrit)

          unread,
          Nov 10, 2025, 11:17:26 AM (2 days ago) Nov 10
          to Madeline Kalil, goph...@pubsubhelper.golang.org, Go LUCI, golang-co...@googlegroups.com
          Attention needed from Madeline Kalil

          Robert Findley added 4 comments

          File gopls/internal/golang/rename.go
          Line 457, Patchset 20: var (
          newPkgName PackageName
          newPkgPath PackagePath
          err error
          )
          if newPkgDir, newPkgName, newPkgPath, err = checkPackageRename(snapshot.Options(), pkg, f, newName); err != nil {
          Robert Findley . resolved

          Looks like these can now be declared with a short variable declaration.

          newPkgDir, newPkgName, newPkgPath, err := ...
          if err != nil {
          ...
          }
          Madeline Kalil

          I think we still need them declared like this since we use newPkgDir at the end of this function to move the files to the new package directory, and only if inPackageName.

          Robert Findley

          Oh! Yep, I just missed that (I can't count...)

          Line 526, Patchset 17: changes = append(changes,
          protocol.DocumentChangeRename(
          protocol.URIFromPath(oldDir),
          protocol.URIFromPath(newPkgDir)))
          Robert Findley . unresolved

          So, this actually looks wrong.

          What if we're renaming a/b, and there's an a/b/c. Doesn't this implicitly move the 'c' directory as well?

          What if we're renaming a/b to a, and there are no `go` files in `a`. Can't we support that, by just moving the files?

          I think we need to...
          1. Check that there are no go files in newPkgDir (or newPkgDir is missing).
          2. Create newPkgDir if it doesn't exist.
          3. Move each file from oldPkgDir.
          4. Delete oldPkgDir if it's now empty.

          Madeline Kalil

          Yeah thinking about it more, it doesn't make sense that nested packages would be also moved. But there is a test TestRenamePackage_NestedModule that asserts that renaming package "foo" in foo/ to "foox" will result in renaming the file "foo/bar/bar.go" which is in package "bar" to "foox/bar/bar.go". Should we change this test expectation?

          Also, not sure about the best way to implement (4) so I'll ask you tomorrow.

          Madeline Kalil

          For (4), looks like we can use a DeleteFile operation to remove the old directory, because it will only delete the directory if it is empty (https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#deleteFileOptions). I also updated the marker test's apply edit functionality to match what LSP says.

          Robert Findley

          Sorry for the churn: chatted about this with Alan and he argued that *either one* of these behaviors is viable: you may want to move subpackages, you may not.

          A great opportunity for dialog support. In the meantime, want to paraneterize this with a (const) bool?

          File gopls/internal/golang/rename_check.go
          Line 926, Patchset 17:func checkPackageRename(opts *settings.Options, curPkg *cache.Package, f file.Handle, newName string) (newPkgDir string, newPkgName PackageName, newPkgPath PackagePath, err error) {
          Robert Findley . unresolved

          We can only perform the package rename if curPkg holds ALL Go files in its directory. If there are any other Go files present, the rename may result in a broken build.

          We can do better by trying to find builds that cover all go files, but for now let's just be conservative.

          Madeline Kalil

          Sorry I'm not sure if I understand - are you describing a scenario where we have files for package a located in "root/a" and files for package a also located in "root/b"?

          Robert Findley

          No, what I mean is that there may be a foo_windows.go in the directory, but that file is not present in the curPkg set of compiled go files (because our build is, say, linux). Therefore, the calculations of callers will exclude the windows file, and we'll get a broken build on windows after moving files.

          File gopls/internal/test/marker/marker_test.go
          Line 2154, Patchset 24 (Latest): // Directory is not empty. If "Recursive" is true, we delete
          // every file in the folder. Otherwise, we continue without
          // deleting the directory.
          Robert Findley . resolved

          Nice! I didn't even know about this option.

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Madeline Kalil
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
          Gerrit-Change-Number: 712160
          Gerrit-PatchSet: 24
          Gerrit-Owner: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Robert Findley <rfin...@google.com>
          Gerrit-Attention: Madeline Kalil <mka...@google.com>
          Gerrit-Comment-Date: Mon, 10 Nov 2025 16:17:22 +0000
          unsatisfied_requirement
          open
          diffy

          Madeline Kalil (Gerrit)

          unread,
          Nov 10, 2025, 2:36:36 PM (2 days ago) Nov 10
          to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
          Attention needed from Madeline Kalil

          Madeline Kalil uploaded new patchset

          Madeline Kalil uploaded patch set #25 to this change.
          Open in Gerrit

          Related details

          Attention is currently required from:
          • Madeline Kalil
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: newpatchset
          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
          Gerrit-Change-Number: 712160
          Gerrit-PatchSet: 25
          unsatisfied_requirement
          open
          diffy

          Madeline Kalil (Gerrit)

          unread,
          Nov 10, 2025, 2:39:14 PM (2 days ago) Nov 10
          to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
          Attention needed from Madeline Kalil

          Madeline Kalil uploaded new patchset

          Madeline Kalil uploaded patch set #26 to this change.
          Open in Gerrit

          Related details

          Attention is currently required from:
          • Madeline Kalil
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: newpatchset
          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
          Gerrit-Change-Number: 712160
          Gerrit-PatchSet: 26
          unsatisfied_requirement
          open
          diffy

          Madeline Kalil (Gerrit)

          unread,
          Nov 10, 2025, 2:40:59 PM (2 days ago) Nov 10
          to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
          Attention needed from Robert Findley

          Madeline Kalil voted and added 2 comments

          Votes added by Madeline Kalil

          Commit-Queue+1

          2 comments

          File gopls/internal/golang/rename.go
          Line 526, Patchset 17: changes = append(changes,
          protocol.DocumentChangeRename(
          protocol.URIFromPath(oldDir),
          protocol.URIFromPath(newPkgDir)))
          Robert Findley . resolved

          So, this actually looks wrong.

          What if we're renaming a/b, and there's an a/b/c. Doesn't this implicitly move the 'c' directory as well?

          What if we're renaming a/b to a, and there are no `go` files in `a`. Can't we support that, by just moving the files?

          I think we need to...
          1. Check that there are no go files in newPkgDir (or newPkgDir is missing).
          2. Create newPkgDir if it doesn't exist.
          3. Move each file from oldPkgDir.
          4. Delete oldPkgDir if it's now empty.

          Madeline Kalil

          Yeah thinking about it more, it doesn't make sense that nested packages would be also moved. But there is a test TestRenamePackage_NestedModule that asserts that renaming package "foo" in foo/ to "foox" will result in renaming the file "foo/bar/bar.go" which is in package "bar" to "foox/bar/bar.go". Should we change this test expectation?

          Also, not sure about the best way to implement (4) so I'll ask you tomorrow.

          Madeline Kalil

          For (4), looks like we can use a DeleteFile operation to remove the old directory, because it will only delete the directory if it is empty (https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#deleteFileOptions). I also updated the marker test's apply edit functionality to match what LSP says.

          Robert Findley

          Sorry for the churn: chatted about this with Alan and he argued that *either one* of these behaviors is viable: you may want to move subpackages, you may not.

          A great opportunity for dialog support. In the meantime, want to paraneterize this with a (const) bool?

          Madeline Kalil

          Done

          Line 1148, Patchset 20: moveToInternal := snapshot.Options().PackageMove && (strings.Contains(string(newName), "internal") || strings.Contains(string(newPath), "internal"))
          Robert Findley . resolved

          This doesn't look quite right.

          1. validating whether a renaming is valid shouldn't depend on the PackageMove option: at this point, we've already handled PackageMove, and whether the move is valid is independent of how we got to it.
          2. The condition on importers should be a function of dep path and import path. We shouldn't allow the move if the new import is invalid. See `metadata.IsValidImport`.

          Madeline Kalil

          metadata.IsValidImport has several TODOs saying that the functionality is incorrect, so maybe I should fix that in a separate CL.
          I've handled the case where we are moving from a non-internal to an internal package so that we detect illegal internal imports.

          Madeline Kalil

          Acknowledged

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Robert Findley
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
          Gerrit-Change-Number: 712160
          Gerrit-PatchSet: 26
          Gerrit-Owner: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
          Gerrit-Reviewer: Robert Findley <rfin...@google.com>
          Gerrit-Attention: Robert Findley <rfin...@google.com>
          Gerrit-Comment-Date: Mon, 10 Nov 2025 19:40:56 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: Yes
          unsatisfied_requirement
          open
          diffy

          Madeline Kalil (Gerrit)

          unread,
          Nov 11, 2025, 10:27:36 AM (yesterday) Nov 11
          to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
          Attention needed from Robert Findley

          Madeline Kalil uploaded new patchset

          Madeline Kalil uploaded patch set #27 to this change.
          Following approvals got outdated and were removed:
          • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
          Open in Gerrit

          Related details

          Attention is currently required from:
          • Robert Findley
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: newpatchset
          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
          Gerrit-Change-Number: 712160
          Gerrit-PatchSet: 27
          unsatisfied_requirement
          open
          diffy

          Madeline Kalil (Gerrit)

          unread,
          Nov 11, 2025, 10:27:55 AM (yesterday) Nov 11
          to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
          Attention needed from Robert Findley

          Madeline Kalil voted and added 1 comment

          Votes added by Madeline Kalil

          Commit-Queue+1

          1 comment

          File gopls/internal/golang/rename_check.go
          Line 926, Patchset 17:func checkPackageRename(opts *settings.Options, curPkg *cache.Package, f file.Handle, newName string) (newPkgDir string, newPkgName PackageName, newPkgPath PackagePath, err error) {
          Robert Findley . resolved

          We can only perform the package rename if curPkg holds ALL Go files in its directory. If there are any other Go files present, the rename may result in a broken build.

          We can do better by trying to find builds that cover all go files, but for now let's just be conservative.

          Madeline Kalil

          Sorry I'm not sure if I understand - are you describing a scenario where we have files for package a located in "root/a" and files for package a also located in "root/b"?

          Robert Findley

          No, what I mean is that there may be a foo_windows.go in the directory, but that file is not present in the curPkg set of compiled go files (because our build is, say, linux). Therefore, the calculations of callers will exclude the windows file, and we'll get a broken build on windows after moving files.

          Madeline Kalil

          Got it, thanks. Done

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Robert Findley
          Submit Requirements:
            • requirement is not satisfiedCode-Review
            • requirement satisfiedNo-Unresolved-Comments
            • requirement is not satisfiedReview-Enforcement
            • requirement is not satisfiedTryBots-Pass
            Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
            Gerrit-MessageType: comment
            Gerrit-Project: tools
            Gerrit-Branch: master
            Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
            Gerrit-Change-Number: 712160
            Gerrit-PatchSet: 27
            Gerrit-Owner: Madeline Kalil <mka...@google.com>
            Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
            Gerrit-Reviewer: Robert Findley <rfin...@google.com>
            Gerrit-Attention: Robert Findley <rfin...@google.com>
            Gerrit-Comment-Date: Tue, 11 Nov 2025 15:27:52 +0000
            unsatisfied_requirement
            satisfied_requirement
            open
            diffy

            Robert Findley (Gerrit)

            unread,
            Nov 11, 2025, 10:28:58 AM (yesterday) Nov 11
            to Madeline Kalil, goph...@pubsubhelper.golang.org, Go LUCI, golang-co...@googlegroups.com
            Attention needed from Madeline Kalil

            Robert Findley added 10 comments

            File gopls/internal/golang/rename.go
            Line 564, Patchset 26: if !(strings.HasPrefix(newPkgDir, oldPkgDir)) {
            Robert Findley . unresolved

            Unnecessary parens.

            Line 564, Patchset 26: if !(strings.HasPrefix(newPkgDir, oldPkgDir)) {
            Robert Findley . unresolved

            Here also, don't use HasPrefix to check lexical containment of directories.
            You may want to use the gopls/internal/util/pathutil.InDir helper.

            Line 1128, Patchset 26: if !(string(mp.PkgPath)+"/" == string(oldPkgPath)+"/") {
            Robert Findley . unresolved

            `if mp.PkgPath != oldPkgPath`

            But also: what about test variants? (the x_test package)? Do we have a test for that?

            Line 1235, Patchset 26: if !(strings.Contains(string(rdep.PkgPath), "internal")) && strings.Contains(string(newPath), "internal") {
            // We do not allow moving packages across the module boundary, so mp.Module.Dir is the module directory
            // for the new package path.
            if mp.Module.Dir != rdep.Module.Dir {
            return fmt.Errorf("invalid: package move would result in illegal internal import")
            }
            }
            Robert Findley . unresolved

            Can you explain this condition? I don't think this is accurate to the rules for internal imports, and internal doesn't really have anything to do with module dirs.
            Also, strings.Contains is not correct: "myinternal" contains the string "internal", but is not an internal directory.

            a/b/c can import from a/internal or b/internal, but not a/d/internal.
            https://go.dev/doc/go1.4#internalpackages

            We discuss metadata.IsValidImport: that function has a couple bugs, but we should still use it (and then fix it in a follow-up). The bugs are historical oversights; I noted them as we refactored.

            File gopls/internal/golang/rename_check.go
            Line 929, Patchset 26: return f.URI().DirPath(), PackageName(path.Base(newName)), curPkg.Metadata().PkgPath, nil
            Robert Findley . unresolved

            This isn't correct in the case where curPkg.Metadata().Name does not match the directory base name. Just return curPkg.Metadata().Name.

            And I hope that this doesn't result in any edits! Is that guaranteed to be the case?

            Line 942, Patchset 26: newPkgDir = filepath.Join(filepath.Dir(f.URI().DirPath()), newName)
            Robert Findley . unresolved

            I recommend factoring out `oldDir`.

            Line 943, Patchset 26: newPkgName = PackageName(newName)
            Robert Findley . unresolved

            Nit, move this below the Stat, closer to its usage.

            Line 953, Patchset 26: isValidPkgPath := fs.ValidPath(newName)
            Robert Findley . unresolved

            I don't think this is quite right. fs.ValidPath is about file paths. Should you want until below, when you construct the newPkgDir, and pass that to ValidPath?

            Line 962, Patchset 26: if !(strings.HasPrefix(newName, curModPath)) {
            Robert Findley . unresolved

            1. Unnecessary parens.
            2. This isn't right: need to check newName+"/" and curModPath+"/" to avoid the case of curModPath = module.com/mymodule and newName = module.com/mymodulewithnoslash

            Line 969, Patchset 26: newPkgDir = filepath.Join(modDir, newPathAfterMod)
            Robert Findley . unresolved

            This looks wrong. You're joining a directory and an import path segment. This logic should probably operate entirely on dirs.

            Open in Gerrit

            Related details

            Attention is currently required from:
            • Madeline Kalil
            Submit Requirements:
              • requirement is not satisfiedCode-Review
              • requirement is not satisfiedNo-Unresolved-Comments
              • requirement is not satisfiedReview-Enforcement
              • requirement is not satisfiedTryBots-Pass
              Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
              Gerrit-MessageType: comment
              Gerrit-Project: tools
              Gerrit-Branch: master
              Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
              Gerrit-Change-Number: 712160
              Gerrit-PatchSet: 26
              Gerrit-Owner: Madeline Kalil <mka...@google.com>
              Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
              Gerrit-Reviewer: Robert Findley <rfin...@google.com>
              Gerrit-Attention: Madeline Kalil <mka...@google.com>
              Gerrit-Comment-Date: Tue, 11 Nov 2025 15:28:53 +0000
              Gerrit-HasComments: Yes
              Gerrit-Has-Labels: No
              unsatisfied_requirement
              open
              diffy

              Madeline Kalil (Gerrit)

              unread,
              Nov 11, 2025, 2:44:01 PM (24 hours ago) Nov 11
              to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
              Attention needed from Madeline Kalil

              Madeline Kalil uploaded new patchset

              Madeline Kalil uploaded patch set #28 to this change.
              Following approvals got outdated and were removed:
              • TryBots-Pass: LUCI-TryBot-Result-1 by Go LUCI
              Open in Gerrit

              Related details

              Attention is currently required from:
              • Madeline Kalil
              Submit Requirements:
              • requirement is not satisfiedCode-Review
              • requirement is not satisfiedNo-Unresolved-Comments
              • requirement is not satisfiedReview-Enforcement
              • requirement is not satisfiedTryBots-Pass
              Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
              Gerrit-MessageType: newpatchset
              Gerrit-Project: tools
              Gerrit-Branch: master
              Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
              Gerrit-Change-Number: 712160
              Gerrit-PatchSet: 28
              unsatisfied_requirement
              open
              diffy

              Madeline Kalil (Gerrit)

              unread,
              Nov 11, 2025, 2:47:37 PM (24 hours ago) Nov 11
              to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
              Attention needed from Madeline Kalil

              Madeline Kalil uploaded new patchset

              Madeline Kalil uploaded patch set #29 to this change.
              Open in Gerrit

              Related details

              Attention is currently required from:
              • Madeline Kalil
              Submit Requirements:
              • requirement is not satisfiedCode-Review
              • requirement is not satisfiedNo-Unresolved-Comments
              • requirement is not satisfiedReview-Enforcement
              • requirement is not satisfiedTryBots-Pass
              Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
              Gerrit-MessageType: newpatchset
              Gerrit-Project: tools
              Gerrit-Branch: master
              Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
              Gerrit-Change-Number: 712160
              Gerrit-PatchSet: 29
              unsatisfied_requirement
              open
              diffy

              Madeline Kalil (Gerrit)

              unread,
              Nov 11, 2025, 2:48:02 PM (24 hours ago) Nov 11
              to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
              Attention needed from Robert Findley

              Madeline Kalil voted and added 10 comments

              Votes added by Madeline Kalil

              Commit-Queue+1

              10 comments

              File gopls/internal/golang/rename.go
              Line 564, Patchset 26: if !(strings.HasPrefix(newPkgDir, oldPkgDir)) {
              Robert Findley . resolved

              Unnecessary parens.

              Madeline Kalil

              Done

              Line 564, Patchset 26: if !(strings.HasPrefix(newPkgDir, oldPkgDir)) {
              Robert Findley . resolved

              Here also, don't use HasPrefix to check lexical containment of directories.
              You may want to use the gopls/internal/util/pathutil.InDir helper.

              Madeline Kalil

              Done

              Line 1128, Patchset 26: if !(string(mp.PkgPath)+"/" == string(oldPkgPath)+"/") {
              Robert Findley . resolved

              `if mp.PkgPath != oldPkgPath`

              But also: what about test variants? (the x_test package)? Do we have a test for that?

              Madeline Kalil

              The renaming of package clauses in the test variants is handles above these lines around L1113. The renaming of the files/directories themselves is handled in the outer Rename function as we pass the test package back and move those files individually (L545). There's a test in packagedecl and the TestRenamePackage_Tests and TestRenamePackage_TestVariant in rename_test.go to verify the behavior.

              Line 1235, Patchset 26: if !(strings.Contains(string(rdep.PkgPath), "internal")) && strings.Contains(string(newPath), "internal") {
              // We do not allow moving packages across the module boundary, so mp.Module.Dir is the module directory
              // for the new package path.
              if mp.Module.Dir != rdep.Module.Dir {
              return fmt.Errorf("invalid: package move would result in illegal internal import")
              }
              }
              Robert Findley . resolved

              Can you explain this condition? I don't think this is accurate to the rules for internal imports, and internal doesn't really have anything to do with module dirs.
              Also, strings.Contains is not correct: "myinternal" contains the string "internal", but is not an internal directory.

              a/b/c can import from a/internal or b/internal, but not a/d/internal.
              https://go.dev/doc/go1.4#internalpackages

              We discuss metadata.IsValidImport: that function has a couple bugs, but we should still use it (and then fix it in a follow-up). The bugs are historical oversights; I noted them as we refactored.

              Madeline Kalil

              Oops yeah, makes sense that we need to check for "/internal/" not just "internal".
              My understanding is that if you have some package in a and some package in b/internal, a can only import b/internal if they're in the same module. metadata.IsValidImport verifies the same thing by checking the package path though, so this check isn't necessary anymore

              File gopls/internal/golang/rename_check.go
              Line 929, Patchset 26: return f.URI().DirPath(), PackageName(path.Base(newName)), curPkg.Metadata().PkgPath, nil
              Robert Findley . resolved

              This isn't correct in the case where curPkg.Metadata().Name does not match the directory base name. Just return curPkg.Metadata().Name.

              And I hope that this doesn't result in any edits! Is that guaranteed to be the case?

              Madeline Kalil

              Yep I have a test case in packagedecl.txt for when the specified package path is the same.

              Line 942, Patchset 26: newPkgDir = filepath.Join(filepath.Dir(f.URI().DirPath()), newName)
              Robert Findley . resolved

              I recommend factoring out `oldDir`.

              Madeline Kalil

              Done

              Line 943, Patchset 26: newPkgName = PackageName(newName)
              Robert Findley . resolved

              Nit, move this below the Stat, closer to its usage.

              Madeline Kalil

              Done

              Line 953, Patchset 26: isValidPkgPath := fs.ValidPath(newName)
              Robert Findley . resolved

              I don't think this is quite right. fs.ValidPath is about file paths. Should you want until below, when you construct the newPkgDir, and pass that to ValidPath?

              Madeline Kalil

              This is mainly checking if the path is a valid utf8 string, but it does make more sense to check the directory (file path) although we have to remove the slash prefix before passing it to fs.ValidPath

              Line 962, Patchset 26: if !(strings.HasPrefix(newName, curModPath)) {
              Robert Findley . resolved

              1. Unnecessary parens.
              2. This isn't right: need to check newName+"/" and curModPath+"/" to avoid the case of curModPath = module.com/mymodule and newName = module.com/mymodulewithnoslash

              Madeline Kalil

              Thanks! Added a test as well

              Line 969, Patchset 26: newPkgDir = filepath.Join(modDir, newPathAfterMod)
              Robert Findley . unresolved

              This looks wrong. You're joining a directory and an import path segment. This logic should probably operate entirely on dirs.

              Madeline Kalil

              Sorry I'm not sure how else to piece together the new package directory.
              Since the module is not allowed to change, the new package directory should be the module directory joined with the part of the package path that comes after the module name.

              Open in Gerrit

              Related details

              Attention is currently required from:
              • Robert Findley
              Submit Requirements:
              • requirement is not satisfiedCode-Review
              • requirement is not satisfiedNo-Unresolved-Comments
              • requirement is not satisfiedReview-Enforcement
              • requirement is not satisfiedTryBots-Pass
              Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
              Gerrit-MessageType: comment
              Gerrit-Project: tools
              Gerrit-Branch: master
              Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
              Gerrit-Change-Number: 712160
              Gerrit-PatchSet: 29
              Gerrit-Owner: Madeline Kalil <mka...@google.com>
              Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
              Gerrit-Reviewer: Robert Findley <rfin...@google.com>
              Gerrit-Attention: Robert Findley <rfin...@google.com>
              Gerrit-Comment-Date: Tue, 11 Nov 2025 19:47:59 +0000
              Gerrit-HasComments: Yes
              Gerrit-Has-Labels: Yes
              Comment-In-Reply-To: Robert Findley <rfin...@google.com>
              unsatisfied_requirement
              open
              diffy

              Madeline Kalil (Gerrit)

              unread,
              Nov 11, 2025, 3:14:32 PM (23 hours ago) Nov 11
              to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
              Attention needed from Robert Findley

              Madeline Kalil voted and added 1 comment

              Votes added by Madeline Kalil

              Commit-Queue+1

              1 comment

              File gopls/internal/golang/rename_check.go
              Line 1001, Patchset 29 (Latest):func isAllSameBuild(pkg *cache.Package, dir string) (bool, error) {
              Madeline Kalil . unresolved

              I don't think this is correct, working on it

              Open in Gerrit

              Related details

              Attention is currently required from:
              • Robert Findley
              Submit Requirements:
                • requirement is not satisfiedCode-Review
                • requirement is not satisfiedNo-Unresolved-Comments
                • requirement is not satisfiedReview-Enforcement
                • requirement satisfiedTryBots-Pass
                Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                Gerrit-MessageType: comment
                Gerrit-Project: tools
                Gerrit-Branch: master
                Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
                Gerrit-Change-Number: 712160
                Gerrit-PatchSet: 29
                Gerrit-Owner: Madeline Kalil <mka...@google.com>
                Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
                Gerrit-Reviewer: Robert Findley <rfin...@google.com>
                Gerrit-Attention: Robert Findley <rfin...@google.com>
                Gerrit-Comment-Date: Tue, 11 Nov 2025 20:14:27 +0000
                Gerrit-HasComments: Yes
                Gerrit-Has-Labels: Yes
                unsatisfied_requirement
                satisfied_requirement
                open
                diffy

                Madeline Kalil (Gerrit)

                unread,
                Nov 11, 2025, 4:49:12 PM (22 hours ago) Nov 11
                to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
                Attention needed from Robert Findley

                Madeline Kalil uploaded new patchset

                Madeline Kalil uploaded patch set #30 to this change.
                Following approvals got outdated and were removed:
                • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
                Open in Gerrit

                Related details

                Attention is currently required from:
                • Robert Findley
                Submit Requirements:
                  • requirement is not satisfiedCode-Review
                  • requirement is not satisfiedNo-Unresolved-Comments
                  • requirement is not satisfiedReview-Enforcement
                  • requirement is not satisfiedTryBots-Pass
                  Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                  Gerrit-MessageType: newpatchset
                  Gerrit-Project: tools
                  Gerrit-Branch: master
                  Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
                  Gerrit-Change-Number: 712160
                  Gerrit-PatchSet: 30
                  unsatisfied_requirement
                  open
                  diffy

                  Madeline Kalil (Gerrit)

                  unread,
                  10:48 AM (4 hours ago) 10:48 AM
                  to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
                  Attention needed from Robert Findley

                  Madeline Kalil uploaded new patchset

                  Madeline Kalil uploaded patch set #31 to this change.
                  Open in Gerrit

                  Related details

                  Attention is currently required from:
                  • Robert Findley
                  Submit Requirements:
                  • requirement is not satisfiedCode-Review
                  • requirement is not satisfiedNo-Unresolved-Comments
                  • requirement is not satisfiedReview-Enforcement
                  • requirement is not satisfiedTryBots-Pass
                  Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                  Gerrit-MessageType: newpatchset
                  Gerrit-Project: tools
                  Gerrit-Branch: master
                  Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
                  Gerrit-Change-Number: 712160
                  Gerrit-PatchSet: 31
                  unsatisfied_requirement
                  open
                  diffy

                  Madeline Kalil (Gerrit)

                  unread,
                  10:48 AM (4 hours ago) 10:48 AM
                  to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
                  Attention needed from Robert Findley

                  Madeline Kalil voted and added 1 comment

                  Votes added by Madeline Kalil

                  Commit-Queue+1

                  1 comment

                  File gopls/internal/golang/rename_check.go
                  Line 1001, Patchset 29:func isAllSameBuild(pkg *cache.Package, dir string) (bool, error) {
                  Madeline Kalil . resolved

                  I don't think this is correct, working on it

                  Madeline Kalil

                  Will implement this in a follow up

                  Open in Gerrit

                  Related details

                  Attention is currently required from:
                  • Robert Findley
                  Submit Requirements:
                  • requirement is not satisfiedCode-Review
                  • requirement is not satisfiedNo-Unresolved-Comments
                  • requirement is not satisfiedReview-Enforcement
                  • requirement is not satisfiedTryBots-Pass
                  Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                  Gerrit-MessageType: comment
                  Gerrit-Project: tools
                  Gerrit-Branch: master
                  Gerrit-Change-Id: I5a38cc0a3ea4bd2ec63f5d5a28a240194feff327
                  Gerrit-Change-Number: 712160
                  Gerrit-PatchSet: 31
                  Gerrit-Owner: Madeline Kalil <mka...@google.com>
                  Gerrit-Reviewer: Madeline Kalil <mka...@google.com>
                  Gerrit-Reviewer: Robert Findley <rfin...@google.com>
                  Gerrit-Attention: Robert Findley <rfin...@google.com>
                  Gerrit-Comment-Date: Wed, 12 Nov 2025 15:48:29 +0000
                  Gerrit-HasComments: Yes
                  Gerrit-Has-Labels: Yes
                  Comment-In-Reply-To: Madeline Kalil <mka...@google.com>
                  unsatisfied_requirement
                  open
                  diffy
                  Reply all
                  Reply to author
                  Forward
                  0 new messages