From 06e2a6680524d041581b67135039e713331118f3 Mon Sep 17 00:00:00 2001 From: Gabriel Feo Date: Fri, 26 May 2023 23:14:27 +0100 Subject: [PATCH 1/3] Add tasks to test examples --- examples/build.gradle.kts | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 examples/build.gradle.kts diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts new file mode 100644 index 000000000..eb8c83dab --- /dev/null +++ b/examples/build.gradle.kts @@ -0,0 +1,39 @@ +val exampleTestTasks = ArrayList>() + +exampleTestTasks += tasks.register("runExampleScript") { + group = "Application" + description = "Runs the 'example-script.main.kts' script" + commandLine("kotlinc", "-script", file("example-script.main.kts")) +} + +exampleTestTasks += tasks.register("checkExampleProject") { + group = "Verification" + description = "Checks examples/example-project as a standalone build" + dir = file("example-project") + tasks = listOf("check") +} + +val notebooks = fileTree(file("example-notebooks")) { + exclude(".ipynb_checkpoints") +} + +exampleTestTasks += notebooks.map { notebook -> + val buildDir = project.layout.buildDirectory.asFile.get() + tasks.register("run${notebook.nameWithoutExtension}Notebook") { + group = "Application" + description = "Runs the '${notebook.name}' notebook" + commandLine( + "jupyter", "nbconvert", + "--execute", + "--to", "ipynb", + "--output-dir=$buildDir", + notebook, + ) + } +} + +tasks.register("checkExamples") { + group = "Verification" + description = "Checks all examples" + dependsOn(exampleTestTasks) +} From a0974f9e26c631bf891a4b399ce27b36e802db5f Mon Sep 17 00:00:00 2001 From: Gabriel Feo Date: Fri, 26 May 2023 23:25:13 +0100 Subject: [PATCH 2/3] Remove printProgress from examples --- examples/build.gradle.kts | 14 +- .../MostFrequentBuilds.ipynb | 198 +++--------------- .../example/analysis/MostFrequentBuilds.kt | 33 +-- examples/example-script.main.kts | 32 +-- 4 files changed, 48 insertions(+), 229 deletions(-) diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index eb8c83dab..545dee98b 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -6,11 +6,11 @@ exampleTestTasks += tasks.register("runExampleScript") { commandLine("kotlinc", "-script", file("example-script.main.kts")) } -exampleTestTasks += tasks.register("checkExampleProject") { +exampleTestTasks += tasks.register("runExampleProject") { group = "Verification" - description = "Checks examples/example-project as a standalone build" + description = "Runs examples/example-project as a standalone build" dir = file("example-project") - tasks = listOf("check") + tasks = listOf("run") } val notebooks = fileTree(file("example-notebooks")) { @@ -21,7 +21,7 @@ exampleTestTasks += notebooks.map { notebook -> val buildDir = project.layout.buildDirectory.asFile.get() tasks.register("run${notebook.nameWithoutExtension}Notebook") { group = "Application" - description = "Runs the '${notebook.name}' notebook" + description = "Runs the '${notebook.name}' notebook with 'jupyter nbconvert --execute'" commandLine( "jupyter", "nbconvert", "--execute", @@ -32,8 +32,8 @@ exampleTestTasks += notebooks.map { notebook -> } } -tasks.register("checkExamples") { - group = "Verification" - description = "Checks all examples" +tasks.register("runExamples") { + group = "Application" + description = "Runs everything in 'examples' directory" dependsOn(exampleTestTasks) } diff --git a/examples/example-notebooks/MostFrequentBuilds.ipynb b/examples/example-notebooks/MostFrequentBuilds.ipynb index b7c0b8e66..2aabeb8fd 100644 --- a/examples/example-notebooks/MostFrequentBuilds.ipynb +++ b/examples/example-notebooks/MostFrequentBuilds.ipynb @@ -31,7 +31,7 @@ "source": [ "## Setup\n", "\n", - "`%use` is [line magic](https://github.com/Kotlin/kotlin-jupyter#line-magics) of the Kotlin kernel that can do much more than adding the library. To illustrate, this setup:\n", + "`%use` is a [line magic](https://github.com/Kotlin/kotlin-jupyter#line-magics) of the Kotlin kernel that can do much more than adding the library. To illustrate, this setup:\n", "\n", "```kotlin\n", "@file:DependsOn(\"com.gabrielfeo:gradle-enterprise-api-kotlin:0.16.2\")\n", @@ -86,41 +86,6 @@ "}" ] }, - { - "cell_type": "code", - "execution_count": 3, - "id": "39f57804-ca90-4d7b-b4ac-f8d438ba911e", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "// A utility to print progress as builds are fetched. You may ignore this.\n", - "\n", - "fun Flow.printProgress(produceMsg: (i: Int, current: T) -> String): Flow {\n", - " var i = -1\n", - " var current: T? = null\n", - " fun printIt() {\n", - " val msg = current?.let { produceMsg(i, it) } ?: \"Waiting for elements...\"\n", - " print(\"\\r$msg\".padEnd(100))\n", - " }\n", - " val periodicPrinter = GlobalScope.launch {\n", - " while (true) {\n", - " printIt()\n", - " delay(500)\n", - " }\n", - " }\n", - " return onEach {\n", - " i++\n", - " current = it\n", - " }.onCompletion {\n", - " periodicPrinter.cancelAndJoin()\n", - " printIt()\n", - " println(\"\\nEnd\")\n", - " }\n", - "}" - ] - }, { "cell_type": "markdown", "id": "9d0556e7", @@ -135,21 +100,12 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "id": "588a699f", "metadata": { "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fetched 000006412 builds, currently 2023-05-19T19:29:58.350Z \n", - "End\n" - ] - } - ], + "outputs": [], "source": [ "import java.time.temporal.*\n", "import java.util.LinkedList\n", @@ -158,10 +114,7 @@ " val startMilli = startDate.atStartOfDay(ZoneId.of(\"UTC\")).toInstant().toEpochMilli()\n", " GradleEnterpriseApi.buildsApi.getGradleAttributesFlow(since = startMilli)\n", " .filter(buildFilter)\n", - " .printProgress { i, build ->\n", - " val buildDate = Instant.ofEpochMilli(build.buildStartTime).atOffset(ZoneOffset.UTC)\n", - " String.format(\"Fetched %09d builds, currently %s\", i + 1, buildDate)\n", - " }.toList(LinkedList())\n", + " .toList(LinkedList())\n", "}" ] }, @@ -177,7 +130,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "5cd75a65-a819-497e-87c2-f0911cc1554f", "metadata": {}, "outputs": [ @@ -404,7 +357,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "adbd028f-d30a-489e-94bd-d8f968a659a3", "metadata": { "tags": [] @@ -412,96 +365,7 @@ "outputs": [ { "data": { - "application/kotlindataframe+json": { - "columns": [ - "tasks", - "count" - ], - "kotlin_dataframe": [ - { - "count": 3173, - "tasks": "app:assembleBrazilDebug" - }, - { - "count": 974, - "tasks": "IDE sync" - }, - { - "count": 205, - "tasks": "droid-cli:installDist" - }, - { - "count": 147, - "tasks": "clean" - }, - { - "count": 92, - "tasks": "feature:order-delivery:customer-satisfaction:impl:compileReleaseSources" - }, - { - "count": 85, - "tasks": "infrastructure:design-system:compose:compileReleaseSources" - }, - { - "count": 54, - "tasks": "app:assembleBrazilDebug :app:installBrazilDebug" - }, - { - "count": 51, - "tasks": "build-plugins:functionalTest --tests rasp.AndroidRaspProtectionPluginTest" - }, - { - "count": 44, - "tasks": "analytics-braze:testReleaseUnitTest --tests br.com.ifood.analytics.braze.AppBrazeAnalyticsProviderTest" - }, - { - "count": 44, - "tasks": "feature:survey:impl:compileReleaseSources" - }, - { - "count": 33, - "tasks": "clean app:assembleBrazilDebug" - }, - { - "count": 31, - "tasks": "feature:voucher-android-training:impl:compileReleaseSources" - }, - { - "count": 30, - "tasks": "feature:search:impl:compileReleaseSources" - }, - { - "count": 29, - "tasks": "droid-cli:run --args ci run-jupyter-notebook" - }, - { - "count": 27, - "tasks": "clean :feature:internal-settings:sample:assemble" - }, - { - "count": 24, - "tasks": "clean :app:assembleBrazilDebug" - }, - { - "count": 20, - "tasks": "protectArtifact" - }, - { - "count": 19, - "tasks": "analytics-braze:testReleaseUnitTest --tests br.com.ifood.analytics.braze.AppBrazeAnalyticsProviderTest.sendEvent_featureFlagCanSendEvent_sendEvent" - }, - { - "count": 19, - "tasks": "setupDependencies" - }, - { - "count": 16, - "tasks": "feature:checkout:core:impl:testReleaseUnitTest --tests br.com.ifood.checkout.presentation.plugin.standard.delivery.DeliveryPluginViewModelTest" - } - ], - "ncol": 2, - "nrow": 682 - }, + "application/kotlindataframe+json": "{\"nrow\":266,\"ncol\":2,\"columns\":[\"tasks\",\"count\"],\"kotlin_dataframe\":[{\"tasks\":\"app:assembleBrazilDebug\",\"count\":977},{\"tasks\":\"IDE sync\",\"count\":285},{\"tasks\":\"droid-cli:installDist\",\"count\":80},{\"tasks\":\"feature:order-delivery:waiting-platform-components:impl:compileReleaseSources\",\"count\":48},{\"tasks\":\"feature:home:impl:compileReleaseSources\",\"count\":17},{\"tasks\":\"feature:chat:impl:testReleaseUnitTest --tests br.com.ifood.chat.presentation.chat.viewModel.ChatViewModelTest.dispatchViewAction_withInitializeAction_andChatCreated_\",\"count\":16},{\"tasks\":\"clean\",\"count\":13},{\"tasks\":\"analytics-braze:testReleaseUnitTest --tests br.com.ifood.analytics.braze.AppBrazeAnalyticsProviderTest.sendEvent_featureFlagCanSendEvent_sendEvent\",\"count\":12},{\"tasks\":\"analytics-braze:testReleaseUnitTest --tests br.com.ifood.analytics.braze.AppBrazeAnalyticsProviderTest\",\"count\":12},{\"tasks\":\"app:assembleBrazilDebug :app:installBrazilDebug\",\"count\":11},{\"tasks\":\"buildPlugin\",\"count\":11},{\"tasks\":\"infrastructure:design-system:global-components-sample:assembleDebug\",\"count\":11},{\"tasks\":\"setupDependencies\",\"count\":10},{\"tasks\":\"feature:groceries:shopping-list:impl:testReleaseUnitTest --tests br.com.ifood.groceries.shoppinglist.presentation.shoppinglistvoice.ShoppingListVoiceSharedViewModelTest\",\"count\":8},{\"tasks\":\"feature:review:evaluating:impl:testReleaseUnitTest --tests br.com.ifood.review.presentation.viewmodel.ReviewViewModelTest\",\"count\":7},{\"tasks\":\"build-plugins:test --tests rasp.DexProtectorConfigManagerTest\",\"count\":7},{\"tasks\":\"build-plugins:functionalTest --tests rasp.AndroidRaspProtectionPluginTest\",\"count\":7},{\"tasks\":\"droid-cli:test --tests br.com.ifood.cli.util.RunCommandShellTest\",\"count\":7},{\"tasks\":\"feature:order-delivery:waiting:impl:testReleaseUnitTest\",\"count\":6},{\"tasks\":\"feature:checkout:core:impl:testReleaseUnitTest --tests br.com.ifood.checkout.presentation.contextcard.mapper.CartModelToMinimizedCartUiModelMapperTest\",\"count\":5}]}", "text/html": [ " \n", " \n", @@ -663,26 +527,26 @@ " \n", " \n", " \n", - "
\n", + "
\n", "\n", - "

... showing only top 20 of 682 rows

DataFrame: rowsCount = 682, columnsCount = 2

\n", + "

... showing only top 20 of 266 rows

DataFrame: rowsCount = 266, columnsCount = 2

\n", " \n", " \n", " " ] }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -714,7 +578,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "8c28e684-0f3b-43d9-a3d2-7b1ef91fa6c4", "metadata": {}, "outputs": [ @@ -772,7 +636,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "293b2b4d", "metadata": { "tags": [] @@ -785,18 +649,18 @@ "output": { "data": { "count": [ - 3173, - 974, - 205, - 147, - 92 + 977, + 285, + 80, + 48, + 17 ], "tasks": [ "app:assembleBrazilDebug", "IDE sync", "droid-cli:installDist", - "clean", - "feature:order-delivery:customer-satisfaction:impl:compileReleaseSources" + "feature:order-delivery:waiting-platform-components:impl:compileReleaseSources", + "feature:home:impl:compileReleaseSources" ] }, "ggsize": { @@ -827,7 +691,8 @@ ] }, { - "aesthetic": "y" + "aesthetic": "y", + "discrete": true } ] }, @@ -836,14 +701,14 @@ }, "text/html": [ " \n", - "
\n", + "
\n", " " ] }, - "execution_count": 8, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } diff --git a/examples/example-project/app/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/example/analysis/MostFrequentBuilds.kt b/examples/example-project/app/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/example/analysis/MostFrequentBuilds.kt index 93e94e224..8f4e91cc2 100644 --- a/examples/example-project/app/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/example/analysis/MostFrequentBuilds.kt +++ b/examples/example-project/app/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/example/analysis/MostFrequentBuilds.kt @@ -33,9 +33,11 @@ suspend fun mostFrequentBuilds( val startMilli = startDate.atStartOfDay(ZoneId.of("UTC")).toInstant().toEpochMilli() val builds: List = api.getGradleAttributesFlow(since = startMilli) .filter(buildFilter) - .printProgress { i, build -> + .onEach { build -> val buildDate = Instant.ofEpochMilli(build.buildStartTime).atOffset(ZoneOffset.UTC) - String.format("Fetched %09d builds, currently %s", i + 1, buildDate) + print(String.format("\rFetching builds... (current date: %s)", buildDate)) + }.onCompletion { + print('\n') }.toList(LinkedList()) // Process builds and count how many times each was invoked @@ -61,30 +63,3 @@ suspend fun mostFrequentBuilds( """.trimMargin() ) } - - -// A utility to print progress as builds are fetched. You may ignore this. -@OptIn(DelicateCoroutinesApi::class) -fun Flow.printProgress(produceMsg: (i: Int, current: T) -> String): Flow { - var i = -1 - var current: T? = null - fun printIt() { - val msg = current?.let { produceMsg(i, it) } ?: "Waiting for elements..." - print("\r$msg".padEnd(100)) - } - - val periodicPrinter = GlobalScope.launch { - while (true) { - printIt() - delay(500) - } - } - return onEach { - i++ - current = it - }.onCompletion { - periodicPrinter.cancelAndJoin() - printIt() - println("\nEnd") - } -} diff --git a/examples/example-script.main.kts b/examples/example-script.main.kts index 836b776ac..be9d83a93 100644 --- a/examples/example-script.main.kts +++ b/examples/example-script.main.kts @@ -31,38 +31,16 @@ val buildFilter: (GradleAttributes) -> Boolean = { build -> "LOCAL" in build.tags } -// A utility to print progress as builds are fetched. You may ignore this. -fun Flow.printProgress(produceMsg: (i: Int, current: T) -> String): Flow { - var i = -1 - var current: T? = null - fun printIt() { - val msg = current?.let { produceMsg(i, it) } ?: "Waiting for elements..." - print("\r$msg".padEnd(100)) - } - val periodicPrinter = GlobalScope.launch { - while (true) { - printIt() - delay(500) - } - } - return onEach { - i++ - current = it - }.onCompletion { - periodicPrinter.cancelAndJoin() - printIt() - println("\nEnd") - } -} - // Fetch builds from the API val builds: List = runBlocking { val startMilli = startDate.atStartOfDay(ZoneId.of("UTC")).toInstant().toEpochMilli() GradleEnterpriseApi.buildsApi.getGradleAttributesFlow(since = startMilli) .filter(buildFilter) - .printProgress { i, build -> + .onEach { build -> val buildDate = Instant.ofEpochMilli(build.buildStartTime).atOffset(ZoneOffset.UTC) - String.format("Fetched %09d builds, currently %s", i + 1, buildDate) + print(String.format("\rFetching builds... (current date: %s)", buildDate)) + }.onCompletion { + print('\n') }.toList(LinkedList()) } @@ -89,5 +67,5 @@ println( """.trimMargin() ) -// Shutdown to end OkHttp's thread pool earlier +// Shutdown to end background threads and allow script to exit earlier (see README) GradleEnterpriseApi.shutdown() From 70ef7ff73576e8112451efae52ea0cab80c19d22 Mon Sep 17 00:00:00 2001 From: Gabriel Feo Date: Fri, 26 May 2023 23:29:53 +0100 Subject: [PATCH 3/3] Remove simpler printing too --- .../enterprise/api/example/analysis/MostFrequentBuilds.kt | 7 +------ examples/example-script.main.kts | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/examples/example-project/app/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/example/analysis/MostFrequentBuilds.kt b/examples/example-project/app/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/example/analysis/MostFrequentBuilds.kt index 8f4e91cc2..43af9a475 100644 --- a/examples/example-project/app/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/example/analysis/MostFrequentBuilds.kt +++ b/examples/example-project/app/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/example/analysis/MostFrequentBuilds.kt @@ -33,12 +33,7 @@ suspend fun mostFrequentBuilds( val startMilli = startDate.atStartOfDay(ZoneId.of("UTC")).toInstant().toEpochMilli() val builds: List = api.getGradleAttributesFlow(since = startMilli) .filter(buildFilter) - .onEach { build -> - val buildDate = Instant.ofEpochMilli(build.buildStartTime).atOffset(ZoneOffset.UTC) - print(String.format("\rFetching builds... (current date: %s)", buildDate)) - }.onCompletion { - print('\n') - }.toList(LinkedList()) + .toList(LinkedList()) // Process builds and count how many times each was invoked val buildCounts = builds.groupBy { build -> diff --git a/examples/example-script.main.kts b/examples/example-script.main.kts index be9d83a93..8f6789ad6 100644 --- a/examples/example-script.main.kts +++ b/examples/example-script.main.kts @@ -36,12 +36,7 @@ val builds: List = runBlocking { val startMilli = startDate.atStartOfDay(ZoneId.of("UTC")).toInstant().toEpochMilli() GradleEnterpriseApi.buildsApi.getGradleAttributesFlow(since = startMilli) .filter(buildFilter) - .onEach { build -> - val buildDate = Instant.ofEpochMilli(build.buildStartTime).atOffset(ZoneOffset.UTC) - print(String.format("\rFetching builds... (current date: %s)", buildDate)) - }.onCompletion { - print('\n') - }.toList(LinkedList()) + .toList(LinkedList()) } // Process builds and count how many times each was invoked