我们从一个开发人员开始,然后是一个包含我们所有代码的svn存储库:
^/foo/trunk/module-a
^/foo/trunk/module-b
^/foo/trunk/module-b/submodule-b1
^/foo/trunk/website1
(当时是一个很大的进步)。在这有了长足发展的机会之后,我们开始遇到循环依赖项,缓慢的测试套件以及重用代码的一般困难的问题(因为例如website1的功能集已潜入其他通用模块-a中)。
想要对代码库进行模块化,并希望我们不久就迁移到git(并且已经读过git不喜欢svn mega-repos的地方),我们已经过渡到了更精细的结构:
^/module-a/trunk/
^/module-b/trunk/
^/module-b/trunk/sumbmodule-b1
^/earlier-sub-sub-sub-module-c/trunk
etc. (about 120 such modules)
从概念上讲,这很棒。更多的模块化代码,更快的测试套件,更容易记录的文档,等等。我们开源了一些更通用的组件,并使所有模块都可以pip安装(pip install -e .
用于将它们安装在development
virtualenv中)。
我们创建了一个^/srv/trunk
存储库,其中包含运行时环境的文件夹结构。^/srv/trunk/lib
用于模块,/srv/trunk/src
用于的其余部分^/foo/trunk
,^/srv/trunk/www
用于网站等。
最后(从我很久以前与perforce合作的[ https://www.perforce.com/perforce/r12.1/manuals/cmdref/client.html]中吸取灵感),我们创建了一个“ vcs-提取”文本文件,其中列出了所有相关的存储库以及应将其检出到开发环境中的位置,并提供了相应的命令来执行此操作。例如vcs-fetc行:
svn srv/lib/module-a ^/module-a/trunk
会导致(第一次)
cd /srv/lib && svn co ^/module-a/trunk module-a
或(之后)
cd /srv/lib/module-a && svn up
同样适用于github repos(我们自己的和更改/未更改的供应商软件包)。
我们使用了相同的vcs-fetch流程来创建生产环境,但是我们很快发现,在进行vcs-fetch之后,我们无法知道哪个版本在prod中运行。
对于大型仓库,我们可以在从主干更新产品之前记下修订号,然后回去就很简单svn -r nnn up .
了。使用svn和git中的代码(以及hg中的一个模块)以及〜120个仓库,如何执行此操作并不明显。
我今天读了http://12factor.net/,第一个因素是“一个代码库”,所以我也想知道我是否在正确的道路上走?
我曾经想到的一个想法是创建一个部署脚本,该脚本将创建可pip安装的“部署”轮,并将它们“捆绑”在一个requirements.txt
文件中。然后,部署将涉及创建新的virtualenv,点安装列出部署轮的requirements.txt文件,并切换活动的virtualenv。恢复到先前的状态仅涉及将virtualenv切换回去(但是除非我们希望永久保留virtualenv,否则不允许我们回到任何时间点-尽管根据我的经验,这是从未需要的)。
在这一点上,我想知道我是朝错误的方向行走,还是只是在正确的道路上走的不够远。(我正在阅读的所有内容都在谈论“您的应用”,而且我不知道这将如何转化为使用相同的代码库运行14个网站...)