Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Gradle入門

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

 Gradle入門

Avatar for Benoît Quenaudon

Benoît Quenaudon

August 19, 2016
Tweet

More Decks by Benoît Quenaudon

Other Decks in Programming

Transcript

  1. Gradle Tasks • Gradleはタスクベース。 ◦ タスクって?なんでもあり。 ◦ 例:javac, cp /src

    /out, print `hello`… • タスク同士の依存関係有り • インプットとアウトプットの設定有り
  2. CLI Gradle • gradle コマンド • ラッパー $~ gradle wrapper

    で生成 ◦ gradlew.sh Linux/OS X ◦ gradlew.bat Windows ◦ gradle/wrapper/gradle-wrapper.properties ▪ 環境変数 ▪ Gradleバージョン ◦ gradle/wrapper/gradle-wrapper.jar
  3. Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21

    buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle
  4. Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21

    buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle • android プラグインを適用
  5. Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21

    buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle • android プラグインを適用 • android プラグインの設定
  6. Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21

    buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle • android プラグインを適用 • android プラグインの設定 • hello タスクを定義
  7. Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21

    buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle • android プラグインを適用 • android プラグインの設定 • hello タスクを定義 • 宣言型(declarative)
  8. Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21

    buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle • android プラグインを適用 • android プラグインの設定 • hello タスクを定義 • 宣言型(declarative) • 命令はプラグインがやる
  9. Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21

    buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle • android プラグインを適用 • android プラグインの設定 • hello タスクを定義 • 宣言型(declarative) • 命令はプラグインがやる • 言語:Gradle DSL ◦ Groovy 拡張
  10. Groovy:Java Class class JavaGreeter { public void sayHello() { System.out.println("Hello

    Java!"); } } JavaGreeter greeter = new JavaGreeter() greeter.sayHello() // Hello Java!
  11. Groovy /* 動的 ⇒ 型チェックはランタイムに。 型定義も任意。*/ def foo = 6.5

    // String interpolation println "foo has value: $foo" // foo has value: 6.5 println "Let's do some math. 5 + 6 = ${5 + 6}" // Let's do some math. 5 + 6 = 11
  12. Groovy /* 型変更可能 や 型の確認もできる */ println "foo is of

    type: ${foo.class} and has value: $foo" // foo is of type: java.math.BigDecimal and has value: 6.5 foo = "a string" println "foo is now of type: ${foo.class} and has value: $foo" // foo is now of type: java.lang.String and has value: a string
  13. Groovy /* セミコロン 不要 */ def doubleIt(n) { n +

    n // return 不要 } foo = 5 println "doubleIt($foo) = ${doubleIt(foo)}" // doubleIt(5) = 10 println "${doubleIt('foobar')}" // foobarfoobar
  14. /* 関数の呼び出しに括弧不要:引数が一つ以上かつ不明でなければ */ def noArgs() { println "Called the no

    args function" } def oneArg(x) { x } def twoArgs(x, y) { x + y } oneArg 500 // 括弧なし twoArgs 200, 300 // 括弧なし noArgs // エラー noArgs() // 引数ないため括弧必須 twoArgs oneArg 500, 200 // 不明でエラー twoArgs oneArg(500), 200 // 正常
  15. Groovy:Closure /* Closure:引数や変数に渡せるメソッド(メソッドポインター) */ def foo = "カレー" def myClosure

    = { println "Closureからの$foo" } myClosure() // Closureからのカレー foo = "寿司" def bar = myClosure bar() // Closureからの寿司
  16. Groovy:Closure /* Closure に引数を渡すとき */ def doubleIt = { x

    -> x + x } def applyTwice(func, arg){ func(func(arg)) } println applyTwice(doubleIt, 2) // 8 ((2 + 2) + 4)
  17. Groovy:List ✠ Closure def myList = ["カレー", "寿司", "コカ・コーラ"] def

    printItem = {item -> println "List item: $item"} myList.each(printItem) // List item: カレー // List item: 寿司 // List item: コカ・コーラ /* インライン Closure */ myList.each { println "引数のデフォルト名は it : $it" }
  18. Groovy:Class /* java Class の sugar */ class Restaurant {

    String greeting = "いらっしゃい" def printGreeting() { println "Greeting: $greeting" } } def myRestaurant = new Restaurant() myRestaurant.printGreeting() // Greeting: いらっしゃい myRestaurant.greeting = "まいどおおきに" myRestaurant.printGreeting() // Greeting: まいどおおきに
  19. Groovy:Delegate /* closure に delegate オブジェクトを定義できる。 closure に存在しないリファレンスは delegate に対して評価される

    */ def greetingClosure = { greeting = "またおまえか" printGreeting() } greetingClosure() // greeting が not defined でエラー greetingClosure.delegate = myRestaurant greetingClosure() // Greeting: またおまえか
  20. Gradle:タスク定義 • build.gradle 全体の delegate は project オブ ジェクトになる。 ◦

    project.task("A") ⇒ task("A") ◦ task("A") ⇒ task "A" ◦ task "A" ⇒ task A
  21. Gradle:タスク定義 // build.gradle println "Script start" task A A.description =

    "タスク一覧にでる説明文" A.group = "タスク一覧のヘッダーになる" A.doLast { println "Do last" } A.doFirst { println "Do first" } A.leftShift { println "Do leftShift" } A << { println "Do crazy leftShift" } println "Script end"
  22. Gradle:設定 closure // Configuration Closure を利用 // Gradle は変数のセッターを用意してくれるので //

    description = "" も可能で description("") も可能。 // 例外:List の場合は = で値を設定するしかない task A { description "タスク一覧にでる説明文" group "タスク一覧のヘッダーになる" doLast { println "Do last" } }
  23. Gradle Task:依存関係 • dependsOn: 自分の実行前に実行する • finalizedBy: 自分の実行後に実行する • mustRunAfter:

    実行順番を設定する • shouldRunAfter: 実行順番を設定する ◦ 無視される場合もある。例:循環が発生する時とか
  24. Typed Task • タイプ無し:ad hoc task ◦ task myTask {}

    • タイプ有り:typed task ◦ コアタスクを拡張するイメージ ◦ task myTask(type: aType) {}
  25. Incremental Builds • 対応済のものはスキップする方針。 • どうやって判断する? ◦ Inputsのスナップショット ▪ 変更ある

    ⇒ 実行 ▪ 変更ない ⇒ Outputs確認 ◦ Outputsのスナップショット ▪ 変更ある ⇒ 実行 ▪ 変更ない ⇒ UP_TO_DATE ⇒ スキップする
  26. CLI // build.gradle task hello << { println world }

    # shell ./gradlew hello -Pworld=value # value
  27. gradle.properties // build.gradle task hello << { println world }

    # ./build.properties # ~/.gradle/build.properties world = "value" # shell ./gradlew hello
  28. プロパティ拡張 // build.gradle task hello << { println world }

    // 全ドメインオブジェクトに world を追加する ext { world = "value" } # shell ./gradlew hello
  29. Custom Task Type class MyTask extends DefaultTask { String feeling

    @TaskAction void myAction() { println "話寿司 は ${feeling}" } } task sushi(type: MyTask) su.feeling "好き"
  30. Logging Levels • println = quiet • エラー時 ◦ スタックトレースはでない

    ◦ stacktrace ⇒ -s ◦ full-stacktrace ⇒ -S ▪ Gradleコアまででる Debug Info Warning Lifecycle Error Quiet -q デフォルト -i -d
  31. Build Lifecycle Initialization Configuration Execution • シングルPJもマルチPJ もあるため • ビルドにどのPJが絡ま

    れるかを確認して • 各PJのインスタンスを 作成 • どのタスクがあるか • 依存確認などのため • 各PJのビルドスクリプト が実行される ◦ build.gradle • タスクが生成され • 設定される • 生成されたタスクを • 依存関係に従って • 順番に実行する
  32. Gradle Plugin:Type • Script Plugin ◦ 他gradleスクリプトをインクルードするイメージ ◦ 例:apply from:

    'other.gradle' • Binary Plugin ◦ Plugin インターフェースを実装したクラス ◦ 例:apply plugin: 'java'
  33. Java Build Lifecycle build check test testClasses process Test Resources

    compile Test Java assemble jar classes process Resources compile Java
  34. ⇒ Java Plugin:Convention / src test java resources main java

    resources / build reports classes main test build tests test-results
  35. 依存管理:Repo repositories { // ローカル flatDir { dirs 'libs' }

    // 有名レポ mavenCentral() jcenter() mavenLocal() // ~/.m2/repository // url 指定、http, sftp, file:///... maven { url 'https://maven.fabric.io/public' } // 認証 ivy { url 'https://curry.yummy.com/ credentials { username 'user' password 'secret' } } }
  36. 依存管理:Repo repositories { // ローカル flatDir { dirs 'libs' }

    // 有名レポ mavenCentral() jcenter() mavenLocal() // ~/.m2/repository // url 指定、http, sftp, file:///... maven { url 'https://maven.fabric.io/public' } // 認証 ivy { url 'https://curry.yummy.com/ credentials { username 'user' password 'secret' } } }
  37. 依存管理:Repo repositories { // ローカル flatDir { dirs 'libs' }

    // 有名レポ mavenCentral() jcenter() mavenLocal() // ~/.m2/repository // url 指定、http, sftp, file:///... maven { url 'https://maven.fabric.io/public' } // 認証 ivy { url 'https://curry.yummy.com/ credentials { username 'user' password 'secret' } } }
  38. 依存管理:Repo repositories { // ローカル flatDir { dirs 'libs' }

    // 有名レポ mavenCentral() jcenter() mavenLocal() // ~/.m2/repository // url 指定、http, sftp, file:///... maven { url 'https://maven.fabric.io/public' } // 認証 ivy { url 'https://curry.yummy.com/ credentials { username 'user' password 'secret' } } }
  39. 依存管理:Repo repositories { // ローカル flatDir { dirs 'libs' }

    // 有名レポ mavenCentral() jcenter() mavenLocal() // ~/.m2/repository // url 指定、http, sftp, file:///... maven { url 'https://maven.fabric.io/public' } // 認証 ivy { url 'https://curry.yummy.com/ credentials { username 'user' password 'secret' } } }
  40. 依存管理:Repo repositories { // ローカル flatDir { dirs 'libs' }

    // 有名レポ mavenCentral() jcenter() mavenLocal() // ~/.m2/repository // url 指定、http, sftp, file:///... maven { url 'https://maven.fabric.io/public' } // 認証 ivy { url 'https://curry.yummy.com/ credentials { username 'user' password 'secret' } } }
  41. 依存管理:Dep dependencies { // ファイル参照 compile files('libs/foo.jar', 'libs/bar.jar') // 他PJを参照

    compile project(':someProject') // レポジトリから参照、長い版と省略 compile group: 'com.google.android', name:'android', version:'2.1.2' compile 'com.google.android:android:2.1.2' // テストビルド用 testCompile junit: 'junit:junit:4.12' }
  42. 依存管理:Dep dependencies { // ファイル参照 compile files('libs/foo.jar', 'libs/bar.jar') // 他PJを参照

    compile project(':someProject') // レポジトリから参照、長い版と省略 compile group: 'com.google.android', name:'android', version:'2.1.2' compile 'com.google.android:android:2.1.2' // テストビルド用 testCompile junit: 'junit:junit:4.12' }
  43. 依存管理:Dep dependencies { // ファイル参照 compile files('libs/foo.jar', 'libs/bar.jar') // 他PJを参照

    compile project(':someProject') // レポジトリから参照、長い版と省略 compile group: 'com.google.android', name:'android', version:'2.1.2' compile 'com.google.android:android:2.1.2' // テストビルド用 testCompile junit: 'junit:junit:4.12' }
  44. 依存管理:Dep dependencies { // ファイル参照 compile files('libs/foo.jar', 'libs/bar.jar') // 他PJを参照

    compile project(':someProject') // レポジトリから参照、長い版と省略 compile group: 'com.google.android', name:'android', version:'2.1.2' compile 'com.google.android:android:2.1.2' // テストビルド用 testCompile junit: 'junit:junit:4.12' }
  45. 依存管理:Dep dependencies { // ファイル参照 compile files('libs/foo.jar', 'libs/bar.jar') // 他PJを参照

    compile project(':someProject') // レポジトリから参照、長い版と省略 compile group: 'com.google.android', name:'android', version:'2.1.2' compile 'com.google.android:android:2.1.2' // テストビルド用 testCompile junit: 'junit:junit:4.12' }
  46. 依存管理:Dep dependencies { // ファイル参照 compile files('libs/foo.jar', 'libs/bar.jar') // 他PJを参照

    compile project(':someProject') // レポジトリから参照、長い版と省略 compile group: 'com.google.android', name:'android', version:'2.1.2' compile 'com.google.android:android:2.1.2' // テストビルド用 testCompile junit: 'junit:junit:4.12' }
  47. Gradle:Dry Run -m $ ./gradlew -m assemble :compileJava SKIPPED :processResources

    SKIPPED :classes SKIPPED :jar SKIPPED :assemble SKIPPED BUILD SUCCESSFUL
  48. Gradle:Dry Run -m $ ./gradlew -m assemble :compileJava SKIPPED :processResources

    SKIPPED :classes SKIPPED :jar SKIPPED :assemble SKIPPED BUILD SUCCESSFUL
  49. Gradle Daemon • GradleはJVM上で動くので起動に時間かかる ◦ いくつかのライブラリも必要で更にかかる • Daemonを使う事でいろいろキャッシュされる • デフォルトで無効

    ◦ 3.0(8月15日〜) からデフォルトで有効 • CIでは無効するのがおすすめ ◦ gradle.properties:org.gradle.daemon=false
  50. Gradle 入門:Reference • Udacity コース ◦ https://www.udacity.com/course/gradle-for-android-and-java--ud867 • Gradle ◦

    http://gradle.org/ • Gradle vs Maven ◦ https://gradle.org/maven_vs_gradle/ • デモのレポジトリ ◦ https://github.dev.cybozu.co.jp/benoit/gradle-benkyokai