如何查看嵌套Go依赖

时间:2017-06-13 12:07:08

标签: go build dependency-management

我试图在我们的CI中调试以下构建错误,其中" A依赖于无法构建的B,因为它依赖于C。"我正在建立我的数据服务,它并不直接依赖于kafkaAvailMonitor.go,这使得这个错误难以追踪。换句话说:

  

数据(我建造的)取决于(?)依赖的数据   kafkaAvailMonitor.go

修复他们刚刚做的开发人员可能看起来微不足道。"去做任何事情"但作为发布过程的一部分,我无法做到这一点 - 我必须找到添加依赖关系并要求他们修复它的人。

我意识到有可视化依赖树和其他更复杂的构建系统的工具,但这似乎是一个非常基本的问题:有什么方法可以查看完整的跟踪以查看什么'导致构建问题?回应其中一条评论 - 我用过的所有编程语言,例如Java / Python都提供了开箱即用的这些信息,它对调试我没有写过的代码非常有帮助,因为我不能只看一个像POM或requirements.txt这样的地方看看谁添加了依赖。

同样回应评论 - 如果以下不是堆栈跟踪它是什么?二进制文件记录到stdout的错误列表? Aren的那些错误是由正在执行的go build二进制文件首先放入堆栈的吗?对我来说似乎是一种愚蠢的区别,并且说#34;它不是堆栈跟踪"特别是当它与我的问题无关时,但我删除了“#34; stack"从问题是否能让人开心。

go build -a -v

../../../msgq/kafkaAvailMonitor.go:8:2: cannot find package 
  "github.com/Shopify/sarama/tz/breaker" in any of:
  /usr/lib/go-1.6/src/github.com/Shopify/sarama/tz/breaker (from $GOROOT)
  /home/jenkins/go/src/github.com/Shopify/sarama/tz/breaker (from $GOPATH)
  /home/jenkins/vendor-library/src/github.com/Shopify/sarama/tz/breaker
  /home/jenkins/go/src/github.com/Shopify/sarama/tz/breaker
  /home/jenkins/vendor-library/src/github.com/Shopify/sarama/tz/breaker

3 个答案:

答案 0 :(得分:5)

使用模块时,您可能可以从 using (myEntities db = new myEntities ()) { db.Database.Connection.Open(); try { using (var scope = db .Database.BeginTransaction(System.Data.IsolationLevel.Serializable)) { { var test = db.customer_table.Where(x => x.id == 38).FirstOrDefault(); test.bank_holder_name = "CLIENT A"; db.SaveChanges(); scope.Commit(); } } } catch (Exception ex) { throw; } } 获得所需的信息。

go mod graph

例如,对于原始问题,运行usage: go mod graph Graph prints the module requirement graph (with replacements applied) in text form. Each line in the output has two space-separated fields: a module and one of its requirements. Each module is identified as a string of the form path@version, except for the main module, which has no @version suffix. ,然后更仔细地查看左侧的每个条目。

答案 1 :(得分:3)

  

如果以下不是堆栈跟踪是什么?

这是Go寻找您丢失的包裹的路径列表。

  

我不知道是谁导入kafkaAvailMonitor.go

它不是“导入”,只是您的部分来源并已编译 除非它无法编译,因为它需要github.com/Shopify/sarama/tz/breaker,而不是GOROOTGOPATH

不过,请检查直接包裹上的go list would return,看看是否提到kafkaAvailMonitor

  

go list可以显示程序包直接依赖的程序包,也可以显示其完整的传递依赖项集。

% go list -f '{{ .Imports }}' github.com/davecheney/profile
[io/ioutil log os os/signal path/filepath runtime runtime/pprof]
% go list -f '{{ .Deps }}' github.com/davecheney/profile
[bufio bytes errors fmt io io/ioutil log math os os/signal path/filepath reflect run

然后,您可以编写脚本列表以列出所有依赖项 请this bash script for instance

查看Noel Cower (nilium)
#!/usr/bin/env bash
# Usage: lsdep [PACKAGE...]
#
# Example (list github.com/foo/bar and package dir deps [the . argument])
# $ lsdep github.com/foo/bar .
#
# By default, this will list dependencies (imports), test imports, and test
# dependencies (imports made by test imports).  You can recurse further by
# setting TESTIMPORTS to an integer greater than one, or to skip test
# dependencies, set TESTIMPORTS to 0 or a negative integer.

: "${TESTIMPORTS:=1}"

lsdep_impl__ () {
    local txtestimps='{{range $v := .TestImports}}{{print . "\n"}}{{end}}'
    local txdeps='{{range $v := .Deps}}{{print . "\n"}}{{end}}'

    {
        go list -f "${txtestimps}${txdeps}" "$@"
        if [[ -n "${TESTIMPORTS}" ]] && [[ "${TESTIMPORTS:-1}" -gt 0 ]]
        then
            go list -f "${txtestimps}" "$@" |
            sort | uniq |
            comm -23 - <(go list std | sort) |
                TESTIMPORTS=$((TESTIMPORTS - 1)) xargs bash -c 'lsdep_impl__ "$@"' "$0"
        fi
    } |
    sort | uniq |
    comm -23 - <(go list std | sort)
}
export -f lsdep_impl__

lsdep_impl__ "$@"

答案 2 :(得分:2)

上面的答案仍然没有向我展示一个依赖树,所以我花了很多时间编写一个脚本来做我需要的东西 - 希望能帮助其他人。

上述解决方案的问题(其他提议如go list)是它只告诉我最高级别。他们不会穿过这棵树。&#34;这是我得到的输出 - 除了构建给我的东西之外,它没有任何帮助。

.../npd/auth/
   .../mon/mlog
   .../auth/service

这就是我想要获得的东西 - 我知道auth已被破坏(顶部)并且断路器已经破坏(底部),但我不知道它们之间是什么 - 我的脚本下面给出了这个输出。

.../npd/auth/
    .../npd/auth/service                
        .../npd/auth/resource
            .../npd/auth/storage
               .../npd/middleware
                  .../npd/metrics/persist
                    .../npd/kafka
                        .../vendor-library/src/github.com/Shopify/sarama
                            .../vendor-library/src/github.com/Shopify/sarama/vz/breaker

我的剧本

import subprocess
import os

folder_locations=['.../go/src','.../vendor-library/src']

def getImports(_cwd):
    #When the commands were combined they overflowed the bugger and I couldn't find a workaround
    cmd1 = ["go", "list", "-f", " {{.ImportPath}}","./..."]
    cmd2 = ["go", "list", "-f", " {{.Imports}}","./..."]

    process = subprocess.Popen(' '.join(cmd1), cwd=_cwd,shell=True,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)

    out1, err = process.communicate()

    process = subprocess.Popen(' '.join(cmd2), cwd=_cwd,shell=True,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)

    out2, err = process.communicate()
    out2clean=str(out2).replace("b'",'').replace('[','').replace(']','').replace("'",'')

    return str(out1).split('\\n'),out2clean.split('\\n')

def getFullPath(rel_path):
    for i in folder_locations:
        if os.path.exists(i+'/'+rel_path):
            return i+'/'+rel_path
    return None

def getNextImports(start,depth):

    depth=depth+1
    indent = '\t'*(depth+1)

    for i,val in enumerate(start.keys()):

        if depth==1:
            print (val)

        out1,out2=getImports(val)

        noDeps=True
        for j in out2[i].split(' '):
            noDeps=False

            _cwd2=getFullPath(j)
            new_tree = {_cwd2:[]}
            not_exists = (not _cwd2 in alltmp)

            if not_exists:
                print(indent+_cwd2)
                start[val].append(new_tree)
                getNextImports(new_tree,depth)
                alltmp.append(_cwd2)

        if noDeps:
            print(indent+'No deps')

_cwd = '/Users/.../npd/auth'

alltmp=[]
start_root={_cwd:[]}
getNextImports(start_root,0)