我试图在我们的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
答案 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
,而不是GOROOT
或GOPATH
。
不过,请检查直接包裹上的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)