Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Gradle入門
Search
Benoît Quenaudon
August 19, 2016
Programming
1
260
Gradle入門
Benoît Quenaudon
August 19, 2016
Tweet
Share
More Decks by Benoît Quenaudon
See All by Benoît Quenaudon
36・15 Cash App
oldergod
1
180
Sweet Architecture
oldergod
1
360
Architecture at Scale (droidconNYC 2022)
oldergod
2
600
Managing gRPC with Wire
oldergod
2
520
Wire & Proto3
oldergod
0
79
Effective Reactive Architecture
oldergod
2
210
Wire 3 : Tackling gRPC with Kotlin
oldergod
0
970
Server Driven UI Workflow
oldergod
2
490
Applying Rx Best Practices to Your Architecture
oldergod
1
230
Other Decks in Programming
See All in Programming
Datadog Workflow Automation で圧倒的価値提供
showwin
1
300
pylint custom ruleで始めるレビュー自動化
shogoujiie
0
160
コミュニティ駆動 AWS CDK ライブラリ「Open Constructs Library」 / community-cdk-library
gotok365
2
250
GoとPHPのインターフェイスの違い
shimabox
2
210
第3回関東Kaggler会_AtCoderはKaggleの役に立つ
chettub
3
1.2k
もう少しテストを書きたいんじゃ〜 #phpstudy
o0h
PRO
19
4.2k
.NET Frameworkでも汎用ホストが使いたい!
tomokusaba
0
200
Jakarta EE meets AI
ivargrimstad
0
560
iOSでQRコード生成奮闘記
ktcryomm
2
120
新宿駅構内を三人称視点で探索してみる
satoshi7190
2
120
LINE messaging APIを使ってGoogleカレンダーと連携した予約ツールを作ってみた
takumakoike
0
130
React 19アップデートのために必要なこと
uhyo
8
1.6k
Featured
See All Featured
Making Projects Easy
brettharned
116
6k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2.1k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.2k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
366
25k
GitHub's CSS Performance
jonrohan
1030
460k
We Have a Design System, Now What?
morganepeng
51
7.4k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
Speed Design
sergeychernyshev
27
810
Facilitating Awesome Meetings
lara
53
6.3k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Transcript
入門
• 2007年: 初リリース • OS: クロスプラットフォーム • 種類: ビルドツール •
サイト: www.gradle.org • 2013年: Android に選ばれた
Gradle Tasks • Gradleはタスクベース。 ◦ タスクって?なんでもあり。 ◦ 例:javac, cp /src
/out, print `hello`… • タスク同士の依存関係有り • インプットとアウトプットの設定有り
CLI Gradle • gradle コマンド • ラッパー $~ gradle wrapper
で生成 ◦ gradlew.sh Linux/OS X ◦ gradlew.bat Windows ◦ gradle/wrapper/gradle-wrapper.properties ▪ 環境変数 ▪ Gradleバージョン ◦ gradle/wrapper/gradle-wrapper.jar
gradlew(rapper) • gradle のインストール確認 ◦ インストールされていない場合properties に従って妥当 なバージョンの gradle をダウンロードする
⇒ どの環境でも同じバージョンで実行される事は保 証できる
タスク実行 • タスク実行 ◦ 例 initというタスク:./gradlew init • タスク一覧の表示 ◦
./gradlew tasks
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
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 プラグインを適用
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 プラグインの設定
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 タスクを定義
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 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 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 拡張
• JVMのスクリプト言語 • オブジェクト指向 • 動的言語 • Java ⊆ Groovy
ほぼ
Groovy:Java Class class JavaGreeter { public void sayHello() { System.out.println("Hello
Java!"); } } JavaGreeter greeter = new JavaGreeter() greeter.sayHello() // Hello Java!
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
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
Groovy /* セミコロン 不要 */ def doubleIt(n) { n +
n // return 不要 } foo = 5 println "doubleIt($foo) = ${doubleIt(foo)}" // doubleIt(5) = 10 println "${doubleIt('foobar')}" // foobarfoobar
/* 関数の呼び出しに括弧不要:引数が一つ以上かつ不明でなければ */ 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 // 正常
Groovy:Closure /* Closure:引数や変数に渡せるメソッド(メソッドポインター) */ def foo = "カレー" def myClosure
= { println "Closureからの$foo" } myClosure() // Closureからのカレー foo = "寿司" def bar = myClosure bar() // Closureからの寿司
Groovy:Closure /* Closure に引数を渡すとき */ def doubleIt = { x
-> x + x } def applyTwice(func, arg){ func(func(arg)) } println applyTwice(doubleIt, 2) // 8 ((2 + 2) + 4)
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" }
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: まいどおおきに
Groovy:Delegate /* closure に delegate オブジェクトを定義できる。 closure に存在しないリファレンスは delegate に対して評価される
*/ def greetingClosure = { greeting = "またおまえか" printGreeting() } greetingClosure() // greeting が not defined でエラー greetingClosure.delegate = myRestaurant greetingClosure() // Greeting: またおまえか
Groovy • まだまだある。 ⇒ Learn Groovy in Y minutes. ◦
https://learnxinyminutes.com/docs/groovy/
Gradle:タスク定義 • build.gradle 全体の delegate は project オブ ジェクトになる。 ◦
project.task("A") ⇒ task("A") ◦ task("A") ⇒ task "A" ◦ task "A" ⇒ task A
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"
Gradle:設定 closure // Configuration Closure を利用 // Gradle は変数のセッターを用意してくれるので //
description = "" も可能で description("") も可能。 // 例外:List の場合は = で値を設定するしかない task A { description "タスク一覧にでる説明文" group "タスク一覧のヘッダーになる" doLast { println "Do last" } }
Gradle Task:依存関係 • dependsOn: 自分の実行前に実行する • finalizedBy: 自分の実行後に実行する • mustRunAfter:
実行順番を設定する • shouldRunAfter: 実行順番を設定する ◦ 無視される場合もある。例:循環が発生する時とか
Gradle Task:依存関係 デモ タイム Yeah? https://github.dev.cybozu.co.jp/benoit/gradle-benkyokai/tree/master/dependencies
Typed Task • タイプ無し:ad hoc task ◦ task myTask {}
• タイプ有り:typed task ◦ コアタスクを拡張するイメージ ◦ task myTask(type: aType) {}
Typed Task 例、ファイルをコピーするタスク: task copy(type: Copy) { description 'resourceフォルダをtargetフォルダへコピーする' from
'resources' into 'target' } ※宣言的:どうやってコピーするかは関係ない。
Incremental Builds • 対応済のものはスキップする方針。 • どうやって判断する? ◦ Inputsのスナップショット ▪ 変更ある
⇒ 実行 ▪ 変更ない ⇒ Outputs確認 ◦ Outputsのスナップショット ▪ 変更ある ⇒ 実行 ▪ 変更ない ⇒ UP_TO_DATE ⇒ スキップする
Parameterised Task • 3つのパラメータ種 ◦ CLI ◦ gradle.properties ◦ プロパティ拡張
※プロパティ拡張>CLI>.properties
CLI // build.gradle task hello << { println world }
# shell ./gradlew hello -Pworld=value # value
gradle.properties // build.gradle task hello << { println world }
# ./build.properties # ~/.gradle/build.properties world = "value" # shell ./gradlew hello
プロパティ拡張 // build.gradle task hello << { println world }
// 全ドメインオブジェクトに world を追加する ext { world = "value" } # shell ./gradlew hello
Custom Task Type デモ タイム Yeah? https://github.dev.cybozu.co.jp/benoit/gradle-benkyokai/tree/master/custom-type
Custom Task Type class MyTask extends DefaultTask { String feeling
@TaskAction void myAction() { println "話寿司 は ${feeling}" } } task sushi(type: MyTask) su.feeling "好き"
Logging Levels • println = quiet • エラー時 ◦ スタックトレースはでない
◦ stacktrace ⇒ -s ◦ full-stacktrace ⇒ -S ▪ Gradleコアまででる Debug Info Warning Lifecycle Error Quiet -q デフォルト -i -d
Build Lifecycle Initialization Configuration Execution • シングルPJもマルチPJ もあるため • ビルドにどのPJが絡ま
れるかを確認して • 各PJのインスタンスを 作成 • どのタスクがあるか • 依存確認などのため • 各PJのビルドスクリプト が実行される ◦ build.gradle • タスクが生成され • 設定される • 生成されたタスクを • 依存関係に従って • 順番に実行する
Gradle Plugin • コアGradleが提供している機能が少ない • Plugin でできる事を増やす事が可能 • モジュール化がやりやすい •
build.gradle は宣言のみにできる
Gradle Plugin:Type • Script Plugin ◦ 他gradleスクリプトをインクルードするイメージ ◦ 例:apply from:
'other.gradle' • Binary Plugin ◦ Plugin インターフェースを実装したクラス ◦ 例:apply plugin: 'java'
Java Plugin • 用意されているタスク ◦ コンパイル ◦ Jar ◦ ドキュメンテーション
◦ テスト ◦ レポート
Java Build Lifecycle build check test testClasses process Test Resources
compile Test Java assemble jar classes process Resources compile Java
Java Plugin デモ タイム Yeah? https://github.dev.cybozu.co.jp/benoit/gradle-benkyokai/tree/master/java-plugin
⇒ Java Plugin:Convention / src test java resources main java
resources / build reports classes main test build tests test-results
依存管理: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' } } }
依存管理: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' } } }
依存管理: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' } } }
依存管理: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' } } }
依存管理: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' } } }
依存管理: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' } } }
依存管理: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' }
依存管理: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' }
依存管理: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' }
依存管理: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' }
依存管理: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' }
依存管理: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' }
Dependencies Report ./gradlew dependencyInsight
Gradle:Dry Run -m $ ./gradlew -m assemble :compileJava SKIPPED :processResources
SKIPPED :classes SKIPPED :jar SKIPPED :assemble SKIPPED BUILD SUCCESSFUL
Gradle:Dry Run -m $ ./gradlew -m assemble :compileJava SKIPPED :processResources
SKIPPED :classes SKIPPED :jar SKIPPED :assemble SKIPPED BUILD SUCCESSFUL
Gradle Daemon • GradleはJVM上で動くので起動に時間かかる ◦ いくつかのライブラリも必要で更にかかる • Daemonを使う事でいろいろキャッシュされる • デフォルトで無効
◦ 3.0(8月15日〜) からデフォルトで有効 • CIでは無効するのがおすすめ ◦ gradle.properties:org.gradle.daemon=false
Gradle Android Plugin ? Not today
Gradle 入門 以上
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