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

Gradle入門

 Gradle入門

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