gopatch icon indicating copy to clipboard operation
gopatch copied to clipboard

Way to handle duplicate imports of one package?

Open fasaxc opened this issue 1 year ago • 3 comments

I have some files that import the same library package multiple times with different names:

import log "github.com/sirupsen/logrus"
import "github.com/sirupsen/logrus"

I was hoping to write a gopatch to clean these up but I can't seem to do it. This patch on its own

@@
var logrus identifier
@@
-import logrus "github.com/sirupsen/logrus"
+import logrusBar "github.com/sirupsen/logrus"
-logrus
+logrusBar

only matches one of the two imports and I can't seem to control which one it matches.

fasaxc avatar Aug 04 '23 16:08 fasaxc

Hi! Thanks for reaching out. You should be able to clean the imports by using 2 patches Could you try using the below patch? The first patch gets rid of the unnamed import and the second gets rids of leftover named import instances.

# get rids of the unnamed imports 
@@
var x identifier
@@
-import "github.com/sirupsen/logrus"
+import logrusBar "github.com/sirupsen/logrus"

-logrus.x
+logrusBar.x

# gets rid of the named imports instances
@@
var log, x identifier
@@
-import log "github.com/sirupsen/logrus"
+import logrusBar "github.com/sirupsen/logrus"

-log.x
+logrusBar.x

Example: test_file : link After running gopatch: link

Please let me know, if this doesn't work, thanks!

lverma14 avatar Aug 15 '23 19:08 lverma14

@lverma14, could a single patch UX for this be turned into a feature request ticket or is a two-patch approach suitable in similar situations?

r-hang avatar Aug 22 '23 19:08 r-hang

So a detail that may not be super obvious:

@@
var logrus identifier
@@
 import logrus "github.com/sirupsen/logrus"

That matches any logrus import—named or unnamed. It records the knowledge of whether it's named or unnamed in that logrus identifier. (See also https://github.com/uber-go/gopatch/blob/main/docs/PatchesInDepth.md#best-practices-for-imports.)

Unfortunately, there's no way to control which import it matches if there are multiple. Plus there's no way to "run" the patch multiple times for each import.

There are a couple possible feature requests to consider here:

  • A means of specifying that something should only match a named import. You can say a patch only matches an unnamed import by specifying an unnamed import.
  • Run a patch repeatedly until it makes no changes. This was considered as a patch option (e.g. @@ loop in the patch open block) or as a flag gopatch --repeat. The idea is that when a patch matches and modifies a file, it should be applied there repeatedly until it no longer makes any changes. This will help for cases like the above where you want to convert all imports of something to the same standard form.

abhinav avatar Aug 22 '23 19:08 abhinav