在本章中,我们将更详细地解释如何利用Iceberg将你的项目发布到GitHub上。Iceberg是一款支持Git仓库操作的工具和库;它的功能不仅仅局限于文件的保存与发布。随后,我们将简要介绍如何确保你或其他开发者能够加载你的代码,而无需理解其内部依赖关系。
我们将不会解释诸如提交(commit)、推送/拉取(push/pull)、合并(merging)或克隆(cloning)等基础概念,这些内容请参考Git教程。阅读本章的一个强有力前提是,你必须能够通过命令行将代码发布到你的Git托管服务。如果你不能做到这一点,请不要指望Iceberg能为你解决这个问题。如果你在SSH配置上遇到问题(这是使用GitHub推送的默认方式),你可以选择使用HTTPS替代,或者阅读《使用Iceberg管理你的代码》这本小册子,你可以在http://books.pharo.org 找到它。让我们开始吧。
7.1 对于急性子
如果你不想阅读以下所有内容,并且感到相当自信,这里是如何发布你的代码的简要步骤:
在GitHub或任何基于Git的平台上创建一个项目。
[可选] 配置Iceberg以使用自定义的SSH密钥。
在Iceberg中添加一个项目。
- [可选(但强烈推荐)] 在克隆的仓库中,在你的文件系统中创建一个名为
src
的目录。这是一个良好的惯例。
- [可选(但强烈推荐)] 在克隆的仓库中,在你的文件系统中创建一个名为
在Iceberg中,打开你的项目并添加你的包。
提交你的项目。
[可选] 为你的项目添加一个基线(baseline)。
将你的更改推送到远程仓库。
至此,你已经完成了。不过,现在让我们更详细地解释这些步骤。
7.2 基本架构
由于Git是分布式版本控制系统,因此需要存储库的本地克隆和工作副本。您的工作副本和本地存储库通常在您的机器上。您对工作副本的更改将提交到本地存储库,然后再推送到远程存储库(图7-1)。Pharo使这种情况稍微有点复杂,这就是我们使用Iceberg的原因。简而言之,Pharo的类和方法是动态修改的对象。修改类源代码时,Git工作副本不会自动修改。这就好像您有两个工作副本:映像中的对象副本和基于git文件的副本。Iceberg在这里帮助您同步和管理它们。
在GitHub上新建一个项目
在GitHub上创建项目如图7-2所示。顺序并不重要,但是当您向Iceberg添加存储库时,您将使用不同的选项,稍后我们将介绍这一点。
[可选]SSH设定:告诉Iceberg你的key
为了能够提交到Git项目,您应该使用HTTPS,或者需要在系统中设置有效的SSH凭证。如果你确实使用SSH(默认方式),你需要确保这些密钥对你的GitHub帐户可用,并且shell添加它们以便与服务器进行更顺畅的通信。
进入设置,搜索“Use custom SSH keys”并输入数据,如图7-3所示。
或者,您可以在Playground中执行以下表达式,或将它们添加到您的Pharo系统首选项文件:
IceCredentialsProvider useCustomSsh: true.
IceCredentialsProvider sshCredentials
publicKey: 'path\to\ssh\id_rsa.pub';
privateKey: 'path\to\ssh\id_rsa'
注意 如果您有一个非默认密钥文件,也可以使用此方法。您只需要将id_rsa替换为您的文件名。
现在,我们已经准备好来查看一下Iceberg这个Pharo中管理Git的工具。
7.3 Iceberg存储库浏览器
Iceberg的顶层窗格如图7-4所示。它表明,目前还没有定义或加载任何项目。它显示了Pharo项目(以及其他项目),但显示为“本地存储库丢失”,表明它无法为其找到本地存储库。
首先,不要担心Pharo的存储库缺失:只有当您想为Pharo语言项目做贡献时才需要它,我们非常欢迎您这样做,但是现在先让我接着完成本章的内容。现在的情况是:Pharo系统不知道它的类对应的Git存储库在哪里。但是Pharo在没有本地存储库的情况下也能正常工作;您仍然可以浏览系统类和方法,并进行更改,因为Pharo在映像中有自己的内部源代码管理。这个警告只是表明,如果您想使用Git对Pharo系统代码进行版本化,那么您应该告诉系统本地机器上Pharo的本地克隆和工作副本位于哪里。但如果您不打算修改和共享Pharo系统代码,则不必担心。
7.4 在Iceberg中新增一个项目
第一步是添加一个项目到Iceberg中:
- 点击Iceberg主窗口右侧的+按钮
- 选择项目的源。在我们的例子中,因为你还没有克隆你的项目,所以选择GitHub选项。
注意,你可以使用SSH(图7-5)或者HTTPS(图7-6)
图7-5
图7-6
这会要求Iceberg克隆我们刚刚在GitHub上创建的存储库。我们指定所有者、项目以及Git本地克隆和工作副本将位于磁盘上的物理位置。
现在Iceberg已将您的项目添加到其托管项目列表中,并将一个空的存储库克隆到您的磁盘中。您将看到项目的状态,如图7-7所示。以下是你所看到的情况:
MyCoolProjectWithPharo
有一个星号,是绿色的。这通常意味着你还没有提交更改,but may also happen in unrelated edge cases like this one.现在不用担心这个。- 项目目前的状态是“No Project Found”,这是更重要的。这很正常,因为项目是空的。Iceberg无法找到元数据。我们很快就会解决这个问题。
稍后,当您提交了对项目的更改,并希望通过再次克隆它来将其加载到另一个映像中时,您将看到Iceberg只会报告项目未加载,如图7-8所示。
救援修复
Iceberg是一个智能的工具,可以帮助您解决在使用Git时可能遇到的问题。作为一般性原则,每当您获得带有红色文本的状态(例如“No Project Found”或“Detached Working Copy”)时,您应该要求Iceberg使用Repair命令来修复它。
Iceberg不能自动解决所有情况,但它会提出并解释可能的修复行动。这些行为从最可能是正确的到最不可能是正确的。每个动作都提供了一个解释和使用它的结果。阅读它们总是一个好主意。以正确的方式设置存储库可以使您非常不容易丢失Iceberg和Pharo的任何代码片段,因为Pharo包含自己的代码副本。非常努力…但也不是不可能。所以要注意!
创建项目元信息
Iceberg报告它无法找到项目,因为缺少了一些元数据,比如代码的文件编码,以及存储库中的示例位置。当我们激活repair命令,我们得到图7-9的结果。它显示了创建项目元数据操作及其解释。
当您选择创建项目元数据(Create project metadata)时,Iceberg会向您显示项目的文件系统以及存储库格式,如图7-10所示。Tonel是Pharo项目的首选格式:它被设计为跨文件系统工作,所以不要随意改变它,除非你知道自己在干什么!
在接受更改之前,向存储库添加一个源文件夹是一个好主意, 按照惯例,通常是一个名为src
的文件夹。通过点击"+"图标来完成。系统将提示您指定存放代码的文件夹,如图7-11所示。创建src
文件夹后,不要忘记选择它。Iceberg将显示您的项目的确切结构,如图7-12所示。
在接受项目细节后,Iceberg会显示您将提交的文件,如图7-13所示。
一旦您提交了元数据,Iceberg会显示您的项目已经修复,但还没有被加载,如图7-8所示。这很正常,因为我们还没有向项目添加任何包。如果您愿意,此时仍然可以将更改推送到远程存储库。
您的本地存储库已经准备好了,让我们转到下一部分。
7.5 使用“Working copy”浏览器添加并提交包
一旦您的项目包含了Iceberg元数据,Iceberg将能够轻松地管理它。双击项目,打开项目的Working copy浏览器。它列出了组成项目的所有包。现在你什么都没有。使用“+”按钮添加包,如图7-14所示。
使用绿色和给包名前面加上星号,Iceberg再次提示你的包包含未提交的更改,如图7-15所示。
提交更改
使用Commit按钮将更改提交到本地存储库,如图7-16所示。Iceberg允许您选择希望提交的已更改实体。这可能不是必要的,但这是一个重要的功能。Iceberg通过删除星号和改变颜色来显示提交操作的结果。它现在显示映像中的代码与您的本地存储库同步,如图7-17所示。如果需要,可以多次提交。
将你的更改推送到远程
使用Push按钮将更改从本地目录发布到远程存储库。如果使用HTTPS,可能会提示您输入密码。
当您推送更改时,Iceberg将显示所有等待发布的提交,并将它们推送到远程存储库,如图7-18所示。
现在你基本上完成了。你已经知道了使用GitHub或者其他远程Git服务管理代码的基本方面。Iceberg被设计来指导你,所以请听从它,除非你真的知道你在做什么。你现在已经准备好使用GitHub和其他人提供的服务来提高你的代码控制和质量!
7.6 如果我没有创建远程存储库会怎样?
我们首先在GitHub上创建一个远程存储库。然后我们要求Iceberg通过从GitHub克隆它来添加一个项目。那么我们如何反过来做呢,在没有预先存在的存储库的情况下发布我们的本地项目。这其实很简单,让我们试一试。
创建一个新存储库
当您添加一个新的存储库时,请使用如图7-19所示的"New repository"选项。
添加一个远端存储库
如果希望提交到远程存储库,则必须使用Repository浏览器添加它。您可以通过相关的菜单项或图标访问此浏览器。Repository浏览器允许您访问与项目关联的Git存储库:您可以访问分支、管理它们,还可以添加或删除远程存储库。图7-20显示了我们项目中的Repository浏览器。
按下Add remote按钮添加一个远端存储库;您只需要填写可以在远程Git项目中找到的信息。图7-21为使用SSH的示例项目,图7-22为使用HTTPS的示例项目。
推送到远端
现在您可以使用push按钮将更改和版本推送到远程存储库。按下按钮后,可以看到您有一个远端存储库,如图7-23所示。
7.7 配置你的项目
对代码进行版本控制只是确保您和其他开发人员可以重新加载代码的第一部分。现在我们将描述如何定义Baseline:您将使用一个项目映射来定义项目内的依赖关系以及它对其他项目的依赖关系。
定义一个BaselineOf
Baseline是对项目架构的描述。你表达了你的包和其他项目之间的依赖关系,确保所有依赖的项目都被加载了,而用户不必理解它们或它们之间的链接。
Baseline为BaselineOf
的子类,并且打包在名为BaselineOfXXX
的包中(其中XXX
是项目的名称)。因此,如果没有依赖项的话,你可以拥有如此简单的baseline定义:
BaselineOf subclass: #BaselinfOfMyCollProjectWithPharo
...
package: 'BaselineOfMyCollProjectWithPharo'
BaselineOfMyCollProjectWithPharo >> baseline: spec
<baseline>
spec
for: #common
do: [ spec package: 'MyCollProjectWithPharo' ]
一旦您定义了baseline,您就应该使用如上所述的工作副本浏览器将它的包添加到您的项目中。您应该会得到类似图7-24的结果。
现在,提交它将你的更改推送到远端。
关于使用Baseline可以实现的更多信息,请访问Pharo维基: https://github.com/pharo-open-documentation/pharo-wiki/
7.8 加载已存在的存储库
有几种方法可以将版本化的代码加载到新的Pharo映像中:
使用Iceberg载入Baseline
要以交互方式加载项目,可以使用Iceberg中的Metacello菜单项,单击存储库的名称即可看到该菜单项。它允许您加载Baseline并执行它来加载项目的包。这样,您就可以确保加载了所有必需的子项目。
手工加载
某些时候,您可能需要直接加载给定的包,或者您的项目可能没有定义Baseline。您可以使用Iceberg加载特定的包,如下所示:
按照我们前面的解释,使用Iceberg添加项目。
在存储库浏览器中双击项目,打开“Working Copy”浏览器。
选择一个包并手动加载它。
脚本加载
第二种方法是使用Metacello脚本:
Metacello new
baseline: 'MyCollProjectWithPharo';
repository: 'github://Ducasse/MyCollProjectWithPharo/src';
load
对于具有元数据的项目,如我们刚刚创建的项目,这就是您要做的全部工作。请注意,我们不仅给出了GitHub路径,还给出了代码文件夹(本例中为src)。
7.9 退一步...
在Pharo中处理由Iceberg管理的包时,您需要了解,您不是在直接编辑本地工作副本:您实际上是在修改Pharo环境中表示为类和方法的对象。因此,就如同您有两个工作副本:运行的Pharo映像和磁盘上的Git工作副本。
当您使用Git在Pharo和Iceberg之外管理项目时,例如使用Git命令行工具,您需要记住Pharo映像中的代码和工作副本中的代码(以及本地克隆中的代码)。要更新映像,首先必须更新Git工作副本,然后将代码从工作副本加载到映像。要保存代码,首先必须将映像中的代码另存为文件,然后将它们添加到Git工作副本中,最后将它们提交给克隆。
Iceberg的美丽之处在于,它为你透明地管理着这一切。两个工作副本之间的所有繁琐同步都在幕后完成。
Iceberg的系统架构如下:
您的代码位于Pharo映像中;
Pharo充当工作副本(它包含本地Git存储库的内容);
Iceberg负责将您的代码发布到Git工作副本和Git本地存储库;
Iceberg负责管理将代码发布到远端存储库;
Iceberg负责管理您的映像与Git本地存储库、Git远程存储库和Git工作副本的重新同步。
7.10 结论
本章介绍了如何正确发布和打包代码的最重要方面。这将帮助您在其他映像中重新加载它,以及与其他Pharo开发人员进行协作。