前言

前言

本书说明如何构建软件工具。

如果你经常编写软件,肯定知道这其实是创建工具的过程。软件也是工具。说到底,电子表格只是加减数字的工具,电子游戏只是打发无聊时间的工具。在人们开始编写软件工具之后,我们几乎立即发现,为了顺利写出一开始想写的那个软件,需要有更多的工具来支持。我们把这些支持软件开发的工具(不是常规意义上的软件工具)叫作元工具(meta-tool)。

在软件开发领域,最重要的一个元工具是 Git。这个元工具能帮助软件开发者解决编写软件过程中的复杂问题。使用 Git,软件开发者可以存储程序的快照(如果需要,可以轻易还原快照),还便于与其他程序员协作(这是个相当复杂的问题)。Git 是一种源码管理(Source Code Management,SCM)工具,虽然在此之前有很多 SCM 工具,但是都没像 Git 这样对软件领域产生如此大的影响。目前,Git 在 SCM 工具中处于领先地位。

GitHub 公司及早发现了 Git 的无穷潜力,以 Git 的功能为底层基础,构建了一层 Web 服务。不难想象,GitHub 成功的因素之一是,员工们从一开始就积极跟随潮流,编写大量的元工具。开发元工具要耐得住寂寞,不能急于求成。GitHub 的员工们对这种做事顺序引以为荣,并撰写了大量文章说明了这样做的好处,例如便于新员工融入,工作流程对所有员工都透明。

本书一窥 GitHub 内部使用的工具。GitHub.com 网站本身也是一个元工具,我们会从多个方面讨论 GitHub 服务。具体而言,我们涉及的技术有 GitHub API 及相关的 GitHub 技术、Gollum 维基、静态页面生成工具 Jekyll,以及聊天机器人 Hubot(如果你对这些都不熟悉,不用担心,我们将在不同的章节详细说明)。

我要重申一点,这不是上述几项技术的参考书。这是一本故事书,以叙事的方式描述构建软件元工具的相关过程,期间不只介绍相关的技术,还会说明折中方案、重构的现实意义,以及编写元工具面临的挑战。

编写元工具所需的思维与常规的软件不同。一般来说,元工具是开源的,用法和责任都不同寻常。有人可能认为,与普通用户相比,软件工程师对质量有更高的要求,因为软件不能满足软件开发者的需求时,他们可以改进或派生。编写元工具需要付出更多的精力,因而自动化测试几乎是必备的。开发元工具之前一定要知道这些概念,本书将告诉你如何在构建元工具的过程中运用这些概念。

为什么使用API,为什么选择GitHub API

使用 API 支持应用是当下常见的做法,这也是应用开发的发展方向。如今显示设备多种多样,使用 API 能在不同的设备中更好地呈现数据。以远程服务 API 支持的应用,起初可能是运行在 Apple iOS 操作系统中的移动应用。经市场验证之后,如果发现这种商业模式不正确,可以迅速响应变化的需求,为 Android 穿戴设备构建新应用,构建车载应用,或者其他控制台(或非控制台)应用。只要应用能调用远程 API 收发数据,你就能为任何平台构建任何用户界面。

此外,我们自己也可以编写和托管 API。Ruby、Go 和 Java 等流行语言的很多框架都支持使用标准的架构风格(如 REST)构建 API。不想自己构建的话,还可以使用第三方 API。本书专门针对一个第三方 API,即 GitHub API。

为什么是 GitHub API 呢?对构建软件的你来说,基本上离不开 GitHub API,因为你可能就使用 GitHub 管理软件代码。即便不用 GitHub,也有可能使用 Git。而 GitHub API 也能操作 Git,因为它把 Git 的功能抽象成网络编程接口了。

GitHub API 算是我见过设计得最好的 API 了。它是超媒体 API,基本上成功解决了一个棘手问题:让 API 客户端适应 API 的变化。GitHub API 有良好的版本划分,功能完整,而且实现了大多数 Git 功能。GitHub API 由多个结构合理的部分组成,便于构建应用。GitHub API 是个典型,通过它可以学习好的 API 应该怎么设计。

本书结构

GitHub API 的功能非常全面,通过它可以访问和修改 Git 仓库中存储的或与之有关的几乎所有数据和元工具。根据 GitHub API 的文档(https://developer.github.com/v3/),我按照字母顺序简要列出了其各部分的作用。

  • Activity:开发者关注的事件通知

  • Gists:以编程的方式创建和分享代码片段

  • Git Data:通过远程 API 访问原始的 Git 数据

  • Issues:添加和修改工单

  • Miscellaneous:无法纳入其他分类的 API

  • Organizations:存取组织成员数据

  • Pull Requests:一个强大的 API,建构在合并过程之上

  • Repositories:修改与仓库有关的一切数据

  • Search:在整个 GitHub 数据库中搜索代码

  • Users:访问用户数据

  • Enterprise:企业内部的 GitHub 专用的 API

此外,有些重要的技术在 GitHub API 文档中没有说明。虽然这些技术不是 API 的一部分,但是使用 GitHub 时应该知道。

  • Jekyll 和“gh-pages”:托管博客和静态文档

  • Gollum:与仓库关联的维基

  • Hubot:GitHub 广泛使用的可编程聊天机器人

GitHub 技术栈的各个部分分别在不同的章节介绍(有两个不会介绍,原因如后)。GitHub API 文档是优秀的参考,编写与 GitHub API 通信的应用时会经常查阅。本书的目的则不同,我们将叙述如何使用 GitHub 提供的技术构建应用。这些故事会告诉你使用 GitHub API 时要采取哪些折中措施,有什么注意事项。如果需要,一章可能涵盖多个 API。通常,每一章都尽量专注于一个主要的 API,努力不涉及其他 API,但是大多数章节确实需要涉及别的 API。

下面概述各章的内容。

第 1 章首次介绍如何使用命令行 HTTP 客户端 cURL 访问 API,并说明响应的格式、如何在命令行中解析响应,以及身份验证方式。这是本书唯一没有使用上述技术构建应用的一章。

第 2 章介绍 Gist API、几个命令行工具,以及 Ruby 语言 API 客户端 Octokit。然后,使用 Gist API 构建一个简单的 Ruby 服务器,存储并显示 Gist。

第 3 章说明如何使用 Gollum 命令行工具及相关的 Ruby 库(gem)。Gollum 由 Grit 提供支持,Grit 是一个 C 语言绑定,用于访问 Git 仓库。我们还会说明 Git 存储格式的一些细节,在 Git 仓库中存储大文件的方式,以及如何使用 Git 命令行工具访问这些信息。这一章使用 Gollum 和 Grit 库构建一个图像管理工具,不过它仍是一个常规的 Gollum 维基,可以发布到 GitHub 中。

第 4 章探讨 Search API,然后使用 Python 构建一个 GUI 工具,用于搜索 GitHub 中的仓库。

第 5 章介绍 GitHub API 中一个相对新的部分,这一部分用于描述第三方工具与代码之间的交互。这一章使用 C# 和 .NET GitHub API 库 Nancy 构建一个应用。

如果把按照特定方式组织的仓库推送到 GitHub 中,GitHub 会将其转换成功能完整的博客,基本上相当于 WordPress 网站(当然,没那么复杂)。第 6 章说明仓库的文件结构,如何在 Jekyll 网站中使用 Markdown,如何使用 Liquid 模板引擎提供的循环结构,以及如何使用 Ruby 语言开发一个工具,从 Internet Archive 中把整个网站导出到 Jekyll 网站中。这一章展示如何使用缓存爬取网站。使用 API 或第三方公开信息时缓存很有用。

第 7 章为 Android 操作系统开发一个移动应用。这个应用使用 GitHub API 的 Git Data 部分读取信息,再把信息写入一个 Jekyll 网站仓库。这一章展示如何使用 UI 测试工具 Calabash 为 Android 应用编写用户界面测试,验证 GitHub API 的响应。

Hubot 是一个 JavaScript(NodeJS)聊天机器人,技术人员使用它可以更进一步,由“DevOps”(开发运维)变成“ChatOps”(聊天运维)。第 8 章说明如何使用 GitHub API 的 Activity 和 Pull Requests 部分。此外,还说明如何模拟 GitHub 的通知,以及如何编写可测试的 Hubot 扩展(JavaScript 代码通常难以测试)。我们将把这些串在一起,构建一个机器人,让它自动分配拉取请求审查邀请。

你知道可以把整个“单页应用”托管在 GitHub 中吗?第 9 章说明如何使用 JavaScript 语言构建一个咖啡店信息应用,这个应用的数据库是普通的文件,托管在 GitHub 中。更重要的是,我们将展示如何编写可测试的 JavaScript 应用,说明如何模拟所需的 GitHub API。

本书不会介绍 Organizations API,因为这是 GitHub API 的一小部分,作用简单,只能列出组织,以及修改组织的元数据。学会 GitHub API 的其他部分后,这个不重要的部分自然就会用了。

本书也不会介绍 Users API。你可能觉得这一部分很重要,其实不然,Users API 只提供了一个端点,用于列出用户的信息、添加或删除 SSH 密钥、修改电子邮件地址和修改关注者。

本书没有为工单专开一章。以前,GitHub 把工单和拉取请求放在 API 的同一部分中,不过拉取请求越来越重要,所以 GitHub API 文档把它单独列为一部分。其实,在 GitHub 内部,二者仍然存储在同一个数据库中,而且拉取请求目前还是工单的一种。第 8 章将说明如何使用拉取请求,工单可以比照使用。

Enterprise API 几乎与 GitHub.com 网站的 API 一样,本书没有单写一章介绍企业版 API 的用法,不过在附录 B 中举了几个示例,说明如何使用企业版。本书还为各章使用的不同语言提供了企业版句法,这样书中的各个示例就能在企业版中使用了。

本书通过这些故事讲述如何使用 GitHub 背后的技术,希望借此让你一窥使用 GitHub API 构建应用的开发者是如何思考问题的。

本书的目标读者

本书应该能为已经使用过 Git 或 GitHub 并想提升技能的读者提供有用的信息。没有用过 GitHub 或 Git 的读者应该先读一本入门书。1

1可参考《GitHub 入门与实践》,人民邮电出版社出版。——编者注

你应该至少熟悉一门现代的命令式编程语言。本书不要求你是专家级程序员,但是要有一定的编程经验,至少熟悉一门编程语言。

你应该知道 HTTP 协议的基础知识。GitHub 团队设计 API 时采用了十分标准的 REST 式架构。你应该知道 GET 请求和 POST 请求的区别,至少要知道 HTTP 状态码的意思。

如果熟悉其他 Web API,阅读本书会轻松一些。本书的目标是告诉你如何使用架构、设计和测试良好的 API,构建有趣且强大的工具。如果你没怎么用过 Web API,但是用过其他类型的 API,这样也行。

你将学到什么

本书主要介绍 GitHub 和强大的 GitHub API 提供的功能。不要以为这会限制你对 Git 的使用。假如你是 Android 开发者,使用 Git 管理应用的源码,如果你想在其他地方使用 Git,没问题,本书能打开你的视野,教你 Git 和 GitHub 的高级用法。如果你在自己的项目中已经使用 Git,想在更大的群体中推广 Git,本书会教你 GitHub 引领的“社交编程”风潮。本书为使用其他分布式版本控制系统的软件开发者架起了桥梁,能指引他们转用 Git 和 GitHub 这样的 Web 服务。

资深开发者都喜欢自动化工具。本书提供了一些示例,说明如何把单调的任务转换成可自动和重复执行的过程。这些示例使用多门编程语言编写,让你了解如何与 GitHub API 通信。

为了让本书适合更多的人群阅读,我们没有限定必须使用哪个编辑器或操作系统,很多示例程序都在命令行中执行。如果你不熟悉命令行,本书能让你深入了解它的用法,相信你读完本书之后会发现命令行的强大。如果从 5 岁起你的爸爸就强迫你使用命令行,导致你对它充满恨意,那么通过本书你将重新爱上 bash shell。

如果你能透过 GitHub 提供的技术看到其背后文化和思想的改变,很有可能会发现一种符合现代社会的工作方式。本书集中精力讨论工具本身,工具能做什么则由你自己去探索。

书中各章几乎都有对应的仓库,这些仓库托管在 GitHub 中,供你查看书中讨论的代码。

你可以随意派生这些示例,在自己的项目和工具中使用。

最后,本书会教你编写可测试的 API 后端代码。即便是最有经验的开发者,往往也觉得为代码编写测试是件有挑战的事,何况还要把测试代码写得像文学作品那样高深莫测。测试以 API 为后端的程序尤其艰难。我们要跳出单元测试的思维,以不同的方式思考。为了帮你跨过这道障碍,本书会告诉你怎么让与 GitHub API 交互的代码变得易于测试。

GitHub钟爱的语言

有两门语言与 GitHub 密不可分,你要安装并使用它们才能更好地理解本书的内容。

  • Ruby

    这是一门简单、易读的编程语言,GitHub 公司的创始人在公司早期广泛使用。

  • JavaScript

    这是唯一普遍使用的浏览器端编程语言,随着 NodeJS 的出现,其重要性迈上了新的台阶,甚至与开发 Web 应用的服务器端框架 Ruby on Rails 平起平坐了。独立开发者尤其喜爱该语言。

不可否认,本书的很多读者都已经熟悉 Ruby 或 JavaScript/NodeJS 了,因此正文没有说明它们的基本用法和安装方式,而是放到了附录中。不过,附录也没有介绍这两门语言的句法,我们希望你有使用其他语言的经验,能读懂任何命令式语言编写的代码。书中各章讨论 GitHub API 的方方面面,偶尔会讲解语言细节,但是不管你熟悉哪门语言,书中的代码应该都通俗易懂。附录讨论了这两门语言在 GitHub 发展过程中的作用,还着重说明了一些特殊文件的作用和安装方式。

安装和使用这两门语言不会浪费你的时间,相反,能为你建立坚实的基础,以便深入探索 GitHub API。书中有几章使用 Ruby 或 JavaScript,所以花点时间学习基本句法有助于更好地理解书中的内容。

对操作系统的要求

本书是两位作者在 MacBook Pro 中撰写的。MacBook 中都有 shell(“BASH”),与任何 Linux 设备中的 shell 几乎一样。如果你使用这两个操作系统,各章的代码都能顺利运行。

如果你使用 Windows 设备(或者没有 BASH shell 的操作系统),部分命令和代码示例可能无法运行,需要安装额外的软件才行。

简单的解决方法是使用 VirtualBox 和 Vagrant。VirtualBox 是免费的虚拟系统,能在 x86 硬件中使用。Vagrant 是开发环境管理工具。使用 VirtualBox 和 Vagrant 能快速安装 Linux 虚拟机。如果想安装这两个工具,分别访问 VirtualBox(https://www.virtualbox.org/wiki/Downloads)和 Vagrant(https://www.vagrantup.com/downloads.html)的下载页面。安装好之后,可以使用下述两个命令安装 Ubuntu 虚拟机:

$ vagrant init hashicorp/precise32
$ vagrant up

不适合阅读本书的读者

本书探讨 GitHub API 的用法,没有限定于单一的语言,而是使用多门不同的语言。本书不仅说明了 GitHub 团队设计 API 的方式,还分析了不同编程语言和社区对客户端库的实现方式。我们相信这样能教你更多知识,因此,如果你只对某一门语言感兴趣,想知道如何使用那门语言与 GitHub API 交互,那么这本书就不适合你。

本书努力证明 API 驱动的代码可以测试,而且这么做是有好处的。但是本书不是测试编写手册,不会教你怎么写出最好的测试代码。我们使用多门语言,为的是不加入各个社区对测试框架的争论。我们认识到多数软件项目完全没有测试,因此本书的重点是帮你跨过这只大拦路虎。如果你从未写过测试,那么要转换一下思维方式。我们希望通过具体的示例让你(尤其是没有写过测试的读者)知道如何为使用 API 的代码编写测试。有些章节对应的仓库中有更详细的测试组件,书中的测试大都简略,没有涵盖全部边缘情况。

排版约定

本书使用了下述排版约定。

  • 楷体

    表示新术语。

  • 等宽字体(constant width

    表示程序片段,以及正文中出现的变量、函数名、数据库、数据类型、环境变量、语句和关键字等。

  • 加粗等宽字体(constant width bold

    表示应该由用户输入的命令或其他文本。

  • 斜体等宽字体(Constant width italic

    表示应该替换成用户提供的值,或者由上下文决定的值。

 这个图标表示一般性说明。

 

 这个图标表示警告或提醒。

使用代码示例

补充材料(代码示例、练习等)可以从 https://github.com/xrd/building-tools-with-github 下载。

本书是要帮你完成工作的。一般来说,如果本书提供了示例代码,你可以把它用在你的程序或文档中。除非你使用了很大一部分代码,否则无需联系我们获得许可。比如,用本书的几个代码片段写一个程序就无需获得许可,销售或分发 O'Reilly 图书的示例光盘则需要获得许可;引用本书中的示例代码回答问题无需获得许可,将书中大量的代码放到你的产品文档中则需要获得许可。

我们很希望但并不强制要求你在引用本书内容时加上引用说明。引用说明一般包括书名、作者、出版社和 ISBN。比如:“Building Tools with GitHub by Chris Dawson and Ben Straub (O'Reilly). Copyright 2016 Chris Dawson and Ben Straub, 978-1-491-93350-3.”

如果你觉得自己对示例代码的用法超出了上述许可的范围,欢迎你通过 permissions@oreilly.com 与我们联系。

Safari® Books Online

Safari Books Online(http://www.safaribooksonline.com)是应运而生的数字图书馆。它同时以图书和视频的形式出版世界顶级技术和商务作家的专业作品。技术专家、软件开发人员、Web 设计师、商务人士和创意专家等,在开展调研、解决问题、学习和认证培训时,都将 Safari Books Online 视作获取资料的首选渠道。

对于组织团体、政府机构和个人,Safari Books Online 提供各种产品组合和灵活的定价策略。用户可通过一个功能完备的数据库检索系统访问 O'Reilly Media、Prentice Hall Professional、Addison-Wesley Professional、Microsoft Press、Sams、Que、Peachpit Press、Focal Press、Cisco Press、John Wiley & Sons、Syngress、Morgan Kaufmann、IBM Redbooks、Packt、Adobe Press、FT Press、Apress、Manning、New Riders、McGraw-Hill、Jones & Bartlett、Course Technology 以及其他几十家出版社的上千种图书、培训视频和正式出版之前的书稿。要了解 Safari Books Online 的更多信息,我们网上见。

联系我们

请把对本书的评价和问题发给出版社。

美国:

  O'Reilly Media, Inc.

  1005 Gravenstein Highway North

  Sebastopol, CA 95472

中国:

  北京市西城区西直门南大街 2 号成铭大厦 C 座 807 室(100035)

奥莱利技术咨询(北京)有限公司

O'Reilly 的每一本书都有专属网页,你可以在那儿找到本书的相关信息,包括勘误表、示例代码以及其他信息。本书的网站地址是:

  http://shop.oreilly.com/product/0636920043027.do

对于本书的评论和技术性问题,请发送电子邮件到:bookquestions@oreilly.com

要了解更多 O'Reilly 图书、培训课程、会议和新闻的信息,请访问以下网站:

  http://www.oreilly.com

我们在 Facebook 的地址如下:http://facebook.com/oreilly

请关注我们的 Twitter 动态:http://twitter.com/oreillymedia

我们的 YouTube 视频地址如下:http://www.youtube.com/oreillymedia

致谢

Chris 要感谢他可爱的妻子 Nicole。与我相处和持家的过程中你充满了智慧,真希望我能把这些智慧用到本书中。我的儿子 Roosevelt 活力四射,不断感染着我,即使我已筋疲力尽,也能给我前进的动力。感谢我的女儿 Charlotte,你像微笑的佛像那样让我安宁。感谢我的母亲,谢谢你教我写作,最重要的是,告诉我为什么写作,这是技术圈急需的技能。感谢 Tim O'Brien 邀请我参与这个项目,谢谢你,希望以后还有机会合作。感谢 Bradley

Horowitz,你证明了小小的善举可以产生极大的影响。还要感谢 David J. Groom,虽然我们从未谋面,但是你的建议和鼓舞对这本书极其重要,你的鼓励让我写完了这本书,如此才能与某一天阅读本书的读者结识。

Ben 要感谢他的妻子 Becky,谢谢她一直以来的支持,并在需要的时候督促他。没有她,世界将变得不完美。

电子书

扫描如下二维码,即可购买本书电子版。

目录

  • 版权声明
  • O'Reilly Media, Inc.介绍
  • 前言
  • 第 1 章 开放的 GitHub API
  • 第 2 章 Gist 和 Gist API
  • 第 3 章 GitHub 使用的维基库 Gollum
  • 第 4 章 Python 和 Search API
  • 第 5 章 .NET 和 Commit Status API
  • 第 6 章 Ruby 和 Jekyll
  • 第 7 章 Android 和 Git Data API
  • 第 8 章 CoffeeScript、Hubot 和 Activity API
  • 第 9 章 JavaScript 和 Git Data API
  • 附录 A GitHub 企业版
  • 附录 B GitHub 对 Ruby、NodeJS(和 shell)的利用
  • 作者简介
  • 关于封面