へぬもへメモ

https://twitter.com/henumohe

gitとgradleでeclipseのプロジェクト設定を管理する

警告やフォーマッター等のeclipse設定を、個々人の設定に依存しない形で管理できるようにしてみた。

方針

  • 基本的には、プロジェクト設定をgitに突っ込んでしまう
  • gradleが生成するファイルはgitに入れず、各々でgradle eclipseを叩いてもらう
    • classpathの設定値が環境ごとに異なる点への配慮
    • gradleでeclipse関連タスクを叩いた時の冪等性を保ちたい

以下、自分のGitHubより抜粋。

フォルダ構成

│  .checkstyle
│  .classpath
│  .fbprefs
│  .gitignore
│  .project
│  build.gradle
│  README.md
│
├─.settings
│      checkstyle.xml
│      findbugs.xml
│      org.eclipse.core.resources.prefs
│      org.eclipse.core.runtime.prefs
│      org.eclipse.jdt.launching.prefs
│      org.eclipse.jdt.ui.prefs
│      org.eclipse.ltk.core.refactoring.prefs
│      org.eclipse.pde.prefs
│      org.eclipse.wst.sse.core.prefs
│      org.eclipse.wst.validation.prefs
│
├─eclipse-settings-template
│      org.eclipse.jdt.core.prefs
│
└─src
    └─main
        └─java
            └─....

eclipseの設定は、@daisuke_m氏のMaven Archetypeの中にある設定を参考にしている。見つけたばかりなので細かい設定はまだ変えてないが、とりあえず以下の3点だけ変更した。

  • Javaのバージョンを1.6から1.8に変更(grepで4ヶ所ほど置換)
  • checkstyle.xmlから、5.6で廃止された設定を削除(<module name="DoubleCheckedLocking">)
  • maven関連の設定を削除( pom.xml, org.maven.ide.eclipse.prefs)

.gitignoreの内容は以下。githubjavaプロジェクト作った時のgitignoreに追記する形で作成。

*.class

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

#以下、追加内容

.gradle

# eclpse settings generated by `gradle eclipse`
.project
.classpath
.settings/org.eclipse.jdt.core.prefs

gradle eclipseを叩くと、サブタスクのeclipseClasspath, eclipseProject, eclipseJdtが実行され、上記.gitignore内の3ファイルが生成される。この3ファイルはcleanEclipseタスクによって、いとも簡単に初期化されてしまうので、gitで管理せず、gradleで生成するようにした。

/* ...省略... */
eclipse {
    classpath {
        downloadSources = true
        downloadJavadoc = true
        defaultOutputDir = file('build/classes')
    }
    jdt {
        file {
            def props = new Properties()
            props.load(new FileInputStream('eclipse-settings-template/org.eclipse.jdt.core.prefs'))
            withProperties { properties -> properties.putAll(props) }
        }
    }
    project {
        natures 'net.sf.eclipsecs.core.CheckstyleNature'
        buildCommand 'net.sf.eclipsecs.core.CheckstyleBuilder'
        //natures 'edu.umd.cs.findbugs.plugin.eclipse.findbugsNature'
        //buildCommand 'edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder'

        file.withXml {
            def node = it.asNode()

            def fr = node.get('filteredResources')
            if(fr) {
                node.remove(fr)
            }
            def fi, ma
            fi = node.appendNode('filteredResources').appendNode('filter')
            fi.appendNode('id', '1359048889071')
            fi.appendNode('name', '')
            fi.appendNode('type', '30')
            ma = fi.appendNode('matcher')
            ma.appendNode('id', 'org.eclipse.ui.ide.multiFilter')
            ma.appendNode('arguments', '1.0-projectRelativePath-matches-false-false-build')

            fi = node.appendNode('filteredResources').appendNode('filter')
            fi.appendNode('id', '1399217844078')
            fi.appendNode('name', '')
            fi.appendNode('type', '30')
            ma = fi.appendNode('matcher')
            ma.appendNode('id', 'org.eclipse.ui.ide.multiFilter')
            ma.appendNode('arguments', '1.0-name-matches-false-false-eclipse-settings-template')
        }
    }
}

org.eclipse.jdt.core.prefsは設定内容が多いので、eclipse-settings-template/org.eclipse.jdt.core.prefsをloadして、設定をマージしている。

findbugsはjava8未対応なので、一旦コメントアウトしている。最初はgradle.propertiesにjavaVersion明記してハンドリングしてたけど、もうjava7使うことないだろうからやめた。

.projectのfilteredResourcesを追加するAPIがgradleに用意されてないので、springのgradle設定を参考にして、直接Xmlに要素を追加している。正直この粒度でスクリプトを書くのは面倒なので、.projectや.classpathも、org.eclipse.jdt.core.prefsと同様にテンプレートをマージしたほうが楽そう。たぶんgroovy.util.XmlSlurperでやれる。

今後

ここまでやっておけば、git checkoutしてgradle eclipse叩いてeclipseからプロジェクトをimportして、どこでも同じeclipse設定を使うことができる。 残りの課題は以下。

  • IntelliJ IDEA環境との共存
    • eclipse, ideaそれぞれでテンプレートディレクトリを作って、タスク叩くと中のファイルがルートディレクトリにコピーされるようにすればいい?
    • ときたまIntelliJ使いたい欲が高まるので、その時に対処する
  • 勝手にeclipse設定変更してpushされるのを防ぐ方法
    • 何かのcommitに紛れて設定変更されるとつらい。↑の方法で解決できそうな気がする
    • テンプレートディレクトリ用意した上で、そこへのpush権限を絞れればよさげ。gitでできるだろうか?