2013年4月18日木曜日

Cloud FoundryにWebアプリをIntelliJでデプロイする

IntelliJのバージョンいくつかから、Cloud FoundryおよびCloudBeesとの連携機能がバンドルされるようになっていたので試してみました。

ここではとりあえず、GrailsアプリをCloud Foundryにデプロイしてみます。

プロジェクトを作成

プロジェクトがなきゃ始まりませんので……

デプロイするwarファイルを作成する

「Ctrl+Alt+G」から「prod war」コマンドを実行して、デプロイするwarを作成します。

実行設定を作成

「Edit Configuration」から……

「Defaults」から「Cloud Foundry Server」を選択して、緑の+ボタンで実行設定を追加

「Server」タブの「Configure」でCloud Foundryアカウントを設定

「Deployment」タブでデプロイするwarを設定

デプロイするアプリの設定を行う。とりあえず、「Type」を「Grails」に。MongoDBとかサービスを追加するときは「Edit services」から適宜追加。

設定したwarをデプロイ

「Application Servers」タブから、緑の矢印でCloud Foundryに接続、デプロイ

で、warがデプロイされて、ブラウザが開いてアプリケーションに繋がるはず。

アプリケーションを更新したら

「prod war」でもう一回warを作り直して、実行画面から更新。更新中404になるのがイケてない。

うわぁ簡単すぎて書くことない…もうちょっと複雑なことしようとしたらいろいろ出てくるかも、ということで

2012年12月14日金曜日

GrailsでMongoDBの複合キーインデックスに属性を指定するプラグインを公開

先日、Grailsプラグインgrails-mongodb-compound-index-attributesを紹介して、セントラルリポジトリに公開するまでもないので何とかかんとかと書きましたが、公開してもいいですよということなのでやっぱりお言葉に甘えてGrailsセントラルに公開することにしました。

以下、プラグインについて。

MongoDBでは複合キーに対してインデックスをはることができます。 GrailsのMongoDBプラグインでは、以下のように指定します。

class Book {

    static mapping = {
        compoundIndex contributor: 1, name: 1
    }

    String contributor
    String name

}

が、今のところ、このインデックスにユニーク属性などの属性を指定できません。

それを解決するのが、今回公開したMongoDBプラグインのアドオンであるgrails-mongodb-compound-index-attributesです。インストールすると以下のようにできます。

class Book {

    static mapping = {
        compoundIndex contributor: 1, name: 1, indexAttributes: [name: "contributorUniqueName", unique: true]
    }

    String contributor
    String name

}

ブラボーGrailsプラグインシステム

2012年12月11日火曜日

GrailsのプラグインをCloudBeesで公開する

どうも、G* Advent Calendar 2012、11日目担当、@literaliceです。

さて、突然ですが先日、grails-mongodb-compound-index-attributesというGrailsのプラグインを公開しました。

このプラグインは、GrailsのMongoDBプラグインを拡張し、compound indexにunique属性などを追加できるようにするものです。こんな:

class Book {
    static mapping = {
        compoundIndex contributor: 1, name: 1, indexAttributes: [name: "idxName", unique: true]
    }
    String contributor
    String name
}

で、この機能はどうせ将来的にMongoDBプラグインに実装されるでしょうし、わざわざGrails本家のプラグインリポジトリに公開するまでもない気がしますね。

以前はこういうとき、Githubをプラグインリポジトリにして公開していました。

が、ナウい方法はCloudBeesのDEV@cloudを使うことです。

DEV@cloudは登録するとJenkinsサーバーとMavenリポジトリ、Gitのリポジトリをもらえます。

Mavenリポジトリはいろいろハウスキーピングしてもらえますし、何よりプライベートリポジトリにできるのがGithubをムリヤリ使う方法に比べてイケてますね。

と言うわけで前置きが長くなりましたが、GrailsプラグインをCloudBees、DEV@cloudで公開する手順を紹介します。

Grails version
2.1.1

手順

  1. Grailsプラグインを作る
  2. CloudBeesにアカウントを作る
  3. releaseプラグインをCloudBees用に設定する
  4. publish-pluginコマンドでリリース

Grailsプラグインを作る

作ります。例:grails-mongodb-compound-index-attributes

CloudBeesにアカウントを作る

作ります。→CloudBees

releaseプラグインをCloudBees用に設定する

releaseプラグインはGrailsのcreate-pluginコマンドでプラグインを作成すれば入ってるはずです。

このreleaseプラグインを、CloudBees上に作られたWebDAVのMavenリポジトリにリリースするよう設定します。

// BuildConfig.groovy or ~/.grails/settings.groovy
grails.release.scm.enabled = false // プラグインのソースコードはリリースしない

grails.project.repos.default = "releaseRepository" // リリース先未指定時のリリース先
grails.project.repos.releaseRepository.url = "dav:https://repository-[CloudBeesアカウント名].forge.cloudbees.com/release/" // リリース先"releaseRepository"のURL
grails.project.repos.releaseRepository.type = "maven"
grails.project.repos.releaseRepository.username = "[CloudBeesのUser SettingsにあるUsername]"
grails.project.repos.releaseRepository.password = "[CloudBeesのログインパスワード]"

私の場合は、CloudBeesのJenkinsからビルド、リリースしているので、システムプロパティでファイルを渡して、そのファイルから上記設定を読み込むようにしています。その設定ファイルは、CloudBeesに用意されるプライベートなファイルストレージに置いておきます。
例: BuildConfig.groovy

publish-pluginコマンドでリリース

grails publish-plugin --repository=releaseRepository --protocol=webdav

なお、CloudBees上のJenkinsでビルド、リリースする場合は、前述のようにシステムプロパティに認証情報などを記述した設定ファイルのパスを渡し、そのファイルから設定を読み込むようにします。

sh ./grailsw -DhogehogeFile=/private/[CloudBeesアカウント名]/grails/credential.properties publish-plugin --repository=releaseRepository --protocol=webdav --non-interactive

公開したプラグインをGrailsプロジェクトで使用する

このようにプラグインを公開すると、Grailsプロジェクトから以下のようにして使用できるようになります。

//Build.groovy
grails.project.dependency.resolution = {
    // ...

    repositories {
        // ...

        // For the plugin
        mavenRepo "http://repository-[CloudBeesアカウント名].forge.cloudbees.com/release"
    }

    // ...
    plugins {
        // ...

        compile ":[公開したプラグイン名]:[公開したプラグインバージョン]"
    }
}

まとめ

というわけで、こんな感じにCloudBeesを使ってGrailsプラグインを流れるようにpush→Jenkinsビルド→Mavenリポジトリに公開しましょう。

G* Advent Calendar 2012、12日目は@yamkazuさんです。

2012年6月1日金曜日

PaaSでGrailsならCloudBeesがイイ

HerokuとかCloud Foundryとか、いろんなPaaSを試してみましたが、今のところCloudBeesが良い感じだと思いました。

なお、パフォーマンスや安定性を調査したわけではなく、アプリを動かしてみたときの単純な感想です。
Jelasticなど、Javaをメインに想定したPaaSであればGrailsとの相性もいいと思うので、更に調査したいと思っています。

さて、CloudBeesですが、無料範囲だと、1アプリにつき2インスタンス、5アプリまで作れるようです。さらにビルド環境も用意してくれます。
メモリ制限がきついので本格運用するときは有料プランが必要でしょうけど、試しに始めてみるにはいいGrails実行環境なんじゃないでしょうか。

以下いいとこ雑感

Amazon EC2で動作
これはメリットデメリットあると思いますが、とりあえずMongoHQとかMongoLabとかAmazon SESとか、AWS使った豊富なサービスが使えるのが嬉しい。
例えばcloudfoundry.comとかだとそうは行かない
ビルドサーバー付き
DEV@cloudというCloudBeesのサービスでJenkinsサーバーが使えます。
ソースコードをプッシュしたら、CloudBees上のTomcatで公開するまで全自動
HerokuにもBuildpackというシステムがあって、ソースコードをプッシュしたら自動でビルドが走ってデプロイしてくれる…
が、Grailsのように依存性解決なんかでビルドに時間がかかる場合、途中でタイムアウトになってデプロイに失敗するんですよね。2回に1回くらい。
あとやっぱりJavaな人ならJenkinsが慣れてて使いやすいと思いますし
普通にTomcatにデプロイ
Grailsは大体Tomcatで動かしながら開発するのでTomcatが安心
スティッキーセッション、セッションクラスタリングに対応
クラスタリング時のセッションストアはそれなりに価格高いですけど、なんにしてもこの辺はHerokuでは使えません。
再デプロイ時にダウンタイムがない
CloudBeesはアプリケーションアップデート時、新しいクラスタでアプリを起動させてから古いアプリケーションを破棄してくれるのでダウンタイムが発生しません。
URLのGETパラメータが化けない
Cloud Foundryェ…

今のとこの気になる点

独自ドメイン対応
CloudBees上のアプリを独自ドメインで参照する場合、CNAMEでエイリアスとして設定します
普通の人は独自ドメインのルート(example.comとか)にCNAMEレコード作れないと思うので、www.example.com、とかのサブドメインを使わなければなりません。
Herokuだと普通にAレコードで設定できます。
メモリ
無料範囲だと使用できるのが最大256mで、ここからPermGenなんかを割り当てるようです。
Grailsを動かす場合256mのPermanent領域が推奨されるということですが、もちろんそんなに割り当てたら起動できなくなります。
本格的に動かすときは有料プランで

時間があったら、動かしてみた手順でも書いてみます。

2012年1月7日土曜日

Grails2.0のユニットテスト用アノテーションを整理してみる

Grails Version
2.0.0

Grails 2.0から、アノテーションを使ってユニットテストを書くことになってるのですが、
そのアノテーションの使い方が少しややこしかったので整理してみました。あんまり自信ないです。

Grailsのテストで使うアノテーションは以下のとおり。

  • grails.test.mixin.TestMixin
  • grails.test.mixin.Mock
  • grails.test.mixin.TestFor

@TestMixin

使用例
@TestMixin(GrailsUnitTestMixin)

テストクラスに以下のようなミックスインを適用して、テスト用、モック作成用のメソッドやプロパティを追加、設定するのに使用する。

リストを渡せば複数のミックスインを適用できる。

  • grails.test.mixin.support.GrailsUnitTestMixin
  • grails.test.mixin.domain.DomainClassUnitTestMixin
  • grails.test.mixin.services.ServiceUnitTestMixin
  • grails.test.mixin.web.ControllerUnitTestMixin
  • grails.test.mixin.web.FiltersUnitTestMixin
  • grails.test.mixin.web.GroovyPageUnitTestMixin
  • grails.test.mixin.web.UrlMappingsUnitTestMixin
  • grails.test.mixin.webflow/WebFlowUnitTestMixin

以下にいくつかの使用例を挙げる。

GrailsUnitTestsMixin

以下のような機能をテストクラスに追加する、全てのミックスインの基盤となるミックスイン

  • grailsApplicationやmessageSourceなどのGrailsのコンテキストプロパティを追加
  • mockForConstraintsTests、mockForなどの基本的なモック作成メソッドを追加
import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import org.junit.Test

@TestMixin(GrailsUnitTestMixin)
class GenericTests {
    
    @Test
    void genericTest() {
        mockForConstraintsTests(Book)
        def book = new Book(title: "")
        assert !book.validate()
        assert book.errors["title"] == "blank"
    }
}

DomainClassUnitTestMixin

さっきの「GrailsUnitTestsMixin」を適用し、さらにドメインクラスのテスト用にmockDomainメソッドを追加する。

import grails.test.mixin.TestMixin
import grails.test.mixin.domain.DomainClassUnitTestMixin
import org.junit.Test

@TestMixin(DomainClassUnitTestMixin)
class GenericTests {
    
    @Test
    void genericTest() {
        mockDomain(Book)
        def book = new Book(title: "")
        assert !book.save()
        assert book.errors.getFieldError("title").code == "blank"
    }
}

ServiceUnitTestMixin

さっきの「GrailsUnitTestsMixin」を適用し、さらにサービスのテスト用にmockServiceメソッドを追加する。

import grails.test.mixin.TestMixin
import grails.test.mixin.services.ServiceUnitTestMixin
import org.junit.Test

@TestMixin(ServiceUnitTestMixin)
class GenericTests {
    @Test
    void genericTest() {
        mockService(HelloService)
        assert applicationContext.helloService.hello() == "Hello, World"
    }
}

ControllerUnitTestMixin

「GrailsUnitTestsMixin」を適用し、さらにコントローラーのテスト用にmockControllerメソッドやサーブレットコンテキストのモックなどを追加する。

import grails.test.mixin.TestMixin
import grails.test.mixin.web.ControllerUnitTestMixin
import grails.test.mixin.services.ServiceUnitTestMixin
import org.junit.Test

@TestMixin([ControllerUnitTestMixin, ServiceUnitTestMixin])
class GenericTests {
    @Test
    void genericTest() {
        mockService(HelloService)
        
        def controller = mockController(BookController)
        controller.show()

        assert response.text == "Hello, World"
    }
}

などなど。

@Mock

使用例
@Mock(BookController)
  • 指定クラスに応じて、適当にミックスインを適用する
  • 更に指定クラスのモックを作成してコンテキストに登録する

例えば……

  • ドメインクラスの場合: DomainClassUnitTestMixinを適用し、更に指定クラスに対してmockDomainを適用する
  • サービスクラスの場合: ServiceUnitTestMixinを適用し、更に指定クラスに対してmockServiceを適用する
  • コントローラークラスの場合: ControllerUnitTestMixinを適用し、更に指定クラスに対してmockControllerを適用する
  • などなど
import org.junit.Test
import grails.test.mixin.Mock
import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes

@Mock([BookController, HelloService])
class GenericTests {
    
    @Test
    void genericTest() {
        def controller = webRequest.currentRequest.getAttribute(GrailsApplicationAttributes.CONTROLLER)
        controller.show()
        assert response.text == "Hello, World"
    }
    
}

@TestFor

使用例
@TestFor(BookController)
  • 指定クラスに対して@Mock相当の機能を適用してモックを作成
  • 指定クラスのモックに、アーティファクト名のプロパティでアクセスできるようにする
  • testで始まるメソッドに、@Testアノテーションを付加

このアノテーションには、複数のクラスを引数に渡すことができない。

import grails.test.mixin.Mock
import grails.test.mixin.TestFor

@TestFor(BookController)
@Mock(HelloService)
class GenericTests {

    void testGenericTest() {
        controller.show()
        assert response.text == "Hello, World"
    }
    
}

ちなみに

Grailsのコマンド、test-appを使ってテストを実行すると、いくつかの処理を自動で行ってくれるようです。

例えば、ドメインクラスがBookで、テストクラスがBookTestsという名前だった場合、BookTestsに@TestFor(Book)が何も書かなくても適用されるように見えます。

この辺の動作はまだよく分かりません。

おわりに

もっぱら使用するのは@TestForと@Mockであって、@TestMixinで直接テストメソッドをミックスインすることはあまりないと思いますが、大体こんな役割になってそう、ということです。

動作確認はしましたが、ソースはあまり追っていないので間違ってるところもあるかもしれません。

気がついたことなどありましたら、教えてもらえると幸いです。

2011年12月16日金曜日

ConfluenceのHTML→PDF変換ライブラリを利用する

JIRA Advent Calendar 2011、15日目です。

ってすみません、ConfluenceネタですがまあJIRA使ってる人は連携して使ったりしますよねとか、そんな感じで。
GradleのユーザーガイドPDFに変換するときにお世話になったので、紹介してみます。

Confluenceは、バンドルされているプラグインでページをPDFに変換して出力できるのですが、この機能に使われているライブラリを使って、XHTMLをPDFに変換しようという話です。

ConfluenceのXHTML→PDF処理にはFlying SaucerというJavaのライブラリが使われています。
Flying Saucerを使うと、XMLやXHTMLファイルを、PDFやSWT、Swingのスクリーンに出力させることができます。デザインはCSSで指定できます。

ただ、このFlying Saucer、PDFに変換したときに、文字列が空白位置でしか改行されません。
英文Onlyならいいのですが、日本語で長文をだらだら書いていると画面外にあふれて見えなくなってしまうわけですね。
ConflueceのPDFエクスポートでの禁則 - azuki note

この問題を、Atlassianさんがパッチを当てて修正しているので、しかもMavenリポジトリ上に上げてくれているので、今回はそれを使います。

@Grape+Groovyスクリプトでもいいですが、いろいろ面倒なのでGradleスクリプトで。

フルのサンプルはGithubに上げたのでそちらを見てもらうとして、ポイントだけ書いておきます。

変換元のHTMLとCSSのサンプル

AtlassianさんのMavenリポジトリからFlying Saucerを取得

AtlassianさんのMavenリポジトリから、パッチの当たったFlying Saucerライブラリを取得します。
GradleとかMavenとかIvyとか、そのあたりの設定に依存関係を追加するのがいいですね。

ライセンスが気になるところですが、LGPLのままみたいなので大丈夫でしょう、多分…

Mavenリポジトリ
https://maven.atlassian.com/repository/public
アーティファクト
org.xhtmlrenderer:xhtmlrenderer:8.3-atlassian

Flying SaucerはPDF生成にiTextを使うのでそちらも

Mavenリポジトリ
セントラルリポジトリ
アーティファクト
com.lowagie:itext:2.0.8
// Gradleの例
buildscript {
    repositories {
        mavenCentral()
        mavenRepo url: "https://maven.atlassian.com/repository/public"
    }
    dependencies {
        classpath "org.xhtmlrenderer:xhtmlrenderer:8.3-atlassian"
        classpath "com.lowagie:itext:2.0.8"
    }
}

PDFへの変換処理

PDFへの変換処理は、次のような感じで書きます。

import org.xhtmlrenderer.pdf.ITextRenderer

def renderer = new ITextRenderer()
renderer.setDocument(new File("sample.html"))
renderer.layout()
new File("sample.pdf").withOutputStream {
    renderer.createPDF(it)
}

このコードを実行すれば、sample.htmlがsample.pdfに変換されます。

CSSでPDFに埋め込むフォントを指定する

日本語を使うには日本語フォントをPDFに埋め込むか参照させる必要があります。変換元のHTMLに次のようなCSSを適用しましょう。

@font-face{
    font-family: "IPAexGothic";
    src: url(ipaexg.ttf);
    -fs-pdf-font-embed: embed;
    -fs-pdf-font-encoding: Identity-H;
}

body {
    font-family: "IPAexGothic";
}

なんか、使えるフォントと使えないフォントがあるみたいです。

fsなんたらはFlying Saucerのベンダー拡張ですね。詳しくはFlying Saucerのユーザーガイドを見てみてください。

長い文章を折り返すための設定

Atlassianさんのパッチが当たったFlying Saucerを使うと、次のようにCSSでword-wrapを指定することで長い文章が折り返されるようになります。

p {
    word-wrap: break-word;  
}

おわりに

いやぁ、便利ですね。ちょっとしたPDF作るだけなら、それ用のHTMLファイル作って変換するのが簡単かもしれません。

さて、かなり脱線気味でしたが、こんなところで。
引き続きJIRA Advent Calendar 2011をお楽しみください。

2011年12月6日火曜日

GrailsのプラグインリポジトリとしてGithubを使う

G* Advent Calendar、6日目いってみます。
今日を境に、公開Grailsプラグインの数が爆発的に増える……といいなーという感じで

Grails version
2.0.0.RC1

Grailsプラグインのリポジトリには、Maven形式のリポジトリが使用できます。

つまり、MavenのリモートリポジトリをGithub上に構築する以下の手法を使えば、GraisプラグインのリポジトリをGithub上に持てるわけですね。
Github を Maven 公開リポジトリにする
GitHub を Maven 公開リポジトリにする (Gradle 編)

何ができるの?

例えば、私はGrailsのAWSプラグインにパッチを当てたものをGithub上に公開しています。1

このプラグインは、次のようにしてどこからでも使用できます。

// grails-app/conf/BuildConfig.groovy
// ...
grails.project.dependency.resolution = {
    // ...
    repositories {
        grailsPlugins()
        grailsHome()
        grailsCentral()

        // ...
        // Github上のマイプラグインリポジトリを指定
        mavenRepo "http://literalice.github.com/maven-repo/releases"
    }
}

# 上で指定したプラグインリポジトリからプラグインをインストール
cd grails-project
grails install-plugin aws 1.2.12.1.p1

とまあ、このように、改造したり開発したりした非公式オリジナルプラグインを簡単に公開して使えるようにしちゃおうというのが目的です。

GrailsのプラグインはzipファイルのURLを指定してインストールできるので他にいくらでも方法はあるわけですが、不特定多数に公開して良いなら今のところこれが一番手軽なんじゃないかなぁと。

この記事は、私がAWSプラグインを改造して公開したときの手順を思い出しながら書いていますが、オリジナルのプラグインを公開するときも同じような感じです。

以下がその手順です。

プラグインのソースコードを入手する

  • Github上にあるプラグインのソースコードをフォークして、手元にクローン
  • grails create-plugin コマンドでプラグインプロジェクトを作成する
  • などなど

プラグインのバージョン番号を更新する

既存のプラグインを改造する場合は、バージョン番号がオリジナルのものと被らないように変更しておいた方が良いでしょう。1.0.0.p1、といった風に適当なサフィックスを付けておきます。

    // XXGrailsPlugin.groovy - プラグインディスクリプタ
    // ..
    def version  = "1.0.0.p1"
    // ..

GrailsのReleaseプラグインをインストールする

プラグインのビルド、リポジトリへの公開は、このReleaseプラグインを使います。

Grails2系のcreate-pluginでプラグインプロジェクトを作成した場合は既にプロジェクトにインストールされているかと思いますが、そうでなければ自分でインストールする必要があります。

install-pluginコマンドでインストールせず、必ずBuildConfig.groovy上でプラグインを追加してexport設定を追加します。そうでないと、このマイプラグインをインストールしたときに、インストール先のプロジェクトもreleaseプラグインに推移的に依存するようになってしまいますので。

ちなみにAWSプラグインはinstall-pluginでreleaseプラグインをインストールしていたようなので、改造版ではこちらも修正しています。

// grails-app/conf/BuildConfig.groovy
// ...
grails.project.dependency.resolution = {
    // ...
    plugins {
        // ...
        build(':release:1.0.0.RC3') {
            export = false // このプラグインはインストール先のプロジェクトには不要
        }
    }
}

プラグインをがしかし実装

プラグインをオレオレに改造します。がしかし好きな機能を実装します。

Github上にMavenリポジトリを構築する

好きな機能は実装できましたか? ではプラグインを公開しましょう。

Github を Maven 公開リポジトリにする
を参考に、MavenリポジトリをGithub上に構築します。

おおざっぱに言えば、

  1. ローカルにフォルダを作ります(「D:\mvn」など)。
  2. そのフォルダをgitのリポジトリとして初期化します。
  3. そのリポジトリに「gh-pages」という名前のブランチを作ります。
  4. 作った「gh-pages」ブランチをgithubにプッシュします
  5. おわり

後は、このフォルダにMavenリポジトリ構造でファイルを追加してプッシュすれば、Github上にそのファイルを公開できるわけですね

ここでは、「D:\mvn」にgitのリポジトリを作ったものとします。

ローカルフォルダにGrailsプラグインをリリースする

先ほどgitリポジトリとして初期化したフォルダ「D:\mvn」にプラグインをリリースします。

Grailsのreleaseプラグインは、SubversionリポジトリやリモートのWebDAV Mavenリポジトリにプラグインをリリースできますが、ローカルにはき出すことも可能なようです。

リリース先の指定方法はreleaseプラグインのマニュアルに載っています。

プロジェクトのBuildConfig.groovyか、ユーザーのホームディレクトリにsettings.groovyというファイルを置いて設定することができます。

バージョン管理に入れるであろうBuildConfig.groovyに、ローカルのファイルパスを書き込むというのはダサい気がするので、私はsettings.groovyを使いました。以下のように設定します。

// ~/.grails/settings.groovy
grails.release.scm.enabled = false // プラグインのソースコードはリリースしない

grails.project.repos.default = "localRelease" // リリース先未指定時のリリース先
grails.project.repos.localRelease.url = "file:///D:/mvn" // リリース先"localRelease"のURL

設定が終わったら、プラグインのプロジェクトディレクトリに移動して、リリースコマンドを実行します。2

cd my-grails-plugin
grails publish-plugin

コマンドが正常に終了すれば、「D:\mvn」にプラグインのzipファイル、pomファイルなどが生成されているはずです。3

MavenリポジトリをGithubにプッシュ

「D:\mvn」に生成された全てのファイルをコミットし、github上にプッシュします。

これで、作成したプラグインをどこからでも使用できるようになりました。

公開したプラグインを使う

公開したプラグインは、前述のように「BuildConfig.groovy」にGithub上のプラグインリポジトリを追加すれば使用できます。

リポジトリのURLは、Githubユーザー名が「literalice」、プッシュしたMavenリポジトリのフォルダ名が「mvn」であれば、「http://literalice.github.com/mvn」となります。

// grails-app/conf/BuildConfig.groovy
// ...
grails.project.dependency.resolution = {
    // ...
    repositories {
        // ...
        // Github上のマイプラグインリポジトリを指定
        mavenRepo "http://literalice.github.com/mvn"
    }
}

# 上で指定したプラグインリポジトリからプラグインをインストール
cd grails-project
grails install-plugin myplugin 1.0.0.p1

Twitterとかで通知

使って欲しい人に向けて、プラグインのリリース情報を通知します。プラグインリポジトリのURLとプラグイン名、プラグインバージョンを教えてあげれば大丈夫なはず。

まとめ

これでもう、プラグインのバグ修正も機能追加も待つ必要ないですね。直して公開です。

わざわざGrailsの公式リポジトリにプラグインを公開する必要もないですね。プラグイン名とリポジトリのURLを一緒に教えてあげれば大丈夫です。

気が向きましたら、本家にpull requestとか、プラグインを公式リポジトリに公開とかするとよりナイスですね。

Githubの最大容量は300MBらしいですが、普通のプラグインはそんなに容量大きくならないので大丈夫じゃないでしょうか、多分。

G* Advent Calendar、7日目は@masanobuimaiさんです。



注1: AWSプラグインは、GrailsからAmazon Web Serviceを簡単に使えるようにするものですが、SESでメールを送信するときに文字セットを指定できなかったためパッチを当てて使っています。

注2: 本来であれば、

cd my-grails-plugin
grails publish-plugin --repository=localRelease
とすることで、リリース先を明示的に指定できるはずなのですが、私の環境ですと上手く動かなかったので、デフォルトのリリース先をsettings.groovyで設定して、リリース先を指定せずにリリースできるようにしています。

注3: 「WARNING: unknown protocol 'file' for repository」というワーニングが出るのが気になりますが…とりあえず、問題なくリリースできるようです。