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

Gradle入門

 Gradle入門

05162bc961c3654218bf1839974a4f35?s=128

Benoît Quenaudon

August 19, 2016
Tweet

More Decks by Benoît Quenaudon

Other Decks in Programming

Transcript

  1. 入門

  2. • 2007年: 初リリース • OS: クロスプラットフォーム • 種類: ビルドツール •

    サイト: www.gradle.org • 2013年: Android に選ばれた
  3. Gradle Tasks • Gradleはタスクベース。 ◦ タスクって?なんでもあり。 ◦ 例:javac, cp /src

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

    で生成 ◦ gradlew.sh Linux/OS X ◦ gradlew.bat Windows ◦ gradle/wrapper/gradle-wrapper.properties ▪ 環境変数 ▪ Gradleバージョン ◦ gradle/wrapper/gradle-wrapper.jar
  5. gradlew(rapper) • gradle のインストール確認 ◦ インストールされていない場合properties に従って妥当 なバージョンの gradle をダウンロードする

    ⇒ どの環境でも同じバージョンで実行される事は保 証できる
  6. タスク実行 • タスク実行 ◦ 例 initというタスク:./gradlew init • タスク一覧の表示 ◦

    ./gradlew tasks
  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
  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 プラグインを適用
  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 プラグインの設定
  10. 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 タスクを定義
  11. 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)
  12. 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) • 命令はプラグインがやる
  13. 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 拡張
  14. • JVMのスクリプト言語 • オブジェクト指向 • 動的言語 • Java ⊆ Groovy

    ほぼ
  15. Groovy:Java Class class JavaGreeter { public void sayHello() { System.out.println("Hello

    Java!"); } } JavaGreeter greeter = new JavaGreeter() greeter.sayHello() // Hello Java!
  16. 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
  17. 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
  18. Groovy /* セミコロン 不要 */ def doubleIt(n) { n +

    n // return 不要 } foo = 5 println "doubleIt($foo) = ${doubleIt(foo)}" // doubleIt(5) = 10 println "${doubleIt('foobar')}" // foobarfoobar
  19. /* 関数の呼び出しに括弧不要:引数が一つ以上かつ不明でなければ */ 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 // 正常
  20. Groovy:Closure /* Closure:引数や変数に渡せるメソッド(メソッドポインター) */ def foo = "カレー" def myClosure

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

    -> x + x } def applyTwice(func, arg){ func(func(arg)) } println applyTwice(doubleIt, 2) // 8 ((2 + 2) + 4)
  22. 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" }
  23. 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: まいどおおきに
  24. Groovy:Delegate /* closure に delegate オブジェクトを定義できる。 closure に存在しないリファレンスは delegate に対して評価される

    */ def greetingClosure = { greeting = "またおまえか" printGreeting() } greetingClosure() // greeting が not defined でエラー greetingClosure.delegate = myRestaurant greetingClosure() // Greeting: またおまえか
  25. Groovy • まだまだある。 ⇒ Learn Groovy in Y minutes. ◦

    https://learnxinyminutes.com/docs/groovy/
  26. Gradle:タスク定義 • build.gradle 全体の delegate は project オブ ジェクトになる。 ◦

    project.task("A") ⇒ task("A") ◦ task("A") ⇒ task "A" ◦ task "A" ⇒ task A
  27. 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"
  28. Gradle:設定 closure // Configuration Closure を利用 // Gradle は変数のセッターを用意してくれるので //

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

    実行順番を設定する • shouldRunAfter: 実行順番を設定する ◦ 無視される場合もある。例:循環が発生する時とか
  30. Gradle Task:依存関係 デモ タイム Yeah? https://github.dev.cybozu.co.jp/benoit/gradle-benkyokai/tree/master/dependencies

  31. Typed Task • タイプ無し:ad hoc task ◦ task myTask {}

    • タイプ有り:typed task ◦ コアタスクを拡張するイメージ ◦ task myTask(type: aType) {}
  32. Typed Task 例、ファイルをコピーするタスク: task copy(type: Copy) { description 'resourceフォルダをtargetフォルダへコピーする' from

    'resources' into 'target' } ※宣言的:どうやってコピーするかは関係ない。
  33. Incremental Builds • 対応済のものはスキップする方針。 • どうやって判断する? ◦ Inputsのスナップショット ▪ 変更ある

    ⇒ 実行 ▪ 変更ない ⇒ Outputs確認 ◦ Outputsのスナップショット ▪ 変更ある ⇒ 実行 ▪ 変更ない ⇒ UP_TO_DATE ⇒ スキップする
  34. Parameterised Task • 3つのパラメータ種 ◦ CLI ◦ gradle.properties ◦ プロパティ拡張

    ※プロパティ拡張>CLI>.properties
  35. CLI // build.gradle task hello << { println world }

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

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

    // 全ドメインオブジェクトに world を追加する ext { world = "value" } # shell ./gradlew hello
  38. Custom Task Type デモ タイム Yeah? https://github.dev.cybozu.co.jp/benoit/gradle-benkyokai/tree/master/custom-type

  39. Custom Task Type class MyTask extends DefaultTask { String feeling

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

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

    れるかを確認して • 各PJのインスタンスを 作成 • どのタスクがあるか • 依存確認などのため • 各PJのビルドスクリプト が実行される ◦ build.gradle • タスクが生成され • 設定される • 生成されたタスクを • 依存関係に従って • 順番に実行する
  42. Gradle Plugin • コアGradleが提供している機能が少ない • Plugin でできる事を増やす事が可能 • モジュール化がやりやすい •

    build.gradle は宣言のみにできる
  43. Gradle Plugin:Type • Script Plugin ◦ 他gradleスクリプトをインクルードするイメージ ◦ 例:apply from:

    'other.gradle' • Binary Plugin ◦ Plugin インターフェースを実装したクラス ◦ 例:apply plugin: 'java'
  44. Java Plugin • 用意されているタスク ◦ コンパイル ◦ Jar ◦ ドキュメンテーション

    ◦ テスト ◦ レポート
  45. Java Build Lifecycle build check test testClasses process Test Resources

    compile Test Java assemble jar classes process Resources compile Java
  46. Java Plugin デモ タイム Yeah? https://github.dev.cybozu.co.jp/benoit/gradle-benkyokai/tree/master/java-plugin

  47. ⇒ Java Plugin:Convention / src test java resources main java

    resources / build reports classes main test build tests test-results
  48. 依存管理: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' } } }
  49. 依存管理: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' } } }
  50. 依存管理: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' } } }
  51. 依存管理: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' } } }
  52. 依存管理: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' } } }
  53. 依存管理: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' } } }
  54. 依存管理: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' }
  55. 依存管理: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' }
  56. 依存管理: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' }
  57. 依存管理: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' }
  58. 依存管理: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' }
  59. 依存管理: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' }
  60. Dependencies Report ./gradlew dependencyInsight

  61. Gradle:Dry Run -m $ ./gradlew -m assemble :compileJava SKIPPED :processResources

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

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

    ◦ 3.0(8月15日〜) からデフォルトで有効 • CIでは無効するのがおすすめ ◦ gradle.properties:org.gradle.daemon=false
  64. Gradle Android Plugin ? Not today

  65. Gradle 入門 以上

  66. 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