您的位置:首页 > 编程语言 > Java开发

hudson(jenkins) plugin

2011-09-07 15:03 357 查看
CI(継続的インテグレーション)ツールの一つである Hudson は以下のような点で個人的に気に入っている。
インストール(実行環境の構築や設定など)が容易
プラグインによる機能追加が容易
ビルド結果等のファイル構成が非常にシンプル
REST 的なリモートアクセス API が用意(XMLJSON

Apache Tomcat の
webapps ディレクトリダウンロードした hudson.war
ファイルを配置してTomcat を起動するだけで使えるし、hudson の起動時に作成された
.hudson ディレクトリ
plugins ディレクトリプラグイン(.hpi ファイル)を配置して Tomcat を再起動するだけでプラグインが使えるようになるなど、手間がかからず手軽に使い始められる。

今回は Hudson プラグインの自作に興味がわいたので、Extend
Hudsonのサイトを参考にして実際に作ってみた。


事前準備

まず、hudson のプラグイン作成には Maven を使用するため、Apache
Maven 2 をダウンロードインストールしておく。(今回は Maven 2.0.9
を使用)

次に、下記 URL から pom.xml ファイルをダウンロードし、適当なディレクトリに配置する。
https://hudson.dev.java.net/source/browse/*checkout*/hudson/trunk/hudson/tools/bootstrap/pom.xml

mvn package を実行し hudson プラグイン作成に必要なライブラリを Maven のローカルリポジトリダウンロードする。

接着在CMD中输入 

Java代码 

 
1. mvn hpi:create   

之后会问你一些如groupId和artifactId之类的问题,按照需要来填写就好了。 

完成后计算机会自动的创建了一个项目,里面有一些模板代码,可供你学习如何开始写一个Hudson的插件,后面的代码全部来自模版代码。如果你需要在Eclipse里编辑插件可以执行 

Java代码 

 
1. mvn -DdownloadSources=true eclipse:eclipse   

然后你就可以在Eclipse中导入这个项目并开始开发了。

>mvn package


mvn package が正常に終了すれば、pom.xml ファイルは不要なため削除。


プラグイン作成プロジェクトの作成

hudson プラグインを作成するためのディレクトリを用意、その中で以下のコマンドを実行して、hudson のプラグイン作成用プロジェクトを作成する。
>mvn org.jvnet.hudson.tools:maven-hpi-plugin:1.20:create


作成処理の最後の方で、groupId(パッケージ名)と artifactId(プロジェクト名)の入力が促されるので適当に入力する。

なお、上記コマンドの 1.20 の部分は、Maven2 のローカルリポジトリライブラリ内容に合わせて適時修正することになると思う。

Eclipse にインポートする場合


Eclipse で開発を実施する場合、以下のコマンドを実行して Eclipse 用のプロジェクトファイル(.project
や .classpath)を生成し、Eclipse にインポートする。
>mvn -DdownloadSources=true eclipse:eclipse


.classpath ファイルでは、Maven2 のローカルリポジトリの場所を環境変数 M2_REPO
で指定しているため、eclipse の環境変数
M2_REPO が未設定であれば、.m2/repository ディレクトリへのパスを設定する。


サンプルプラグインの構成

create で生成されたプロジェクトには、既に HelloWorldBuilder というサンプルプラグインが生成されており、これを
mvn package して .hudson/plugins に配置すればプラグインとして動作するようになっているので、プラグイン作成の参考になると思う。。

ちなみに、主なファイル構成は以下の通り。
pom.xml ファイル
src/main/java/パッケージ名 ディレクトリ
HelloWorldBuilder.java ファイル : プラグインの実装クラス、Builder 抽象クラスを継承している
PluginImpl.java ファイル : プラグインのエントリーポイントを実装するクラス(1プラグイン
1クラス必要)

src/main/resources/パッケージ名/HelloWorldBuilder ディレクトリ
global.jelly ファイル : 「Hudsonの管理」->「システムの設定」で表示・設定する内容を記述
config.jelly ファイル : プロジェクト毎の「設定」で表示・設定する内容を記述


拡張ポイント(Extension points)

プラグインは拡張ポイントを使って実装するような仕組みになっており、以下のような拡張ポイントが用意されている。
Publisher
プロジェクト「設定」の「ビルド後の処理」で選択対象になる

Builder
プロジェクト「設定」の「ビルド」で選択対象になる

SCM
プロジェクト「設定」の「ソースコード管理システム」で選択対象になる

Trigger
プロジェクト「設定」の「ビルド・トリガ」で選択対象になる

Action
ビルド結果の画面に表示される(左メニューに追加されたりする)

Job
MavenReporter
BuildWrapper


Publisher 拡張ポイントを使ったプラグインの作成

ここから、本格的にプラグインを作成していくことにするが、サンプルプラグイン
HelloWorldBuilder を改造するだけでは面白みに欠けるので、別の拡張ポイント Publisher を使ったプラグインを作成していくことにする。

とりあえず、多少の実用性を考慮して以下のような機能を実装することにした。
JavaNCSS によるソフトウェアメトリクスの測定結果(XMLファイル)を Hudson 上で表示

なお、今回は表示メッセージなどの国際化は考慮しない事とする。

ちなみに、ソフトウェアメトリクスのツールとして
JavaNCSS を選んだ理由は、Maven2 用のプラグインが用意されていたからで、下記のように Maven2 を使用して容易にメトリクスの測定が可能となっている点がポイントだった。

Maven2
JavaNCSS プラグインの使い方


以下のように、メトリクスの測定対象プロジェクト(Maven2 用のプロジェクト)の pom.xml ファイルに
JavaNCSS プラグインの定義を追加して、mvn
javancss:report を実行すれば(mvn site でも可)、target/javancss-raw-report.xml ファイルにソフトウェアメトリクスの測定結果が出力される。
<project>
・・・
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>javancss-maven-plugin</artifactId>
</plugin>
</plugins>
</reporting>
・・・
</project>

>mvn javancss:report
もしくは
>mvn site


それでは本題に戻って、Hudson のプラグインを作成していく事にする。今回は
groupId に simple、artifactId に simpleTest という名称を使った。

まず、サンプルクラス HelloWorldBuilder.java の名称を変更して拡張ポイント Publisher
継承するクラスを以下のように作成。

src/main/java/simple/JavaNcssPublisher.java ファイル

package simple;

import hudson.FilePath;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.model.Descriptor;
import hudson.model.Result;
import hudson.tasks.Publisher;

import java.io.IOException;

import org.kohsuke.stapler.StaplerRequest;

public class JavaNcssPublisher extends Publisher {

JavaNcssPublisher() {
}

//ビルド後に実施する処理を記述
@Override
public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {

FilePath[] files = build.getProject().getWorkspace().list("**/javancss*report.xml");

if (files.length == 0) {
listener.getLogger().println("not found : javancss report file");
build.setResult(Result.FAILURE);
}
else {
FilePath root = new FilePath(build.getRootDir());
FilePath target = new FilePath(root, "javancss_result.xml");

//workspace 内に生成された javancss-raw-report.xml ファイルを
//ビルドごとに生成されるディレクトリに
//javancss_result.xml という名称でコピー
files[0].copyTo(target);

JavaNcssAction act = new JavaNcssAction(build);
act.setResultFileName(target.getName());

//ビルド結果に JavaNcssAction インスタンスを追加。
//ビルド結果の構成を保存する build.xml ファイルに
//シリアライズされて保存される
build.addAction(act);
}

return true;
}

public Descriptor<Publisher> getDescriptor() {
return DESCRIPTOR;
}

public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();

public static final class DescriptorImpl extends Descriptor<Publisher> {
DescriptorImpl() {
super(JavaNcssPublisher.class);
}

public String getDisplayName() {
return "JavaNCSS reports";
}

public JavaNcssPublisher newInstance(StaplerRequest req) throws FormException {
return new JavaNcssPublisher();
}
}
}


拡張ポイント Publisher を使用するため、hudson.tasks.Publisher を継承
perform メソッドに Publisher としてビルド後に実施する処理を実装する。

Descriptor 関係の処理は、HelloWorldBuilder.java ファイルの処理を元にクラス名の箇所を書き直す。

次に、PluginImpl.java を以下のように修正。

src/main/java/simple/PluginImpl.java ファイル

package simple;

import hudson.Plugin;
import hudson.tasks.BuildStep;

public class PluginImpl extends Plugin {
public void start() throws Exception {
BuildStep.PUBLISHERS.add(JavaNcssPublisher.DESCRIPTOR);
}
}


BuildStep.PUBLISHERS に JavaNcssPublisher.DESCRIPTOR を追加するように変更。

なお、PluginImpl クラスはプラグインファイル(.hpi ファイル)内の
META-INF/MANIFEST.MF ファイルの Plugin-Class として設定され、プラグインを指定の拡張ポイントに登録する処理を実行する。

JavaNcssAction クラスの実装は後回しにして、先に「Hudsonの管理」->「システムの設定」画面で表示するビューを作成するために、resources ディレクトリ
HelloWorldBuilder ディレクトリ
JavaNcssPublisher に名称変更して、global.jelly を以下のように変更。

src/main/resources/simple/JavaNcssPublisher/global.jelly
ファイル

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">

<f:section title="JavaNCSS Publisher">
</f:section>

</j:jelly>


今回は設定値の入力が不要なので、とりあえずプラグインの項目名だけを表示するようにした。





更に、ジョブの「設定」画面で表示するビューを作成するために、config.jelly を以下のように変更。

src/main/resources/simple/JavaNcssPublisher/config.jelly
ファイル

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
</j:jelly>


設定値の入力が不要なので何も記述しなかった。これにより、「設定」->「ビルド後の処理」において、JavaNcssPublisher
で実装した DescriptorImpl クラス getDisplayName() の戻り値を伴ったチェックボックスだけが表示されるようになる。





次に、Action インターフェースを実装した
JavaNcssAction クラスを作成する。

主要なメソッドの説明は以下のとおり。
getDisplayName() メソッドの戻り値ビルド画面の左メニューに表示
getIconFileName() メソッドの戻り値ビルド画面の左メニューにアイコンとして表示
戻り値が null の場合は項目自体が非表示になるので注意が必要
/ で区切らないファイル名を指定すると Hudson 内のメインリソースを参照する模様

getUrlName() メソッドの戻り値は URL に組み込まれる
"/job/ジョブ名/ビルド番号/getUrlName()の戻り値"
という URL が生成


src/main/java/simple/JavaNcssAction.java ファイル

package simple;

import hudson.model.AbstractBuild;
import hudson.model.Action;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

public class JavaNcssAction implements Action {

private static final long serialVersionUID = 1L;

private AbstractBuild<?, ?> owner;
private String resultFileName;

public JavaNcssAction(AbstractBuild<?, ?> owner) {
this.owner = owner;
}

@Override
public String getDisplayName() {
return "JavaNCSS Results";
}

@Override
public String getIconFileName() {
return "document.gif";
}

@Override
public String getUrlName() {
return "javaNcss";
}

public AbstractBuild<?, ?> getOwner() {
return this.owner;
}

public List<FunctionMetrics> getFunctionMetricsList() {
return this.parseResultXml();
}

public void setResultFileName(String resultFileName) {
this.resultFileName = resultFileName;
}

//javancss_result.xml ファイルを解析して、
//メソッドに関するメトリクス結果を List に格納
private List<FunctionMetrics> parseResultXml() {
List<FunctionMetrics> result = new ArrayList<FunctionMetrics>();

if (this.resultFileName != null) {

SAXReader saxReader = new SAXReader();

try {
Document doc = saxReader.read(new File(this.owner.getRootDir(), this.resultFileName));
XPath xpath = DocumentHelper.createXPath("//function");

for (Element func : (List<Element>)xpath.selectNodes(doc)) {
FunctionMetrics fm = new FunctionMetrics();

fm.name = func.elementTextTrim("name");
fm.ccn = this.parseInt(func.elementTextTrim("ccn"));
fm.ncss = this.parseInt(func.elementTextTrim("ncss"));

result.add(fm);
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
return result;
}

private Integer parseInt(String number) {
Integer result = null;

if (number != null) {
try {
result = Integer.parseInt(number);
}
catch (NumberFormatException ex) {
}
}

return result;
}

//メソッドのメトリクス結果を格納するためのクラス
public class FunctionMetrics {
public String name;
public Integer ncss;
public Integer ccn;
}
}


なお、JavaNcssAction クラスは、URLが "/job/ジョブ名/ジョブ番号/javaNcss"
の場合に適用されるようになり、ビューとして simple/JavaNcssAction/index.jelly ファイルが使用されるが、別のURL にリダイレクトしたり、index.jelly
の適用前に処理を実施する場合は、URL の内容に基づいた doXXX メソッドや doDynamic メソッドを定義して処理を実装することになる。

最後にソフトウェアメトリクスの結果表示画面を作成するために
resources/simple/JavaNcssAction ディレクトリを作成し、index.jelly
ファイルを下記のような内容で作成する。

src/main/resources/simple/JavaNcssAction/index.jelly
ファイル

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">

<l:layout>
<st:include it="${it.owner}" page="sidepanel.jelly" />
<l:main-panel>
<h1>JavaNCSS Results</h1>

<table>
<tr>
<th>Method Name</th>
<th>NCSS</th>
<th>CCN</th>
</tr>
<j:forEach var="fm" items="${it.functionMetricsList}">
<tr>
<td>${fm.name}</td>
<td>${fm.ncss}</td>
<td>${fm.ccn}</td>
</tr>
</j:forEach>
</table>

</l:main-panel>
</l:layout>

</j:jelly>


jelly ファイル内では it で JavaNcssAction のインスタンスを参照可能。ここではメソッドに関するメトリクス結果を
JavaNcssAction.getFunctionMetricsList() から取得し、table で表示するようにしている。

sidepanel.jelly の設定は、左メニューの表示を保つための措置。

ちなみに、NCSS はコメント行を除く行数、CCN はサイクロマチック複雑度という測定項目。


プラグインの配置と実行

mvn package の実行で生成された simpleTest.hpi を
.hudson/plugins ディレクトリに配置してHudson を再起動する。(通常、.hudson はユーザーのホームディレクトリに作成される)
mvn package


以下のような手順で、JavaNCSS でソフトウェアメトリクスを実施するジョブを作成し、ビルドを実行する。
「新規ジョブ作成」でジョブを作成
ソースコード管理システム」の設定を実施
ビルド」の「Maven の呼び出し」のゴールで
package と javancss:report を設定(pom.xmlファイルに Maven2 JavaNCSS プラグインの設定を施しておく)
ビルド後の処理」で「JavaNCSS reports」にチェックをつける

ビルド画面から「JavaNCSS Results」に移動して、メトリクス結果画面を表示すると以下のような画面が表示される。(今回は、このプラグイン作成プロジェクトのソースコード自体を Hudson のジョブに設定)



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息