如果纠错是消除软件bug的过程,那编程一定是把它们放进去的过程。

最近收到几封邮件,来自国内的几个edX团队,问些edX开发相关的问题,问题大同小异,一并列到博客上,下回开发者中再有人问。我就把链接一甩,然后在沙发上继续翘着二郎腿看《冰与火之歌》

本文将谈论几个方面的问题:

  • 开发环境
  • IDE
  • 代码管理
  • 部署到生产环境
  • 协同开发
  • 测试
  • 我常用的工具

##开发环境 理论上可以在任何系统下开发,Linux/Mac/Windows都行。无论你在哪个系统下开发,你都应该熟悉linux(Ubuntu)。edX的开发者版本实际是个虚拟机,跑在Virtualbox里的Ubuntu12.04,采用Vagrant管理。

所以只要你的机器装有Vagrant和Virtualbox,无论Linux/Mac/Windows,你都可以开发edX

无论你在哪个系统下开发,大多时间你都在和Ubuntu打交道,更多细节可以参考edX-Developer-Stack

开发环境的搭建参考官方wiki就好,在此不赘述,参考这边:installing-the-edx-developer-stack

重点提醒一下,保证你的开发环境和生产环境参与的configuration版本一致,其中edx-platform的一致是最重要的。

##IDE 我是Vim党,偏好Unix工具箱,基本不用IDE。

Python社区比较鼓励Editor+IPython,我在折腾edX时,用的一直是Vim+IPython的组合,用地很顺手。据我所知,edX官方团队里,用IDE的人也是不多的,如果你偏好IDE,那么wiki里已经为你准备好文档了,关于如何配置PyCharm来开发edX:Setting-up-PyCharm-for-edX-development

PyCharm是Python社区比较流行的IDE,说实话,给edX配置PyCharm还蛮繁琐的,我在三个平台下(Linux/Mac/Windows)都帮人配置过,需要注意的是,Windows平台下无法把代码放到本地目录开发,其中有个软链接的坑(没记错的话,是xmodule目录,Windows下没有软链接),所以跑代码的时候会报错,你需要单独处理下这个软链接的问题。解决方案可以参考这里:dealing-with-line-endings-and-symlinks-under-windows,实际上我觉得官方的解决方案很烦,我的解决方案是采取的是PyCharm的远程编辑功能,如此一来,代码其实在本地虚拟机里,这样就不存在这个软链接的问题了

##代码管理 最恶劣的情况是,安装完毕后,就撸起袖子开始侵入式地定制开发了。连分支都不新建。

稍好一些的情况是, 知道先git checkout -b mybranch

那么最佳实践是什么呢,在我们谈论最佳实践的之前,必须熟悉Git,而后,选一种适合你们使用场景的,包括分支管理及workflow。这和恋爱相似,适合你的才是好的。之后我会分享下我们的做法

项目的技术负责人必须考虑到这样的事实,我们的开发版本基于上游代码库(官方版本)的某个release,在此基础上做自己的定制开发。而上游库一直在演进中,一边增加新特性,一边修复旧bug。越到后来,上游版本越健壮和强大,但我们不能一直等它变强再定制对不对,时机不等人,我们得着手开发自己的定制需求。同时我们又期望能够升级跟进到新的上游版本,如此一来,免费获得新特性的同时,又不丢失定制功能。这便很好地在商业中利用了开源技术,这个过程就是商业公司使用开源项目都要面临的问题。如果你不考虑升级和迁移,那么对公司,等同于损失了整个开源社区的力量。我想不出技术层面上比这更大的损失。

项目的技术负责人,在项目初期对这块投入多大的重视都不为过,之后会有丰厚的回报,如果草率开始,到时候必然面临手动迁移的局面,那么项目升级很可能不是件艰难的事,而是根本不可能。而那时官方出了杀手级的功能,你跟进还是不跟呢,你只好推倒重来

###定制开发 《代码大全》里说 >软件工程的本质即是管理复杂度

在这里,我只能提一些泛泛的建议:

  • 把代码尽量的模块化,定制的功能,可以的话,尽量整个丢到django app里
  • 尽量不要去入侵edx-platform源代码,尽可能采用非侵入式插件风格的定制
  • 诸如主题的定制,你应当使用theme,而不是去改templates
  • 诸如要课程分类,添加属性,尽量不要去动课程模型,而是自建model,采用course_id关联到原有课程。而后整个功能模块丢到django app里。

如果你采用了以上做法,你会发现迁移起来是并不麻烦的,至少是可能的。这也是我目前采用的做法,我们的系统截止到目前迁移了几次,前段时间又从release-2014-09-17升级到Birch,过程都还算顺利。

迁移的工作无非git rebase到上游新的release上,而后解决冲突/migrate数据就好。

关于数据迁移,可以参考我的另一篇文章:edx数据迁移

##部署到生产环境 现在假设你已经定制开发完毕,代码也都git push到远程仓库。

这块要细说的话,涉及到一系列Workflow相关的问题,所以不打算在此细说,况且一时半会儿也没法说清。这些更细致的内容我可能会放在edX国内开发者会议上作为主题发言来说:)

简单说来,就是用好Git,在你的开发环境和生产环境之间只需要同步代码就够了。最简单的做法是只修改了行为相关的代码,没有动系统环境和数据模型。那么只需要在开发环境下git push,然后到生产环境下git pull,之后sudo /edx/bin/supervisorctl restart edxapp:一下,生产环境就同步生效了

此外,如果想让让发布迭代过程更流畅。推荐采用Gitflow工作流,这种工作流示意图如下:

edx_development.png

##协同开发 只要是一个开发团队,就得面对这个问题,如何协同开发。

其实熟悉Vagrant和Git,(团队里至少应当有一人熟练Git,不然会很麻烦),遵循一些社区的建议,基本协同开发就不成问题了。

Vagrant用来保证成员之间系统环境的一致性,而Git用来管理代码。

根据协作情景的不同,我们需要选择不同的Git工作流

如果只是1,2个人,那么集中式工作流就够用了,以中央仓库作为项目所有修改的单点实体。SVN用户应该很熟悉

针对小团队而言(多数情况)。功能分支工作流,可能是不错的选择,简单清晰。核心想法是所有的功能开发应该在一个专门的分支上,而不是在master分支上。 这样一来,开发者在各自的功能上开发而不会弄乱主干代码

针对社区协作而言,Forking工作流最合适,如果暑期国内开发者会议顺利,应该国内社区也会成型,到时候,社区便采用这种方式,在github上协作,目前edX官方采用的也是这种工作流,采用Forking工作流的好处是开发者只需把定制代码push到自己的服务端仓库,而只有项目维护者才能push到正式仓库。 这样项目维护者可以接受任何开发者的提交,但无需给他正式代码库的写权限。
如此一来社区与各个公司之间也容易协作

##Pull Request Pull Request作为补充,可在以上三种工作流中应用,github的Pull Request提供了一个用户友好的Web界面,在提交变更到项目之前可以对变更进行讨论。
如此一来,每次提交的都有了专门的谈论区。团队成员间的协作变得更轻松方便

##测试 这一块没啥特别好说的,官方的wiki和文档都写得很清楚了,参考:

##我常用的工具 前边说了 我是Vim党,偏好Unix工具箱,基本不用IDE,以下是我折腾edX常用的工具

  • 编辑器:Vim
  • debug
    • IPython
      • 切换到edxapp环境下,安装IPython,之后sudo -u www-data /edx/bin/python.edxapp ./manage.py lms --settings aws shell
    • sudo -u www-data /edx/bin/python.edxapp ./manage.py {lms|cms} runserver 8000 --settings aws 使用django的django-debug-toolbar来调试,用于调试生产环境
    • 如果你熟悉django,你一定知道django-extensions。安装完django-extensions,你就可以使用runserver_plus,runserver_plus 命令启动测试服务,并用 Werkzeug 作为调试后台,Werkzeug的强大无需赘言
  • 数据库相关:mongodump,mysqldump,图形化工具可以使用:Robomongo,MySQLWorkbench
  • 网络相关:httpie,nethogs,iftop
  • 源码阅读:understand,Souce Insight
  • Unix工具箱:git,tail,tmux,htop,ack,diff,grep,tar,scp,crontab…