V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
guonaihong
V2EX  ›  Go 编程语言

golang:项目迁移到 go mod 踩坑记

  •  
  •   guonaihong ·
    guonaihong · 2019-11-13 09:33:05 +08:00 · 12406 次点击
    这是一个创建于 1836 天前的主题,其中的信息可能已经有所发展或是发生改变。

    记录项目迁移到 go mod 里面的一些坑

    下面聊的一些坑都是在模拟环境上说的,除非想要 n+1,就不露真实目录结构了。一开始项目的目录结构是 src 风格,和现在的 github 风格很不一样,记录下迁移遇到的问题。

    模拟环境

    目录结构

    .
    └── src
        ├── main.go
        └── nocode
            └── nocode.go
    

    main.go 内容

    package main
    
    import (
    	"fmt"
    	"nocode"
    )
    
    func main() {
    	nocode.NoCode()
    	fmt.Println("vim-go")
    }
    
    

    nocode.go

    package nocode
    
    import (
    	"fmt"
    )
    
    func NoCode() {
    	fmt.Printf("no code\n")
    }
    
    

    迁移过程

    • 直接编译看下错误
    src/main.go:5:2: cannot find package "nocode" in any of:
    	/home/guo/go-version/go1.13.1/src/nocode (from $GOROOT)
    	/home/guo/go/src/nocode (from $GOPATH)
    
    • 先构造 go.mod(第一步)
    go mod init main
    
    • go build src/main.go
    build command-line-arguments: cannot load nocode: malformed module path "nocode": missing dot in first path element
    
    • 需要解决本地包,修改 go.mod 文件(使用 replace 指令)
    module main
    
    replace nocode => ./src/nocode
    
    go 1.13
    
    • go run src/main.go
    go: nocode: parsing src/nocode/go.mod: open /home/guo/talk_go_mod/src/nocode/go.mod: no such file or directory
    
    
    • cd src/nocode/ && go mod init nocode

    • go run src/main.go

    no code
    vim-go
    
    

    重点总结

    • 使用 replace 指令 重定向本地包的位置
    • 本地包没有 go.mod 会报错

    github

    https://github.com/guonaihong/gout

    26 条回复    2019-11-14 10:47:20 +08:00
    dic
        1
    dic  
       2019-11-13 09:44:50 +08:00 via Android   ❤️ 1
    go mod init main

    import "main/nocode"


    不需要放 src 目录
    janxin
        2
    janxin  
       2019-11-13 09:51:01 +08:00   ❤️ 3
    你使用的方式就直接往坑里去了吧...
    liuminghao233
        3
    liuminghao233  
       2019-11-13 09:55:10 +08:00 via iPhone
    1l+1
    新项目的话不应该这样玩
    旧项目的话 换我也全部改了(
    superchijinpeng
        4
    superchijinpeng  
       2019-11-13 09:56:07 +08:00 via iPhone
    第一次看到你这样的使用方式
    guonaihong
        5
    guonaihong  
    OP
       2019-11-13 10:10:24 +08:00
    @dic 这个方法要修改源码里面的 import 路径,所以当初没有选用。。。
    guonaihong
        6
    guonaihong  
    OP
       2019-11-13 10:10:51 +08:00
    @liuminghao233 好几年的老工程。
    Vegetable
        7
    Vegetable  
       2019-11-13 10:12:27 +08:00
    我当时是一狠心把 import 路径全改了.
    TypeErrorNone
        8
    TypeErrorNone  
       2019-11-13 10:15:57 +08:00
    你搞错了,如果要迁到 mod 的话,直接把代码 clone 到一个新目录,在这个新目录里改造。
    因为 clone 下来的代码肯定都在一个目录下,就不再用 replace 了。
    reus
        9
    reus  
       2019-11-13 11:07:39 +08:00   ❤️ 4
    这不叫坑,这叫根本不懂
    JackyCDK
        10
    JackyCDK  
       2019-11-13 11:23:43 +08:00   ❤️ 1
    直接把人往坑里带啊...
    egen
        11
    egen  
       2019-11-13 11:44:45 +08:00
    改 import 基本 0 风险都不愿意改
    yoshiyuki
        12
    yoshiyuki  
       2019-11-13 12:08:38 +08:00
    go mod 迁移的最佳实践应该就是改 import,用编辑器批量修改一下就完事了
    guonaihong
        13
    guonaihong  
    OP
       2019-11-13 12:35:13 +08:00
    @TypeErrorNone 你说的方式没玩过,可否详细说下。如何处理不能通过域名访问的本地包?比如上面的 nocode 包。
    guonaihong
        14
    guonaihong  
    OP
       2019-11-13 12:40:03 +08:00
    @janxin 如何理解带坑里,janxin 兄的做法是?
    guonaihong
        15
    guonaihong  
    OP
       2019-11-13 12:41:22 +08:00
    @reus 懂于不懂的区别是? reus 兄处理这个问题的做法是?
    lxml
        16
    lxml  
       2019-11-13 14:22:12 +08:00
    哪怕用了 go.mod 可以叫 main 啥的,但最好还是叫 github.com/aaa/bbb 这种三级目录,不然迟早挖坑
    janxin
        17
    janxin  
       2019-11-13 14:24:23 +08:00
    @guonaihong 应该是你例子的问题,你这个例子里面会让人以为 nocode 是当前包的一部分存在的,而你后面表述的事情跟这种表现又不一致,存在很多歧义问题。我想很多人也不会按照这种模式在 GOPATH 下组织目录的。
    TypeErrorNone
        18
    TypeErrorNone  
       2019-11-13 14:26:07 +08:00
    你上面为了在 main.go 中引用 nocode 包里的方法,加了 replace 和 go mod init 初始化了 nocode 包。

    因为要用 go mod 来管理依赖包,可以这么搞。
    假设你把 src 下的代码全部都上传到了 github.com/v2ex 下。
    1.把代码 clone 到 /data/v2ex 下,所有的代码都在 ve2x 目录这里。
    2.开启 go mod 功能,再在 V2EX 下 go mod init。
    3.go build main.go 自动下载外部依赖包,这时要用到内部包 nocode,直接改下 import 路径即可( goland 可以自动找到更改),不用再在 nocode 里 go init 和 replace。
    znood
        19
    znood  
       2019-11-13 17:53:20 +08:00
    你这是不会用,不叫坑
    坑的是多版本依赖,logrus 路径大小写,v2 版本,还有本地库的使用
    guonaihong
        20
    guonaihong  
    OP
       2019-11-13 19:30:01 +08:00
    @znood 多版本依赖,何时会出现? pkg/mod 里面的包都是带版本的号的,很好奇?
    lcj2class
        21
    lcj2class  
       2019-11-13 19:36:43 +08:00
    guonaihong
        22
    guonaihong  
    OP
       2019-11-13 19:42:12 +08:00
    @TypeErrorNone  我懂你的意思了,和在 github 做法类似。
    guonaihong
        23
    guonaihong  
    OP
       2019-11-13 19:48:54 +08:00
    @znood 本地包,我上面展示了用 replace 指令搞定。还有别的坑吗?
    zunceng
        24
    zunceng  
       2019-11-13 19:55:01 +08:00
    10w+行代码的项目 我一天就改完了
    小坑平推就完了
    guonaihong
        25
    guonaihong  
    OP
       2019-11-13 22:17:59 +08:00
    @zunceng 厉害厉害。
    zunceng
        26
    zunceng  
       2019-11-14 10:47:20 +08:00
    @guonaihong 去年 11 月 我看 prometheus 的 node_exporter 用了 go mod
    然后我也把项目用了 node_export 如果没出意外 go dep 转 go mod 一行命令就转了
    但我们项目里有个库 接口变了 我记得 golang-x-crypto 上的 也没改几行
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2693 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 12:34 · PVG 20:34 · LAX 04:34 · JFK 07:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.