Tbpgr Blog

元エンジニア 人事 tbpgr(てぃーびー) のブログ

Gradle | Javaのpackage-info.javaを自動生成するGradleカスタムPluginを作成

概要

Javaのpackage-info.javaを自動生成するGradleカスタムPluginを作成

内容

下記の記事で作成した内容をGradleのカスタムPlugin化します。
RubyJavaのpackage-info.javaを一括生成するスクリプト
http://d.hatena.ne.jp/tbpg/20120808/1344447924

要件

・projectBasePathにプロジェクトディレクトリを設定
・srcBasePathにソースディレクトリを設定(\\src\\main\\javaなど ※今回はWin環境で作成しました)
・outputBasePathに出力の基準ディレクトリを設定(\\src\\main\\java\\jp\\co\\hogeなど。hogeより下の各ディレクトリに対してpackage-infoを出力)
・既にpackage-info.javaが存在する場合は上書きしない
・コンソールにファイルの作成状況を出力する
・package-info.javaの中身は以下

/**
 * "#{package_name}" package.
 *
 * <pre>
 * // TODO input package descriptiozn
 * </pre>
 * 
 */
package #{package_name};

ソースコード

build.gradle
def defaultEncoding = 'UTF-8'

apply plugin: 'groovy'
apply plugin: 'eclipse'

sourceCompatibility = 1.7
targetCompatibility = 1.7

group = 'gr.java_conf.tb.packageplugin'
archivesBaseName = 'packageplugin'
version = '1.0-SNAPSHOT'

repositories { mavenCentral() }

dependencies {
  compile gradleApi()
  groovy localGroovy()
}

apply plugin: 'maven'

uploadArchives {
  repositories {
    mavenDeployer {
      repository(url: 'file://' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath)
    }
  }
}

test { systemProperties 'property': 'value' }

uploadArchives {
  repositories { flatDir { dirs 'repos'
    } }
}
/PackageInfoPlugin/src/main/groovy/gr/java_conf/tb/packageplugin/PackageInfoPlugin.groovy
package gr.java_conf.tb.packageplugin

import org.gradle.api.Plugin
import org.gradle.api.Project

/**
 * PackageInfoJavaを生成するPlugin.
 *
 * @author tbpgr
 *
 */
class PackageInfoPlugin implements Plugin<Project> {

  @Override
  public void apply(Project target) {
    target.task('createPackageInfo', type: PackageInfoCreateTask)
  }
}
/PackageInfoPlugin/src/main/groovy/gr/java_conf/tb/packageplugin/PackageInfoCreateTask.groovy
package gr.java_conf.tb.packageplugin
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

/**
 * Package-info.javaを出力するタスク.
 *
 * @author tbpgr
 *
 */
class PackageInfoCreateTask extends DefaultTask {
  def PACKAGE_INFO = 'package-info.java'
  String projectBasePath = null;
  String srcBasePath = null;
  String outputBasePath = null;

  @TaskAction
  def createPackageInfo() {
    if (this.projectBasePath == null | this.outputBasePath == null | this.srcBasePath == null)
      throw new PackageInfoCreateTaskException("projectBasePath or outputBasePath or srcBasePath is null. you must setting these parameter")

    def outputBasePath = new File(projectBasePath + outputBasePath)

    outputBasePath.eachDirRecurse {
      if (it == outputBasePath)
        return
      if (existsPackageInfo(it))
        return

      def packageName = getPackageName(it)
      def javaDoc = getPackageInfoJavaDoc(packageName)
      def writer = new File(it, PACKAGE_INFO).newWriter('UTF-8')
      writer.writeLine(javaDoc)
      writer.close()

      println("${it}/${PACKAGE_INFO}")
    }

    println "package-info output complete!"
  }

  def String getPackageName(File currentFolder) {
    def String currentFolderPath = currentFolder.toString()
    def rootPackageIndex = currentFolderPath.indexOf(srcBasePath)
    def packageName = currentFolderPath.substring(rootPackageIndex + srcBasePath.size() + 1, currentFolderPath.size())
    return packageName.replaceAll(/[\/|\\]/, '.')
  }

  def boolean existsPackageInfo(File file) {
    return new File(file, PACKAGE_INFO).exists()
  }

  def String getPackageInfoJavaDoc(String path) {
    return """\
/**
 * ${path} package.
 *
 * <pre>
 * // TODO input package description
 * </pre>
 *
 */
package ${path};
"""
  }

  class PackageInfoCreateTaskException extends Exception {
    PackageInfoCreateTaskException(String message) {
      super(message)
    }
  }
}
/PackageInfoPlugin/src/main/resources/META-INF/gradle-plugins/packageplugin.properties
implementation-class=gr.java_conf.tb.packageplugin.PackageInfoPlugin

利用側プロジェクト

build.gradle

下記を追記する

buildscript {
  repositories {
    mavenRepo url: 'file://' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath
  }
  dependencies { classpath 'gr.java_conf.tb.packageplugin:packageplugin:1.0-SNAPSHOT' }
}

apply plugin: 'sample'
apply plugin: 'packageplugin'

createPackageInfo.doFirst {
  projectBasePath = projectDir.toString()
  // Gradleプロジェクトの標準構成ならこのままでよい
  srcBasePath = '\\src\\main\\java'
  // 下記に設定したパスより下の階層のパッケージのpackage-info.javaが作成される
  outputBasePath = "${srcBasePath}\\org\\gradle"
}

画像

利用側プロジェクト実行前

利用側プロジェクトGradle Tasksビュー

自作したPackageInfoPluginのcreatePackageInfoタスクが表示されている

実行時コンソール
[sts] -----------------------------------------------------
[sts] Starting Gradle build for the following tasks: 
[sts]      :createPackageInfo
[sts] -----------------------------------------------------
:createPackageInfo
CoberturaSample\src\main\java\org\gradle\hage/package-info.java
CoberturaSample\src\main\java\org\gradle\hoge/package-info.java
CoberturaSample\src\main\java\org\gradle\hoge\child_hoge/package-info.java
package-info output complete!

BUILD SUCCESSFUL

Total time: 0.277 secs
[sts] -----------------------------------------------------
[sts] Build finished succesfully!
[sts] Time taken: 0 min, 0 sec
[sts] -----------------------------------------------------
利用側プロジェクト実行後

org.gradleより下の各フォルダ=hage,hoge,hoge.child_hogeのそれぞれに
package-info.javaが出力されている。

参照

上記のプロジェクトはGitHubに公開中です。
https://github.com/tbpgr/PackageInfoPlugin