Mavenリポジトリのアーティファクト一括抽出するスクリプト

明けましておめでとうございます。まったく新年と関係ないエントリから始まりますが、今年もよろしくお願いします。

この休みで少しでもGroovyに慣れようとまたちょいプロ作ったので、簡単に紹介します。


概要

今回作成したのは、RepoArtifactExtractorというGroovyスクリプトです。Mavenリポジトリをばーっと検索して、リポジトリに登録されている最新アーティファクトの一覧をみんな大好きExcelさんにばーっと書きだしてくれます。こんな感じに。

f:id:ikikko:20110102015937p:image

セントラルリポジトリに登録されているものはMaven Repository: Search/Browse/Exploreとか使えば簡単に検索できるけど、インハウスリポジトリとか建てたときにアーティファクト一覧をばーっと見たいときに使えるでしょう。ま、SonatypeのNexus使えばって話もごもっともですがw*1

実行方法

Githubにソースを置いてます*2。結構ベッタベタな書き方で、お世辞にも美しくはないです。

こちらをpullしてからーの下記のコマンドで、(groupId, artifactId, version)とおまけでivy形式の設定内容が記載されたExcelファイルが作成されます。

/usr/bin/groovy RepoArtifactExtractorScript.groovy
  artifacts.xls
  http://maven.seasar.org/maven2/org/seasar/cubby/
(本当は1行)

あとは、これをCRONなりHudsonの定期実行なりで1日1回でも回しておけば。

余談

今回、中身はPOI*3 + NekoHTMLでのHTMLスクレイピングという構成なので、大して目新しいものはありません。なんで、余談的にいくつか。

HTMLスクレイピング

上記で示したコマンド実行例ではSeasarリポジトリを対象にしていますが、ルートからではなく"http://maven.seasar.org/maven2/org/seasar/cubby/"のようにCubbyというプロダクトだけに絞っています。ご存知の通り、HTMLスクレイピングはWebサーバに負担をかけるんで、検証では極力小さい範囲のスクレイピングで済むようにしていました。もちろん、スクリプトの処理自体も極力負荷を抑えるように小細工はしてますが。

スクレイピングのご利用は、計画的に。

Grape

GroovyのGrapeを使うと、単体のgroovyファイルだけで依存Jarの解決ができます。Groovyの実行環境さえあれば(pom.xmlなどの設定ファイルが不要で)スクリプトファイルをポンと渡すだけで動かすことができるんですね。シェルスクリプトの代わりにGrape付きGroovyスクリプトを呼び出すとかも、効果的な使い方かな。

Grapeの詳細は、id:ksky さんの↓の資料を見てもらえれば。

POMの解析

プログラム上からPOMを解析するには、ModelBuilderクラス辺りを使えばできます。使用方法は、テストケースから何となく分かるでしょう。

ただ、結局このAPIは使わずにベタにPOMをXMLとして解析しています。(ValidationLevelを最低にしても)parentのpomを参照しにいくみたいで、Mavenリポジトリ上のディレクトリ構造ではparentが参照できずに解析エラーとなってしまうケースがあったので。

Excelの処理

ひっそりとGExcelAPI v0.2をリリースしました - 豆無日記がよさそうだったので、当初はPOIの代わりにこれを使おうと考えてました。ただ、これってExcelファイルの参照しかできないんですよね。残念><

POIに比べて直感的で分かりやすかったんで、更新ができるようになるといいなぁ・・・とプレッシャーをかけてみるテスト。


今回学んだもの

  • GroovyでのHTMLスクレイピングのやり方
  • Apache POI / GExcelAPIの使い方
  • プログラム上からPOMを解析する方法

*1:ちなみに、一応Tomcat6の上に載せようとしたけど、うまくデプロイできませんでした。今回の主目的ではなかったので、深追いはしてませんが。

*2:何か不要なディレクトリがGithub上に残ってる。気持ち悪いけど、とりあえずほっておきます。

*3:いつの間にかOffice 2007以降のOffice Open XML形式にも対応してたんですね。

G*ワークショップに行って来ました

今週の木曜にJGGUG主催の12月9日 第13回 G* ワークショップ+忘年LT大会(東京都)に行って来ました。前日まで全員参加のLTがあるの知らなかったので、夜に大慌てで作りました。とりあえず、晒しておきます。

Groovyはまだ触り始めたばかりなので、これから色々取り入れていきたいですね。

CacooPoint : Cacooの図をPowerPointに落とし込む

http://img.f.hatena.ne.jp/images/fotolife/y/yuroyoro/20101006/20101006140123.png

「(PowerPointが入っていないが)そんなPCで大丈夫か?」
「大丈夫だ、問題ない」

流行り物*1に流されやすいikikkoです、こんにちは。

今日は、Cacooで作った図(プレゼン資料)をPowerPointに落としこむスクリプト「CacooPoint」をGroovyで作ってみました。パワポを表示するだけならMicrosoftからPowerPoint Viewerなるものが提供されていますので、これでPCにパワポがなくともプレゼン資料が作れますね。

OpenOffice?なにそれ、おいしいの・・・><


スクリプトの概要

大まかな処理フローは、このような感じです。

  1. Cacoo API経由で、Cacoo Diagramに含まれるシート情報を抽出する
  2. 抽出したシート情報から、図一覧をぶっこぬいてローカルに画像ファイルとして保存する
  3. 保存されたファイルをPowerPointに貼っていく
事前情報の設定

Cacoo API経由で図を取得するので、スクリプト中で大元になるdiagramのIDを指定します。非公開の図形ならばAPIキーも必要になるので、発行して指定しておくこと。

// Cacooの図形IDと(必要ならば)APIキーを指定
def diagramId = 'IZczfsbRj5yEbYEG'
def apiKey = '' // 公開されている図形ならば不要

なお、デフォルトのdiagramはid:tksmdCacoo - 大阪ガベージコレクション2010秋を使用させていただいてます。

Cacooから画像を抽出

上記で設定した情報をもとに

  1. XmlParserで図の情報をXML形式で取得・パースして
  2. HTTPBuilderで各シートの図をGetして保存

してます。

XMLParsar+GPathでXMLをスマートにハンドリングできるのが嬉しいですね。

// Cacooの図一覧を取得
def sheetIndex = 1;
def url = "https://cacoo.com/api/v1/diagrams/${diagramId}.xml?apiKey=${apiKey}"
def diagrams = new XmlParser().parse(url)
def title = diagrams.title.text()
diagrams.sheets.sheet.each {
  def name = it.name.text()
  def imageUrl = it.imageUrlForApi.text() + "?apiKey=${apiKey}"
  
  def http = new HTTPBuilder( imageUrl )
  http.request(GET, BINARY) {req ->
    response.success = { resp, reader ->
      def fileName = String.sprintf('%03d_%s.png', sheetIndex, name)
      def sanitizedFileName = fileName.replaceAll(/[\/:*?"<>|]/, ' ')
      new File("image/${sanitizedFileName}") << reader
      sheetIndex++;
      
      println "created image file : ${sanitizedFileName}"
    }
  }
}
PowerPointに画像を張り付け

PowerPointを扱う部分は、GroovyDSLsで紹介されていたPowerPoint DSLを使用しています。PowerPoint DSLの内部的にはScriptomじゃなくてApache POIを使用してますが。

Groovyのbuilderを使うと、これだけ単純な表記でパワポを扱うことができちゃいます。

// 取得した図をPowerPointに貼りつけ
def builder = new PowerPointBuilder()
builder.slideshow(filename: "${title}.ppt") {
  imageDir.eachFile {
    imageslide(src: it.path)
  }
}

完成

コードの完成形は、Githubに置いています。

ただ、実際やってみると分かるのですが、微妙にうまく貼り付けられていません。Cacooで描いた図のサイズが大きすぎるとはみ出すとか、背景が白いと引っ張ってくる画像に変な模様が入るとか。

多分、PowerPoint DSLの方のコードを修正すればうまくいきそうな気もしなくもないですが、そこまでする気力もないのでとりあえず放置。まぁいい勉強になったということで。。。もしこれを使いたいという奇特な方がいたらもう少し頑張って修正するかもしれませんので、そんな人がいたらコメントなりリプライなりくださいませ。

ちなみに、スクリプトの処理途中でCacooの図を一括で抽出しているので、この部分だけ抜き出しても使えるかもですね。


前からGroovyを勉強はしているんですが、写経じゃなくて何か作ったのは実は初めて。まだ途中だしここから面白くなりそうなので、早くGroovy in Actionも読まんと。

Groovyイン・アクション

Groovyイン・アクション

*1:ニコニコ界隈で話題沸騰中のエルシャダイですね。id:yuroyoroさんの図をお借りしました。

形から入るGroovy

夏休みの自由課題ということで、前からやるやる詐欺をしていたGroovyを触っています。

Groovyイン・アクション

Groovyイン・アクション

とりあえずGroovyのEclipse Plugin入れてから写経しているのですが、どうせやるなら楽しく学習したいですよね。ということで、Eclipseエディタをこんなんにしてみました。

f:id:ikikko:20100809225130p:image

このような有益な環境を構築することができたのも、偉大なる先人の方々のおかげです。ここに心から感謝の意を表します。