Bitbucket - Groovy Pre-receive Hook

时间:2016-01-07 21:26:23

标签: groovy bitbucket

我正在尝试了解以下代码段following site

<% refChanges.getCommits(repository).each { commit -> %>
    - ${commit.author.name} | ${commit.displayId} | ${commit.message} | ${commit.authorTimestamp}
<% } %>

该脚本使用的是getCommits方法,但是当我查看the documentation for the RefChange interface时,我看不到任何此类方法。

我认为自己是一名专业的Java开发人员,但我在Groovy中没有可行的知识,因此我认为我误解了Groovy或BitBucket文档(或两者)。

1 个答案:

答案 0 :(得分:2)

在Groovy中,可以通过meta-programming在运行时向类或接口添加方法。由于RefChange接口不包含getCommits(),因此必须在事后添加方法。根据他们的示例代码,看起来他们正在使用元类。

getCommits()在哪里?

例如,在Groovy中,Collection接口获取方法findAll()(以及许多其他方法)。我可以证实这一点如下:

assert Collection.metaClass.metaMethods*.name.contains('findAll') == true

上面的代码获取了所有元方法的名称,然后使用contains()查看是否找到了匹配项。您可以用类似的方式为getCommits()确认相同内容:

assert Collection.metaClass.metaMethods*.name.contains('getCommits') == true

请注意,我指定的是Collection而不是RefChange,因为refChangesCollection的{​​{1}}。所以我认为Atlasssian将RefChange加入getCommits()作为一种便利方法。

它是如何工作的?

要了解要采取的措施,我会删除模板代码:

Collection
  1. refChanges.getCommits(repository).each { commit -> "${commit.author.name} | ${commit.displayId} | ${commit.message} | ${commit.authorTimestamp}" } 返回getCommits() Collection。{/ li>
  2. Object.each(Closure)由Groovy GDK添加(是的,进入Object类),它反复调用com.atlassian.bitbucket.commit.Commit;每次都使用Closure
  3. 元素
  4. 虽然在示例代码中不明显,但Collection中的行是GString。基本上,each(Closure)中的表达式被评估,整个事物被连接成${...}