gci icon indicating copy to clipboard operation
gci copied to clipboard

Support for go modules (automatically infer module path)?

Open dmke opened this issue 4 years ago • 7 comments

Hi,

at $company, we have a bunch of Go projects named gitlab.$company.com/$project.

All projects use Go modules, i.e. there's a go.mod containing module gitlab.$company.com/$project.

$ head -1 go.mod
module gitlab.$company.com/$project

However, gci doesn't seem to make use of this information, compare the output of the following gci runs (with and without -local flag):

$ gci -d -local gitlab.$company.com/$project queue/client.go
[no output]
$ gci -d queue/client.go
--- queue/client.go.orig        2021-01-25 11:25:02.582529319 +0100
+++ queue/client.go     2021-01-25 11:25:02.582529319 +0100
@@ -11,7 +11,6 @@
 
        ws "nhooyr.io/websocket"
        "nhooyr.io/websocket/wsjson"
-
        "gitlab.$company.com/$project/turn"
 )

The client.go contains this import block:

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"sync"
	"time"

	ws "nhooyr.io/websocket"
	"nhooyr.io/websocket/wsjson"

	"gitlab.$company.com/$project/turn"
)

Would this be a valid feature request? I'd like gci to lookup and use the module path when invoked without -local.

dmke avatar Jan 25 '21 10:01 dmke

It is why -local exists, automatically check to infer module path works for some cases, while if repos use custom domain rather than Github, it would do harm.

daixiang0 avatar Jan 26 '21 01:01 daixiang0

automatically check to infer module path works for some cases

Hmm... Looking at the code (ProcessFileprocessFilenewPkggetPkgType in gci.go), I don't see how that would work. Only if I provide a -local flag, getPkgType will return local: https://github.com/daixiang0/gci/blob/7eb50f3def6fe64ad9acc134b09a7d353035bc0a/pkg/gci/gci.go#L159-L171

For example, with this directory structure:

./
+-- go.mod               (module foo)
+-- internal
|   +-- service
|       +-- service.go   (package service)
+-- main.go              (package main, imports foo/internal/service)

there should be no difference between gci -local foo ./ and gci ./. Do you know what I mean?

For this to work, gci would need to find a go.mod, extract the module path from its module directive, and wire the module path down to getPkgType. I'd be OK if this only works if -local is not present on the command line.

I'll try to come up with a better example/PR later when I'm back home.

dmke avatar Jan 26 '21 11:01 dmke

I have started an example in #31. Some notes:

  • The implementation of type moduleResolver might be incomplete, I haven't written any tests (yet, I'll add some tomorrow)
    • I'm not sure if this works properly on Windows
    • it also doesn't deal with symlinks
  • The important bit is the integration in gci.processFile, where modCache.Lookup happens only if set.LocalFlag is empty.
  • ClearModCache is virtually superfluous in main.go, but I've kept it there for completeness.

dmke avatar Jan 26 '21 22:01 dmke

I also think this is confusing that gci does not find local module name automatically.

invidian avatar May 18 '21 17:05 invidian

Hello, i have the same need :)

This issue still in progress ? Or always planned ?

ymohl-cl avatar Jul 10 '23 08:07 ymohl-cl

I find myself hard-pressed to continue the work started in #31, feel free to take over :)

dmke avatar Jul 10 '23 08:07 dmke

There are some packages that might help resolving the module name:

  • https://pkg.go.dev/golang.org/x/mod/modfile
  • https://pkg.go.dev/golang.org/x/tools/go/packages

palsivertsen avatar Nov 15 '23 13:11 palsivertsen