TFS2013

2015年1月 5日 (月)

TFSとGradleの連携7:Ivy環境作成2

年明け1発目は、去年書き残したIvyのリポジトリ作成の続きです。

とりあえず、今回の環境構築で使ったリポジトリダウンロード用のbuild.xmlを置いてみます。

<?xml version="1.0"?>
<!--
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
   regarding copyright ownership.  The ASF licenses this file
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.   
-->
<!--
   2014/12/01 Changed by @__Black
     checkstyle, findbugs用のライブラリをリポジトリに追加するだけの処理に変更
-->

<project name="ivyRepositoryInstall" default="add-repos"  xmlns:ivy="antlib:org.apache.ivy.ant">
<property name="repositoryBase" value="c:/ivy-repository"/>

<property name="originalResolver" value="libraries"/>
<property name="installFolder" value="my-repository"/>

<property name="ivy.cache.dir" value="${repositoryBase}/cache" />
<property name="dest.repo.dir" value="${repositoryBase}/myrepository" />

<property name="ivy.jar.dir" value="${repositoryBase}/.ivy2/jars" />
<property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" />

<!-- =================================
          target: load-ivy         
            this target is not necessary if you put ivy.jar in your ant lib directory
            if you already have ivy 1.4 in your ant lib, you can simply remove this
            target
         ================================= -->
    <target name="load-ivy">
     <path id="ivy.lib.path">
      <pathelement location="${ivy.jar.file}"/>
     </path>
     <taskdef resource="org/apache/ivy/ant/antlib.xml"
               uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
        <ivy:settings id="settingsFile" file="${repositoryBase}/settings/ivysettings-basic.xml"/>
    </target>   


    <target name="add-repos"  depends="load-ivy">
     <ivy:install settingsRef="settingsFile"
      organisation="com.puppycrawl.tools" module="checkstyle" revision="6.1.1"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="junit" module="junit" revision="4.11"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.hamcrest" module="hamcrest-core" revision="1.3"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.jacoco" module="jacoco"  revision="0.7.2.201409121644"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="antlr" module="antlr"  revision="2.7.7"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.antlr" module="antlr4-runtime"  revision="4.3"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="commons-beanutils" module="commons-beanutils-core"  revision="1.8.3"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="commons-cli" module="commons-cli"  revision="1.2"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="com.google.guava" module="guava"  revision="18.0"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.apache.ant" module="ant"  revision="1.7.0"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.abego.treelayout" module="org.abego.treelayout.core"  revision="1.0.1"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.antlr" module="antlr4-annotations"  revision="4.3"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.jacoco" module="org.jacoco.agent"  revision="0.7.2.201409121644"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.jacoco" module="org.jacoco.ant"  revision="0.7.2.201409121644"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.jacoco" module="org.jacoco.report"  revision="0.7.2.201409121644"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.jacoco" module="org.jacoco.core"  revision="0.7.2.201409121644"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />

     <ivy:install settingsRef="settingsFile"
      organisation="org.jacoco" module="org.jacoco.agent"  revision="0.7.1.201405082137"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.jacoco" module="org.jacoco.ant"  revision="0.7.1.201405082137"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.jacoco" module="org.jacoco.report"  revision="0.7.1.201405082137"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />

     <ivy:install settingsRef="settingsFile"
      organisation="org.ow2.asm" module="asm-debug-all"  revision="5.0.3"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />

     <ivy:install settingsRef="settingsFile"
      organisation="org.jacoco" module="org.jacoco.core"  revision="0.7.1.201405082137"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />

     <ivy:install settingsRef="settingsFile"
      organisation="com.google.code.findbugs" module="findbugs" revision="3.0.0"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="com.google.code.findbugs" module="bcel-findbugs" revision="6.0"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="com.google.code.findbugs" module="annotations" revision="3.0.0"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="com.google.code.findbugs" module="jFormatString" revision="3.0.0"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="dom4j" module="dom4j" revision="1.6.1"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="jaxen" module="jaxen" revision="1.1.6"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="org.ow2.asm" module="asm-debug-all" revision="5.0.2"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="commons-lang" module="commons-lang" revision="2.6"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
     <ivy:install settingsRef="settingsFile"
      organisation="xml-apis" module="xml-apis" revision="1.0.b2"
      from="${originalResolver}" to="${installFolder}" overwrite="true" />
    </target>
</project>

GitHubにも同じファイルを置いています。

このファイルを保存して、「Ant -f build.xml」のような形で実行すると、インターネットからダウンロードしてくれます。

ちなみに、このbuild.xmlの内容を追加したいときには、「ivy:install」タスクをコピペで追加し、必要なライブラリ情報に書き換えるだけです。
「必要なライブラリ情報」をどう指定するかですが、「The Central Repository」という便利なサイトが存在します。
Snapcrab_20150101_205551_no0000

ダウンロードしたいライブラリの情報を検索します。
試しに、"Cobertura"を検索してみます。
Snapcrab_20150101_210154_no0000

過去バージョン/関連ライブラリを含め、リポジトリに登録されているものが表示されます。
(Gradle非公式ですが、Cobertura用Pluginも格納されています)

過去バージョンを選択したいときには、「Latest Version」にある"all"をクリックすると、バージョン一覧が表示されますので、そこから選択できます。
Snapcrab_20150101_210213_no0000

取得したい「Version」をクリックすると、詳細情報が表示されます。
Snapcrab_20150101_210220_no0000

左側にある「Dependency Information」にある"Apache Ivy"をクリックすると、依存関係の情報が表示されます。この内容を元に
organisation="xml-apis" module="xml-apis" revision="1.0.b2"
 org="~"→organisation="~"
 name="~"→module="~"
 rev="~"→revision="~"
としてivy:installタスクに指定すればOKです。
今回のcoberturaであれば、こうなります。
     <ivy:install settingsRef="settingsFile"
      organisation="cobertura" module="cobertura" revision="1.9rc1
  from="${originalResolver}" to="${installFolder}" overwrite="true" />

ちなみにですが、build.gradleの「repositories」に"mavenCentral()"と記載し、Mavenのセントラルリポジトリを使用する場合は、先ほどの「Dependency Information」にある"Gradle/Grails"をクリックしたところに表示される
 compile 'cobertura:cobertura:1.9rc1'
を、build.gradleの「dependencies」に追加するだけです。


Gradleを使ってTFSのビルドを実行させるための環境構築について書いてみました。
今回紹介させていただいた「Gradle for TFS Build Automation」は、Java関連での選択肢として以前のBuild Extentionsよりも幅が広がっているのと、GradleがAnt/Mavenのビルドスクリプトをそのまま使用できることもあり、移行もやりやすいと思います。

2014年12月 7日 (日)

TFSとGradleの連携7:Ivy環境作成1

Ivyはライブラリの依存関係を管理するツールです。.NETでいうところのNuGetといった感じでしょうか。
今回の環境を作成するときにちょっと調べてみたのですが、具体的な手順を書いたものが見当たらなかったので、簡単にまとめてみました。

 

プロジェクトサイトはここになります。http://ant.apache.org/ivy/

Apache Projectなんですね)

ちなみに、今回使用したバージョンは2.4.0-rc1です。
前提として、
JDKAntが必要ですので、事前にセットアップしておきます。
環境変数の
PATHに、「[Antインストール先フォルダ]\bin」を追加しておいてください。

インストールですが、プロジェクトサイトにある「Download」からbinaryをダウンロードし、解凍します。解凍先にある「ivy-2.4.0-rc.jar」を、Antインストールフォルダにある「lib」フォルダにコピーするだけです。


次に、ライブラリを格納しておくリポジトリを作成します。

[Ivyインストール先]\src\example\build-a-ivy-repository」フォルダにある「build.xml」を編集します。
→リポジトリの作成先を「
[Ivyインストール先]\src\example\build-a-ivy-repository」から「C:\ivy-repository」に変更します。
変更点は2点です。
1.${basedir}」を「${repositorybase}」に変更する。

2.<project~」の下に、「<property name="repositorybase" value="c:/ivy-repository"/>」を追加する。
Gradle037


変更したら、コマンドプロンプトで[Ivyインストール先]\src\example\build-a-ivy-repository」に移動し、「Ant -f build.xml」を実行すると、「C:\ivy-repository」を作成します。


この状態は「ライブラリを格納する器を作った」だけなので、実際に使用するライブラリをパブリックリポジトリからダウンロードする必要があります。

実は、前に実行したbuild.xmlの中で、「common-lang」はパブリックリポジトリからローカルリポジトリにダウンロードするよう、タスクが定義されています。
Gradle038

次に、このタスクをベースにして、各種ライブラリをダウンロードするbuild.xmlを別に作成します。

TFSとGradleの連携6:build.gradleの内容

今回使用したbuild.gradleの内容について説明です。

まずはGradle用プラグインの宣言です。
これは使用したいプラグインを記述するだけです。
但し、JUnitについてはJavaプラグインに含まれているので指定する必要はありません。
Gradle028


次は各タスクに対する共通的な設定です。
Gradle029

8行目でソースコードの文字コードはUTF-8であること、9~10行目でFindBugsとcheckstyleのチェック内容でエラーが検知されても、ビルドは中断しないことを指定しています。


次はソースコードの格納場所についてです。
Gradle030

今回、ソースコードのフォルダ構成はGradle標準ではなく、Antの構成にしているので、リリース対象のソースコードとテスト用のソースコードのパスを変更します。


次は各種ライブラリのリポジトリに関するものです。
Gradle031

ざっというと
 ・リポジトリはIvyを使用する
 ・リポジトリの公開パスは「http://tfsba01/ivy_repos
 ・ライブラリの保存場所のパスは「artifact ~」のパターンで検索
 ・依存関係の情報は「ivy "~」で指定されたファイルを参照する
という設定です。もう少し詳細な内容は別の機会にしたいと思います。


次は使用するライブラリの指定です。
Gradle032

これは
 ・テスト用ソースのコンパイルでは、junitのバージョン4.0以上とhamcrest-coreの1.0以上を使用する
 ・checkstyle実行時では、checkstyleのバージョン6.1.1を使用する
という内容になっています。
ここで指定したライブラリが別のライブラリを使用する場合は、repositoriesで指定したリポジトリを使用してライブラリ間の依存関係を解決します。


次はJarファイルの作成についてです。
Gradle033

出力するファイル名を指定します。ちなみに、出力先フォルダは「libs」になります。


次はjacoco(テストカバレッジ取得)の動作設定についてです。
Gradle034

最初のブロック(「jacoco {~」)で、使用するバージョンを指定しています。
なぜか、jacocoだけはここで指定します。

2番目のブロック(「test {~)で、jacocoの設定をします。今回は、カバレッジ取得結果は毎回上書き(前回作成したファイルに追記しない)としているだけです。

3番目のブロック(「jacocoTestReport {~)で、レポートに関する設定をします。
「reports {~」のブロックで、xmlレポートとcsvレポートは出力しない設定にしています。
最後の1文は、タスクの依存関係の設定で、「buildタスクが終わったらjacocoTestReportタスクを実行する」ように指定しています。
ちなみに、このビルドスクリプトでは「jacocoTestReport」が最後のタスクになるので、ビルド定義の「Gradle task(s)」に、この「jacocoTestReport」を指定し、全てのタスクを実行するようにしています。


次はcheckstyleに関する設定です。
Gradle035

「checkstyleMain」が、リリース対象のソースコードに対するタスク設定になります。
「configFile=~」で、チェックパラメータファイルの保存先を指定しています。
「doLast {~」で、Antを個別に呼び出し、事前に作成されたxml形式の結果ファイルを元に、「checkstyle-simple.xsl」テンプレートを使用し、html形式のレポートを作成しています。
※「doLast」は、「タスクの一番最後に実行します」といった感じの宣言です。

「checkstyleTest」は、テスト用ソースコードに対するタスク設定ですが、「<< {}」としているので、「何もしない」ということになります。


次は、FIndBugsに対する設定です。
Gradle036

「findbugsMain」は、リリース対象のソースコードに対するタスク設定になります。
「reports {~」で、xml形式のレポートは生成せず、html形式のレポートは生成する指定にしています。
checkstyleのときと違い、レポート生成は何も指定しなくても自動で実行してくれます。

「findbugsTest」は、「checkstyleTest」同様テスト用ソースコードに対するタスク設定ですが、「<< {}」としているので、「何もしない」ということになります。


概要としては以上になります。各プラグインの詳細については、Gradleのドキュメントページにありますので、そちらを参照してください。


次は、ライブラリのリポジトリとして今回使用した「Ivy」についてです。

TFSとGradleの連携5:TFSビルド定義作成

TFSのチームプロジェクトに対して、ビルド定義を作成します。

Build Extensionの時と違い、EclipseTEEではなくTeam Explorerから作成します。

Gradle連携のために「プロセス」タブの部分を変更します。

「ビルドプロセステンプレート」の右端にある「詳細の表示」をクリックすると、プロセステンプレートの詳細情報が展開されます。

Gradle006_2

テンプレート選択の右にある「新規作成」をクリックすると、ビルドプロセステンプレートの参照画面が表示されます。
Gradle007_2

ここで連携2で
Gitリポジトリにコミットした「GradleGitTemplate.12.xaml」を指定します。チームプロジェクト/リポジトリ名/分岐まではコンボボックスで選択するだけです。リポジトリのパスは、ローカルのGitリポジトリに保存しているファイルを指定します。

Gradle008

Gradle009

Gradle010

プロセステンプレートの読み込みが完了すると、下側のビルドプロセスパラメータが変わります。
Gradle011

Gradle012

Gradle013

Gradle用パラメータやAzure連携用パラメータがいろいろありますが、今回使用するのは「2. Gradle Build」の部分だけです。

以下の設定を行います。

 1. Gradle Command

  →'gradle'

 2. Gradle Build Script

  →連携4で作ったビルドスクリプトファイル名(build.gradle

 3. Gradle Task(s)

  →実行したいタスク名。複数指定することも可能です。

   今回は、一番最後に実行するタスク「jacocoTestReport」を指定しています。

 

その他のタブの項目は、通常のTFSビルド定義と同じです。

 

なお、プロセステンプレートの読み込み後、ビルドプロセスパラメータにこんなエラーが出る場合があります。
Gradle014

このときは、ビルドコントローラーに指定するカスタムアセンブリのパス指定がちゃんとできていないので、ビルドコントローラーのカスタムアセンブリのパス指定を再度設定後、ビルドサービスの再起動を行い、ビルド定義を再度作成するか、一度保存したあと1回定義画面を閉じて開きなおす必要があります。
→「最新の情報に更新」ボタンがありますが、これはビルドプロセスファイルを最新化するだけで、カスタムアセンブリのロードはしてくれません。カスタムアセンブリのロードはビルド定義画面を開く時だけです。

 

基本的にはここまで設定すればGradleでのビルドが実行できます。

今回のbuild.gradleで、「repositories」に対して「mavenCentral()」を追加し、パブリックリポジトリを参照するようにしてしまえば、このままでも動作します。サンプルのビルドスクリプトに「mavenCenter()」がないのは、ローカルリポジトリを使用した動作を確認したかったので、パブリックリポジトリを参照させたくなかったからです。

 

次からは、build.gradleの内容を少し説明します。

TFSとGradleの連携4:build.gradle作成

Antでのbuild.xmlにあたるGraldeのビルドスクリプト(build.gralde)の作成です。

具体的な作り方はGradleのサイトの内容で大半は確認できますので、ここでは完成版を置いておきます。

def defaultEncoding = 'UTF-8'

apply plugin: 'java'
apply plugin: 'findbugs'
apply plugin: 'checkstyle'
apply plugin: 'jacoco'

[compileJava, compileTestJava]*.options*.encoding = defaultEncoding
[findbugsMain, findbugsTest]*.ignoreFailures = true
[checkstyleMain, checkstyleTest]*.ignoreFailures = true

sourceSets {
  main.java.srcDir 'src'
  test.java.srcDir 'testsrc'
}

repositories {
  ivy {
    url "http://tfsba01/ivy_repos"
    layout "pattern", {
      artifact "[organisation]/[module]/[revision]/jars/[artifact]-[revision].[ext]"
      artifact "[organisation]/[module]/[revision]/bundles/[artifact]-[revision].[ext]"
      ivy "[organisation]/[module]/[revision]/ivys/ivy-[revision].xml"
    }
  }
}

dependencies {
  testCompile group: 'junit', name: 'junit', version: '4.+'
  testCompile group: 'org.hamcrest', name: 'hamcrest-core', version: '1.+'
  checkstyle group: 'com.puppycrawl.tools', name: 'checkstyle', version: '6.1.1'
}

jar {
  archiveName = 'GradleSample01.jar'
}

checkstyleMain {
  configFile = file('./DefinitionFiles/CheckStyle/EditChecks1.xml')

  doLast {
    ant.xslt(in: checkstyleMain.reports.xml.destination,
             style: new File('DefinitionFiles/CheckStyle/checkstyle-simple.xsl'),
             out: new File(checkstyleMain.reports.xml.destination.parent, 'main.html'))
  }
}

jacoco {
  toolVersion = "0.7.2.201409121644"
}

jacocoTestReport {
  reports {
    xml.enabled false
    csv.enabled false
  }
}
jacocoTestReport.dependsOn build

test {
  jacoco {
    append = false
  }
}

findbugsMain {
  reports {
    xml.enabled = false
    html.enabled = true
  }
}

task checkstyleTest(overwrite: true) << {}

task findbugsTest(overwrite: true) << {}


大雑把にいうと、
 ・ライブラリのリポジトリを指定
 ・pluginの指定
 ・Taskのプロパティを指定
をすれば動かせるイメージです。
各種プラグインが公開されているので、やりたいなと思ったことは基本できそうです。
内容としては、以前に書いた「TFSでJavaのビルド環境構築 in 2012 その1:概要」とほぼ同じ内容ですが、Gradleのほうがすっきりしている感じです。

次は、ビルド定義の作成です。

TFSとGradleの連携3:Gradle環境作成

Gradle環境の作成はいたって簡単です。
まずはJava JDKをインストールします。
自分の環境ではJava 1.8ではうまく動かなかったものがあるので、今回はJava SE 1.7を使ってます。
インストールしたら、環境変数「JAVA_HOME」を作成し、インストール先フォルダを設定します。

次にGradleのインストールです。
http://www.gradle.org/ から右端にあるダウンロードボタンを押すと最新版のGradleがダウンロードできます。(確認している最中に2.2から2.2.1にバージョンがUpしてました(^-^; )
Gradle005


ZIP形式を解凍したと、環境変数「GRADLE_HOME」に解凍先のフォルダを指定すれば終了です。
とりあえずコマンドプロンプトを起動し、「gradle -v」を実行してバージョン情報が表示されればちゃんと動きます。
Gradle027



次はビルドスクリプトの作成です。

TFSとGradleの連携2:TFS-Gradle-pluginのインストール

TFSGradleの連携1:概要」 の続きです。

まずはTFSのチームプロジェクトを作成しておきます。
プロセステンプレートは何でもかまいませんが、バージョン管理システムはGitを選択してください。SharePointサイトも不要です。

チームプロジェクトができたら、Eclipse上でJavaプロジェクトを作成し、ソースファイルなどをコミット&プッシュします。
Gradle001


今回は「TFSでJavaのビルド環境構築 in 2012」で使ったEclipseのJavaプロジェクトを使用しています。
前回からの変更は、
 ・checkstyleのチェック内容を定義したファイルを「/DefinitionFiles/CheckStyle/EditChecks1.xml」としてソース管理に追加
 ・checkstyleのレポートテンプレートも「/DefinitionFiles/CheckStyle」に追加
しています。
(「/BuildGradle」はGradle関連なので、後で説明します)

Gradleに慣れている方は気が付かれていると思いますが、Gradle標準のフォルダ構成ではなく、今までAntで使ってきたフォルダ構成のままにしています。←Antからの移行を考えてます。

次に、TFS-Gradle-pluginをGitHubからクローン、もしくはZIPでダウンロードしてきます。
クローンしたファイルの中で、「/GradleGitTemplate.12.xaml」と「/BuildTemplate/BuildProcess/bin/BuildProcess.dll」の2つをチームプロジェクトの「/BuildGradle」に追加します。ちなみに、「BuildProcess.dll」だけがGradleビルド用のプログラムで、「GradleGitTemplate.12.xaml」はビルドプロセステンプレートファイルです。
インストールはこれだけです。

最後に、TFSのビルドコントローラーに対して、「buildprocess.dll」を参照するように設定変更します。
Gradle002

Gradle003

Gradle004

設定変更した後は、必ずビルドサービスの再起動をします。


次はビルドエージェント上にGradle環境を作成します。

TFSとGradleの連携1:概要

またもや1ヶ月以上間が空いてしまいました。(^-^;

突然ですが、無意識にこの本を購入していました。
○Gradle徹底入門
51ev2zpcwll__aa160_


AntやMavenの後釜と言われているGradleです。Androidのビルド環境として有名(らしい)ですね。

斜め読みしたあと、「TFSと連携できるんだっけ?」と思って検索してみたら、こんなところにこんなものがありました。
Microsoft Open TechnologiesのGradleプロジェクトサイト
Snapcrab_20141204_212741_no0000

ここの「News」タブにある「Using Gradle for TFS Build Automation」に飛ぶと、TFSとGradleを連携についてのページがあり、ページ下部に連携機能のGitHubサイトへのリンクがあります。

GitHub:TFS-Gradle-plugin
Snapcrab_20141204_214303_no0000

こいつを導入すれば、TFSとGradleの連携ができるそうです。しかも、Azure Storageへの配置・Azure上のWindows VM/Linux VMへのデプロイまで対応しているようです。

自分は実際に使ってみないとわからないタチなので、以前TFS Build Extensionでやってみた内容で環境構築してみました。(なので、Azure連携はまだです)

今回の環境はこんな感じです。
○ADサーバ
 Windows Server 2012 R2
○TFSサーバ
 Windows Server 2012 R2
 Team Foundation Server 2013 Update 4
○Eclipse開発環境
 Windows 8.1 Pro with Update
 Eclipse 4.4(Luna)
 Team Explorer Everywhere 12.0.2
 JDK SE 7
○TFS ビルドコントローラー兼エージェント
 Windows 8.1 Pro with Update
 IIS 6.2
 Team Foundation Server 2013 Update 4 ※ビルドコントローラー分だけインストール
 Team Explorer
 JDK SE 7
 Gradle 2.2
 JUnit 4.11 + hamcrest-core-1.3
 checkstyle 6.1
 findbugs 3.0.0
 jacoco 0.7.2
 Apache Ant 1.9.4
 Apache Ivy 2.4.0 rc1
 ※Gradleから参照するJava関連のライブラリのリポジトリとして、ビルドコントローラー内にローカルでApache Ivy環境も構築しています。

Antの時と結果は変わりませんが、実際にビルドを実行したときのスクリーンショットです。
○ビルド結果
Gradle015

○出力先フォルダ
Gradle016

○checkstyleのレポート
Gradle017

○FindBugsのレポート
Gradle018

○jacocoのレポート
Gradle019

○JUnitのレポート
Gradle020



次はTFS-Gradle-pluginのインストールについてです。

2014年10月11日 (土)

作業項目にリンクした修正ファイルの一覧を取得する:変更セットの取得

今回は作業項目から変更セットを取得するところです。
Tfs007_3

いろいろ処理が詰まっているので、番号を振ってみました。
また、一画面で入りきらなかったので、前半/後半に分けました。

①バージョン管理オブジェクトを取得しています。また、ファイル情報を格納するためのコレクションを作成しています。

②WIQLで取得したWorkItemCollectionからforeachでWorkItemを取り出します。

③作業項目に関連づけれらているリンクを取得します。foreachが使えなかった(と思います)ので、forで回しています。

④作業項目にはいろんな情報をリンクすることができますが、今回は変更セットへのリンクだけを取り出したいので、LinkクラスのArtifactLinkTypeプロパティを使い、リンクの種類が'Fixed in Changeset'でなければ処理対象外としています。

⑤リンクの内容から変更セットにアクセスします。
 リンク内容としてセットされているのが「vstfs:///VersionControl/Changeset/18」という形式になっています。最後の数字部分が変更セットのIDになりますので、これを抽出します。
 抽出した変更セットIDを使って、バージョン管理オブジェクトから変更セットの内容を取得します。

⑥変更セットのコレクションをループで回して変更対象のファイル一覧を作成します。

後半部分です。
Tfs008_2
⑦変更セットには、分岐(ブランチ)/ロックなどの修正以外の情報も格納されているので、ChangeクラスのChangeTypeを参照して修正対象のみを抽出するようにしています。←IsCollectChangeType()
 ChangeTypeの詳細は「ChangeType Enumeration」にあります。
 また、フォルダの変更情報も変更セットに格納されているので、Change.Item.ItemTypeを参照してファイルのみを抽出対象にしています。←IsCollectItemType()

⑧取得したファイルがファイル一覧のコレクションになければ追加、存在すればChangeTypeの内容を追加しています。

基本的にはTFSの標準機能で大体のことは対処できるのですが、こんな感じでTFSから情報を取得するコマンドが簡単に作れますので、自分の開発チームによっては「かゆいところに手が届く」感じのツールを作ることもできます。
今回のネタは自分が欲しかったので作ってみました。

実際に仕事で使うのはいつだろう・・・w

作業項目にリンクした修正ファイルの一覧を取得する:接続・作業項目の取得

接続の前にmain()部分です。
Tfs004

関連処理はTfsWorkItemクラスに入れています。
GetWorkItemsFromId()で作業項目IDから作業項目のリストを取得し、GetChangeFileList()で作業項目内の変更セットからファイル一覧を取得しています。
後は、取得したファイル一覧を単純にコンソールに出力しているだけです。

まずはTFSへの接続です。
Tfs005

チームプロジェクトコレクションのURLを引数にして、Microsoft.TeamFoundation.Client.TfsTeamProjectCollection()を呼び出すだけです。これだとOSユーザでTFSに接続しますので、OSユーザと異なるユーザ情報でTFSに接続したい場合はCredentialsを引数に追加してください。
ここでは、作業項目管理オブジェクトであるWorkItemStoreも取得しています。

次に作業項目の取得です。
Tfs006

WIQL(Work Item Query Language)というSQLに似たクエリ言語を使用して作業項目のリストを取得します。詳細については、MSDNの「バグ、タスク、およびその他の作業項目の照会」で確認してみてください。但し、項目名称は英語版を元に記載されているため、日本語版のTFSでは「フィールドがない」と怒られてしまいます。項目名称は画面上で表示される名称がそのまま使用可能なのですが、コマンドで確認することも可能です。それについては別の機会に説明したいと思います。

今回は一旦WorkItemsから作業項目自体を取得し、作業項目からリンクをたどるようにしています。ちなみですが、リンクを取得するだけであれば、「From WorkItemLinks」で取得可能なのです。
Queryメソッドの戻りはWorkItemCollectionですので、ループでぶん回せば作業項目を取得できます。

次はforeachでぶん回して変更セットから変更ファイルのリストを取得するところです。