7

I have modifed an existing github project with dozens of 3rd party imported packages but I kept the basic structure intact, which is like this:

.
├── config
│   ├── config.json
│   └── mysql.sql
├── gowebapp.go
├── LICENSE
├── README.md
├── static
├── template
│   ├── about
│   │   └── about.tmpl
│   ├── base.tmpl
└── vendor
    └── app
        ├── controller
        │   ├── about.go
        │   ├── error.go
        │   ├── index.go
        │   ├── login.go
        │   ├── notepad.go
        │   ├── register.go
        │   └── static.go
        ├── model
        │   ├── model.go
        │   ├── note.go
        │   └── user.go
        ├── route
        │   ├── middleware
        │   │   ├── acl
        │   │   │   └── acl.go
        │   │   ├── httprouterwrapper
        │   │   │   └── httprouterwrapper.go
        │   │   ├── logrequest
        │   │   │   └── logrequest.go
        │   │   └── pprofhandler
        │   │       └── pprofhandler.go
        │   └── route.go
        └── shared
            ├── database
            │   └── database.go
            ├── email
            │   └── email.go
            ├── jsonconfig
            │   └── jsonconfig.go
            ├── passhash
            │   ├── passhash.go
            │   └── passhash_test.go
            ├── recaptcha
            │   └── recaptcha.go
            ├── server
            │   └── server.go
            ├── session
            │   └── session.go
            └── view
                ├── plugin
                │   ├── noescape.go
                │   ├── prettytime.go
                │   └── taghelper.go
                └── view.go

Now I want to use go modules to make the project portable.

The main.go imports are like:

    package main

    import (
    "encoding/json"
    "log"
    "os"
    "runtime"

    "app/route"
    "app/shared/database"
    "app/shared/email"
    "app/shared/jsonconfig"
    "app/shared/recaptcha"
    "app/shared/server"
    "app/shared/session"
    "app/shared/view"
    "app/shared/view/plugin"
)

As you can see the code mostly sits in vendor/app folder.

I have added several other packages to that.

The problem is that manually adding the packages to go.mod is so tedious, and after all I may miss some imports.

So I'm wondering if there are some automatic tricks to fetch the dependencies to go.mod?

Babr
  • 1,971
  • 14
  • 33
  • 47

2 Answers2

12

Initialize the module with go mod init module-path, this will create the go.mod file. Build the project with go build. It automatically adds all dependencies to go.mod, transitively.

No manual step is involved. The go tool does everything for you. Of course you may edit the go.mod file and "fine-tune" the included versions if the automatically chosen ones do not fit your need / intent. See Version Selection how it is done by default.

Note that starting with Go 1.16, go mod tidy might be needed to add depencencies.

icza
  • 389,944
  • 63
  • 907
  • 827
  • Well I get this error: `build proj1: cannot load app/route: malformed module path "app/route": missing dot in first path element` – Babr May 19 '20 at 10:57
  • 1
    Then fix that error first. You have to use full import path, with module path prefixed. E.g. if your module has path `github.com/joe`, and your module contains `app/route` folder, you have to import that as `github.com/joe/app/route`, and not just as `app/route`. – icza May 19 '20 at 10:59
  • Actually `app/route` is located in `/home/me/go/src/proj1/vendor/app/route`. So how should I modify the import to be useful? – Babr May 19 '20 at 11:02
  • `vendor` is special, it is only used if you pass `-mod=vendor`, but then all your deps should be vendored. Decide what you want. If you don't want to vendor all your deps, then move `app/route` to the project root or to another module which you can import properly. To use a folder on your disk, see [How to use a module that is outside of “GOPATH” in another module?](https://stackoverflow.com/questions/52328952/how-to-use-a-module-that-is-outside-of-gopath-in-another-module/52330233#52330233) – icza May 19 '20 at 11:12
  • Well, the project from github https://github.com/josephspurrier/gowebapp and modified the code heavily. As you can see most of th code is in `vendor` but inside that there are imports from github and google. So what why do you suggest me to do to add `go.mod` with the least re-structuring? – Babr May 19 '20 at 11:20
  • 1
    You may try `go mod vendor` which downloads all dependencies into the `vendor` folder. But your setup seem like it asks for trouble itself. _"don't like github imports"_ is not a valid argumentation here. You're not making your life easier. – icza May 19 '20 at 11:22
  • @Babr Sorry, it's `go mod vendor`. But you should not force workarounds, you should try to properly import existing dependencies. – icza May 19 '20 at 11:26
  • Still get error: `module-path imports app/route: malformed module path "app/route": missing dot in first path element` – Babr May 19 '20 at 11:27
  • @Babr Yes, `go mod vendor` can only download properly imported packages. – icza May 19 '20 at 11:28
  • So please tell me how to modify the imports properly. I'm just using the `gowebapp` imports which are like `import ( "net/http" "app/shared/session" "app/shared/view" )` see:https://github.com/josephspurrier/gowebapp/blob/master/vendor/app/controller/index.go – Babr May 19 '20 at 11:30
  • Modify the imports to be valid. `app/shared/view` is not a valid import path if there is no module and its package denoted by this path. – icza May 19 '20 at 11:33
  • Sorry, it's not clear to me. Can you give me an example, for example what should be the correct import instead of `"app/route"`? The project was built and runnig fine before I added `go.mod`. – Babr May 19 '20 at 11:37
  • The import path must point to a valid package. If there is a published repo such as `github.com/icza/bito`, that is a valid import path. The path `this.leads.to.nowhere/invalid` is not a valid import path, there is no repository hosted there. If you use the `replace` directive in `go.mod` (see linked answer in my previous comment), you may designate any path to point to an existing package in your disk, then that will also be a valid import path. – icza May 19 '20 at 11:39
  • So how would you replace "app/route" in my case where I have downloaded https://github.com/josephspurrier/gowebapp and modifed the code base? Please give me an example instead of lectures. – Babr May 19 '20 at 11:43
  • @Babr That depends how where you put it, and what have you modified in it. Have you thought about that you could learn more from lectures than from a direct answer without reasoning? – icza May 19 '20 at 11:58
  • I have added some controllers, routes and models. I did not change the basic structure of the `gowebapp`, and I'm still in dark on how to modify the imports in order to make it modules-friendly. – Babr May 19 '20 at 12:02
3
go mod tidy

Run that command is the short answer

Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254