标签 Git 下的文章

godep的一个“坑”

很多人学习和使用Golang一段时间后,都会被golang的第三方包依赖版本搞得有些烦躁,golang设计者最初过于乐观的设计使得今天大 家不得不各自想办法解决这个问题。godep就是综合了多年第三方包依赖问题的解决方案后的一个趋向统一的方案,至少是在go get的设计没有进化前的一个比较不错的方案。

今天试用了一把godep,不过“体验”并不理想,这缘于我遇到了godep的一个“坑”,不过是那种你在正式项目中不一定遇到的“坑”,这里来说到说到。

按照godep官方使用说明的第一步,先下载godep:

$ go get github.com/tools/godep
$godep
Godep is a tool for managing Go package dependencies.

Usage:

    godep command [arguments]

The commands are:

    save     list and copy dependencies into Godeps
    go       run the go tool in a sandbox
    get      download and install packages with specified dependencies
    path     print sandbox path for use in a GOPATH
    restore  check out listed dependency versions in GOPATH
    update   use different revision of selected packages

Use "godep help [command]" for more information about a command.

确认正确下载后,我们来准备一个测试例子,目录如下:

$GOPATH/
    src/
        tonybai.com/
                foolib/
                   foo.go
                fooapp/
                   main.go
       
   
//foo.go
package foo

func Add(a, b int) int {
        return a + b
}

//main.go
package main

import (
        "fmt"
        foo "tonybai.com/foolib"
)

func main() {
        fmt.Println(foo.Add(1, 3))
}

fooapp下,编译执行程序:

$go run main.go
4

接下来godep登场,根据godep文档中得步骤,接下来我们应该在一个构建依赖关系完整的项目中执行godep save以保存依赖关系以及依赖的当前版本第三方包:

$godep save
godep: directory "/Users/tony/Test/GoToolsProjects/src" is not using a known version control system
godep: error loading dependencies

出错了!godep提示$GOPATH/src目录没有使用任何版本控制系统(not using a known version control system)。 奇怪啊!这个错误什么意思呢?难道使用godep还需要将$GOPATH/src整体作为一个Project纳入git or subversion repository中?无奈之下,我只能先这么做,再作观察。我在$GOPATH下执行git init,建立一个local git repository,然后将src add到这个repository中。

回到fooapp下,再次执行godep save,居然依旧是同样地错误结果。于是到godep的issues中去查,看看是否有人和我遇到了同样地问题!godep的#116 issue中提到的问题恰恰和我的一致,不过这个issue一 直是open状态,也没有人comments。接着翻看一下godep的源码,godep依赖一些第三方包,save这个命令在分析版本控制工具库时也是 调用了多层外部包实现的,短时间内无法定位问题。

静想一下,godep是管理第三方包依赖关系的,而第三方包多是go get下载的,是不是foolib要放到repository中才行呢?于是尝试在foolib中建立git repository并做一次commit。第三次在fooapp下执行godep save,错误依旧!

难道fooapp也必须放在repository中?试试吧。在fooapp下init一个git repository,将fooapp下的main.go提交到repository中。再执行godep save:

$godep save
$ls -l
total 8
drwxr-xr-x  5 tony  staff  170 10 30 22:01 Godeps/
-rw-r–r–  1 tony  staff  103 10 30 21:44 main.go

这回成功了!godep save在fooapp下建立了Godeps目录,其结构如下:

$ls -R
Godeps.json    Readme        _workspace/

./_workspace:
src/

./_workspace/src:
tonybai.com/

./_workspace/src/tonybai.com:
foolib/

./_workspace/src/tonybai.com/foolib:
foolib.go

godep将当前版本的foolib copy到Godeps/_workspace下了。

Godeps.json记录了fooapp对foolib的依赖关系:

{
        "ImportPath": "fooapp",
        "GoVersion": "go1.3",
        "Deps": [
                {
                        "ImportPath": "tonybai.com/foolib",
                        "Rev": "20a9c2a682537813d37847f2f270bf929672cc84"
                }
        ]
}

godep记录了foolib的当前revision number,这个number恰是我最新一次commit的hash code:

~/Test/GoToolsProjects/src/tonybai.com/foolib]$git log
commit 20a9c2a682537813d37847f2f270bf929672cc84
Author: Tony Bai <bigwhite.cn@gmail.com>
Date:   Thu Oct 30 22:00:25 2014 +0800

    init

到这里让我觉得godep的设计思路有些与我的buildcC程序辅助构建工具)的思路有些类似,只是godep做得更彻底:

    1、godep将项目依赖统统放到项目的私有_workspace下,而buildc是共享的,通过project下的版本号配置区分依赖
    2、godep将依赖管理到revision(修订号)级别,buildc只是根据version来区分依赖。

godep的辅助构建原理(godep go build main.go)通过一条命令即可看出来:

$godep go env
GOARCH="amd64"
GOBIN="/usr/local/go/bin"
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/tony/Test/GoToolsProjects/src/fooapp/Godeps/_workspace:/Users/tony/Test/GoToolsProjects"

godep临时将_workspace放在GOPATH列表的前面,这样gc在编译时就会按顺序先在_workspace下面找依赖包,这样fooapp的私有依赖就会理所当然的被gc用到,即便在其他GOPATH路径下有同名包(可能是不同版本的)。

显然这也算是godep的一个小bug吧(或者是godep依赖的包的bug,目前不确认),毕竟提示的路径是不正确的,不应该提示"/Users/tony/Test/GoToolsProjects/src" is not using a known version control system,而应该是"/Users/tony/Test/GoToolsProjects/src/tonybai.com/foolib或"/Users/tony/Test/GoToolsProjects/src/fooapp没有版本控制系统的repository留存。

另外觉得godep的author应该把这个“坑”作为一个使用godep的前提进行说明,并在github主页给出明确展示,即便这个“坑”多数人可能不会遇到。

关于程序员的构思能力的一些体会

有一段时间,我完全沉迷于在脑海中想象机械绘图和设计新机型所带来的极致享受,这是我一生中有过的最完美的精神愉悦。创造的灵感像泉水般源 源不断 地涌出,我遇到的唯一困难就是必须设法牢牢抓住它们。对我来说,构思中的设备零件都绝对是真实的,所有细节都触手可及,甚至最细微的标识和磨损状态也是如 此。想象发动机在持续不断地运转,仿佛一道迷人的风景呈现在面前,令我欣喜若狂。
                                                                                                       尼古拉. 特斯拉

看完上面这段特斯拉回忆录中的自述后,我们不禁惊叹于特斯拉超乎寻常的大脑构思能力。读完特斯拉的回忆录《被世界遗忘的天才:特斯拉回忆录》后, 我完完全全相信特斯拉是一个不折不扣的“外星人”,就是像克拉克.肯特那样被送到地球的“超人”。不同于超人的是他给地球带来的不是钢铁般的身躯和无比的 正义,而是超级智慧。他的所思所想所做所为完全超越了那个时代,甚至是当今的时代。作为程序员,我们不敢奢望能拥有特斯拉那样的超级构思力,但拥有一个良 好的构思力对于程序员来说还是蛮重要的。

【什么是构思力】

就我自己的认知和经验来说,构思力是一种“在大脑中构造事物的能力”,构造出的事物不是静态的,它在你的构思下不断演化,像是一部电影。日常生活工作中, 绝大部分人都是被动构造,当收到外界的输入时,包括影像、声音、感悟等时,在大脑中应激性的出现一些事物和场景。这种构思的持续时间很短,从长度上来说, 都是微电影,并且很难抓住并转换为现实,价值不大。真正的有价值的构思应该是主动、有意识、有目的地在大脑中构造。因此构思力常用于在创造、创作以及发明 的过程中,各个行业莫不如此。

【构思 vs. 设计】

构思与设计都需要经过脑力完成,甚为相似,难于区分,但个人觉得还是有些许差别。就就像特斯拉回忆录里描述的那种情形,我们称之为构思。构思强调事物从无到有, 都在脑中完成,是一种全脑演算。有时就是一个闪念,瞬间迸发出来,很迅速,并可被快速捕捉到,构思者往往会变得热情高涨,并在短时间内完成主体设计和实 现。构思往往一次成型,多用于整体或全局设计,是真正设计阶段开始的前置条件。构思过程会将事物的全貌在大脑中构造出来;将关键的技术难点在脑中完成突 破,形成思路;会将事物与外围接口在脑中进行对接;会对创造出来的事物在脑中进行初步的验证,证明其正确性。

设计则会将前期构思的事物分解并细化,落于纸面,或画出各种图形,多是渐进和迭代的;有时用作局部优化。

因此可以看出,构思是更高层次的设计

【程序员与构思】

程序员的日常工作与创造关系紧密,而“创新”则离不开构思。哪些工作属于构思范畴呢?目前看来比例不多,在目前这个网络四通八达发达,搜索引擎智能强大的 时代,你要的解决方案基本都能在Internet上找到,只是将现成的方案挪到你的solution中,我觉得算不上构思,顶多是设计,设计如何将现有的 东西组合起来。

构思的结果是崭新的方案或是基于已有方案的优化改进,是有脑力参与的事物演化。但构思不是必须凭空创造,多是站在巨人的肩膀上,是个借鉴再创新的过程。构思有时候可能有“重新发明轮子的味道“,但重造轮子不一定不好。

构思可大可小,Linus Torvalds设计并实现GitMatz发明Ruby等属于大构思,你将某个算法的性能提升20%可算作小构思。

在软件开发领域,构思不是技术领域专有的,业务流程或过程的创新都与构思不无关系。

Non-trivial的开源项目多是构思的结果。我个人在开源lcut, cbehave, buildc时也是深有体会的。当大脑中构思演化出目标图景时,人会变得极为亢奋,软件的主体架子在短短几个小时或一两天内就完成了。很多著名的开源项目也是如此。

【影响构思力的几个因素】

构思力高低要看大脑的活力。个人理解影响构思力高低的几个因素:

    * 脑部成像构造能力
      
        就像特斯拉那样,每个人脑部都有一定的事物成像能力,比如提到神舟发射,你脑中会呈现某种画面;再比如提到Google数据中心,你脑中又会出现何种场 景。当然这些例子还都是简单的事物还原能力。当提到让你改进神舟飞船或降低Google数据中心能耗时,你的脑中的画面会有怎样的变化呢?能否变化或能否 沿着对应的问题演化能反映出构思能力的高低。当然这是需要有领域知识、眼光和技能的。改进的神舟飞船与降低了能耗的Google数据中心是不存在的,需要 你使用纯粹的空想构造能力对其进行演进的。训练你的脑部构造能力,要求你日常勤于用脑,勤于思考,经常将各种信号输入(语言、声音、感觉)进行转换,在脑 中尝试成像,减少视觉信号的输入。记得小时候印象最深的一件事就是一边听着单田芳老师的评书,一边在大脑中构造对应的场面、人物形象和情节,我想这对我大 脑的构思成像能力是大有裨益的。

    * 知识与眼光的广博
       
        凭空的构思创造毕竟是少数,而多是站在巨人的肩膀上。这要求你对所属领域甚是是相关领域有一定的了解和认知,这样在构思时,才能如特斯拉那样思如泉涌,思想的碰撞火花四溅。这就像拍摄电影,需要在日常积累各种素材和技法,兼容并序。

    * 对问题域的透彻理解

        构思多是行业领域相关的,构思的结果都是隶属于某个领域或行业的。构思出的方案是为了解决一个明确的问题或满足特定需求,因此是否对问题有透彻的理解将直接影响构思过程和结果,以及你构思力的发挥。

以上关于构思力的论述感觉还不够系统成熟,仅是一些主观心得体会罢了,供参考并欢迎交流。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats