Coder Social home page Coder Social logo

kotlin-dsl-samples's Introduction

Gradle Kotlin DSL Samples

License

Welcome! The Gradle Kotlin DSL provides support for writing Gradle build scripts using JetBrains' Kotlin language. It aims to provide Gradle users with a rich, flexible and statically-typed approach to developing build logic in conjunction with the best IDE and tooling experience possible.

Getting Started

The fastest way to get up and running with a Kotlin-based Gradle build is to use gradle init

gradle init --dsl kotlin

or, if you don't have Gradle installed already, you can generate Gradle builds online at https://gradle-initializr.cleverapps.io/.

The Gradle Kotlin DSL is documented in a dedicated chapter in the Gradle user manual.

Moreover, the Gradle user manual and guides contain build script excerpts that demonstrate both the Groovy DSL and the Kotlin DSL. This is the best place where to find how to do this and that with the Gradle Kotlin DSL; and it covers all Gradle features from using plugins to customizing the dependency resolution behavior. All snippets in the user manual demonstrate both Groovy and Kotlin DSL.

If you are looking into migrating an existing build to the Gradle Kotlin DSL, please also check out the migration guide.

You can read more about the project in our announcement blog post and check out the frequently asked questions in the project wiki.

Issue Tracking

This repository is only for Gradle Kotlin DSL Samples.

Found a bug in one of the samples, have an idea for an improvement or for a new sample? Feel free to add an issue.

If you're dealing with what you believe to be an issue with Gradle or the Gradle Kotlin DSL, please open an issue on the gradle/gradle repository.

If you're dealing with what you believe to be an issue with Kotlin itself or the Kotlin Plugin for IDEA, you may want to search JetBrains' YouTrack first to see if it is a known issue. In any case, feel free to add an issue here for it as well. We'd like to know and track what our users are experiencing regardless whether the issue is with the Gradle Kotlin DSL or with Kotlin itself.

Staying in Touch

Come chat with us in the #kotlin-dsl channel of the public Gradle Community Slack instance.

License

Like the rest of Gradle, the Gradle Kotlin DSL Samples are released under version 2.0 of the Apache License.

Contributing

Please see CONTRIBUTING.md for details of how to build and contribute to Gradle Kotlin DSL Samples.

kotlin-dsl-samples's People

Contributors

adammurdoch avatar bamboo avatar big-guy avatar breskeby avatar cbeams avatar dksmiffs avatar donat avatar elect86 avatar eskatos avatar gildor avatar guenhter avatar hotchemi avatar jaredsburrows avatar jlleitschuh avatar jnizet avatar ligee avatar liutikas avatar marcphilipp avatar melix avatar mkobit avatar pioterj avatar shradej1 avatar stefma avatar supercilex avatar tyvsmith avatar yole avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kotlin-dsl-samples's Issues

Support automatic detection of Kotlin-based builds

To use Kotlin build scripts, one has to set an explicit buildFileName in his settings.gradle file:

def configureGradleScriptKotlinOn(ProjectDescriptor project) {
    if(project.file('build.gradle.kts').exists()) {
        project.buildFileName = 'build.gradle.kts'
    }
    project.children.each { configureGradleScriptKotlinOn(it) }
}

include 'a', 'b', 'c'

configureGradleScriptKotlinOn rootProject

The default value of buildFileName is build.gradle.

This issue is about removing the need to set an explicit buildFileName.

See also #56 for settings.gradle.kts support.

Support convenient creation of objects within NamedDomainObjectContainers

We decided to provide two ways of configuring domain object containers and their elements. First, a declarative approach, better suited to configuring many objects at once, and another one based on delegated properties, better suited to configuring single objects or simply bringing them into scope.

1. Bulk configuration

Monomorphic containers

container {
  "new-item-a" {
     newItemProperty = false
  }
  "new-item-b" {
  }
  "new-item-c"() // invocation without passing a block also works
}

Polymorphic containers

container {
  "new-item-a"(JvmLibrary::class) {
     jvmLibraryProperty = "foo"
  }
  "new-item-b"(type = JvmApplication::class) // can use explicit parameter name for clarity
  "new-item-c"() // create element with default type 
}

2. Selective access/configuration

Via delegated properties

Bringing an existing element into scope

val clean by tasks // brings an existing task into scope by name

val clean: Delete by tasks // brings an existing task into scope by name and type

Creating new elements

val clean: Delete by tasks.creating { // creates a new object in the container
    delete("build")
}

Via collection indexer

Collection elements can also be accessed via index:

val clean = tasks["clean"]

tasks["build"].apply {
  dependsOn(clean)
}

Minimize impact of Kotlin dependencies on distribution file size

The inclusion of gradle-script-kotlin and its transitive dependencies causes the Gradle distribution zip to grow by more than 22 MB, 20 MB of which is due to the kotlin-compiler-embeddable jar alone.

There are multiple ways to approach dealing with this, including:

  • resolving gradle-script-kotlin and its dependencies on demand into a Gradle distribution instead of packaging them with the distribution up front
  • using ProGuard or similar to pare down the Kotlin compiler classes to only those that we actually need (it is unknown whether this would produce any measurable reduction)
  • do both of the above

In any case, per our last discussions with JetBrains on this topic, it doesn't sound likely that the file size of the embeddable compiler jar will be reduced any time soon.

Support programmatic configuration of Kotlin plugin

When this work is complete, it will eliminate the current need for a static gradle.ktscfg.xml (#19) file to be generated (by generateKtsConfig) at the root of each project.

The general idea is to expose a configuration API on the Kotlin plugin side and to then integrate with it via the Gradle Tooling API.

Partially migrate gradle-script-kotlin's own build

At time of writing, gradle-script-kotlin's build is still fundamentally Groovy-based, in that it has a build.gradle file as an entry point.

However, notice line 14 of build.gradle, which reads:

apply from: 'build.gradle.kts'

And then have a look at build.gradle.kts to see what's been migrated so far.

We'll continue to migrate the build as new functionality comes online, and until nothing remains but .kts files.

applyFrom causes an error due to duplicate generateKtsConfig

Looks like all KotlinBuildScripts try to create the task, so applyFrom doesn't work:

Caused by: org.gradle.api.InvalidUserDataException: Cannot add task ':generateKtsConfig' as a task with that name already exists.
        at org.gradle.api.internal.tasks.DefaultTaskContainer.create(DefaultTaskContainer.java:74)
        at org.gradle.api.internal.tasks.DefaultTaskContainer.create(DefaultTaskContainer.java:97)
        at org.gradle.script.lang.kotlin.provider.KotlinScriptPlugin.registerBuiltinTasks(KotlinScriptPlugin.kt:59)
        at org.gradle.script.lang.kotlin.provider.KotlinScriptPlugin.apply(KotlinScriptPlugin.kt:41)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyScript(DefaultObjectConfigurationAction.java:102)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.access$000(DefaultObjectConfigurationAction.java:36)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction$1.run(DefaultObjectConfigurationAction.java:62)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.execute(DefaultObjectConfigurationAction.java:136)
        at org.gradle.api.internal.project.AbstractPluginAware.apply(AbstractPluginAware.java:40)
        at org.gradle.script.lang.kotlin.KotlinBuildScript.apply(KotlinBuildScript.kt)
        at org.gradle.script.lang.kotlin.ProjectExtensionsKt.applyFrom(ProjectExtensions.kt:50)
        at Build_gradle.<init>(build.gradle.kts:18)
        at org.gradle.script.lang.kotlin.provider.KotlinScriptPlugin.instantiateScriptClass(KotlinScriptPlugin.kt:52)
        at org.gradle.script.lang.kotlin.provider.KotlinScriptPlugin.apply(KotlinScriptPlugin.kt:42)

_project_hidden_ should not show up in content assist

Repro steps:

  1. Follow the instructions to set up a sample project within IDEA
  2. Open the project's build.gradle.kts file
  3. Place the cursor at the left margin of the file, outside the context of any block or function
  4. Press CMD-SPACE to get a content assist window
  5. Notice that _project_hidden_ is available for completion

_project_hidden_ is an implementation detail of the way our integration with Kotlin Scripting works, and should probably be hidden from users (as its name suggests!)

Support navigation to and manipulation of script sources

@orangy wrote:

I want to discuss one more thing related to user experience in what we are doing. Right now, given a Gradle model for Project, it’s next to impossible to navigate to locations in scripts where particular entity is defined. E.g. if we have list of Gradle projects in IDEA’s Gradle tool window, we can’t make a “Go to definition” command to navigate to project("…") line. We’d like to improve it, and here is what we think:

  • make it possible to attach some ScriptLocation instance to any entity like task, project, extension object, whatever
  • populate ScriptLocation from script by using compiler-generated instance as it knows exactly where the call is located, and passed somehow implicitly into DSL function
  • for a prototype, before we commit to supporting it in compiler, use stacktrace information to populate the data (may be slow for production, but ok for prototype)
  • use this data in diagnostics wherever applicable, collaborate with IJ gradle plugin (Vlad) to support this information in IDE, if present.

Strategically, it can open way to manipulating scripts from IDE in a safe manner, as follows:

  • support not just file:line in SourceLocation instance, but also text range of the entire call, including lambda
  • be able to serialise parts of the model back into script
  • if serialised model is the same as text in the script source (except for whitespace), then this part of the script can be modified programmatically by manipulating model and serialising it back into source
  • otherwise, IDE would resist to modify particular parts of the model, e.g. if some imperative code is present

Support task selection and configuration

We have a clear approach to task declaration (#9, #10), but have not yet made decisions around how to configure existing tasks that have been created or declared elsewhere, e.g. by a plugin.

In Groovy, this is done as follows:

mytask {
    // additional configuration goes here
}

Where mytask is a task already registered with the tasks container.

In Kotlin, we want:

tasks.mytask {
     ...
}

Consider aggregating all build/project specific extensions, conventions and tasks under a my namespace:

my.artifactory {
   ...
}

my.taskContributedByPlugin {
   ...
}

Can't get sample project working with instructions

Its failing at the step to IDEA config for auto completion and what not

i.e. ./gradlew patchIdeaConfig

Seems like it expects hello-world.iml to be right under modules directory, but it is under a subdirectory -597800014

Any insight will be much appreciated.

Error:

$ ./gradlew patchIdeaConfig
:patchIdeaConfig FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':patchIdeaConfig'.
> java.io.FileNotFoundException: /private/tmp/gradle-script-kotlin/samples/hello-world/.idea/modules/hello-world.iml (No such file or directory)

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Contents of .idea directory

$ ll -R .idea
total 184
-rw-r--r--  1 berinle  wheel   870B May 18 11:00 compiler.xml
drwxr-xr-x  3 berinle  wheel   102B May 18 11:00 copyright
-rw-r--r--  1 berinle  wheel   159B May 18 11:00 encodings.xml
-rw-r--r--  1 berinle  wheel    13K May 18 11:00 findbugs-idea.xml
-rw-r--r--  1 berinle  wheel   684B May 18 11:00 gradle.xml
drwxr-xr-x  5 berinle  wheel   170B May 18 11:02 libraries
-rw-r--r--  1 berinle  wheel   1.4K May 18 11:00 misc.xml
drwxr-xr-x  3 berinle  wheel   102B May 18 11:00 modules
-rw-r--r--  1 berinle  wheel   682B May 18 11:00 modules.xml
-rw-r--r--  1 berinle  wheel    55K May 18 11:02 workspace.xml

.idea/copyright:
total 8
-rw-r--r--  1 berinle  wheel    74B May 18 11:00 profiles_settings.xml

.idea/libraries:
total 64
-rw-r--r--  1 berinle  wheel   481B May 18 11:00 Gradle__junit_junit_4_12.xml
-rw-r--r--  1 berinle  wheel   537B May 18 11:00 Gradle__org_hamcrest_hamcrest_core_1_3.xml
-rw-r--r--  1 berinle  wheel    20K May 18 11:02 gradle_ide_support.xml

.idea/modules:
total 0
drwxr-xr-x  5 berinle  wheel   170B May 18 11:00 -597800014

.idea/modules/-597800014:
total 96
-rw-r--r--  1 berinle  wheel    12K May 18 11:00 hello-world.iml
-rw-r--r--  1 berinle  wheel    12K May 18 11:00 hello-world_main.iml
-rw-r--r--  1 berinle  wheel    13K May 18 11:00 hello-world_test.iml

Set up:
IntelliJ IDEA 2016.1.2
Build #IU-145.972, built on May 14, 2016
JRE: 1.8.0_76-release-b162 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o

Kotlin plugin: https://teamcity.jetbrains.com/repository/download/bt345/766796:id/kotlin-plugin-1.1.0-dev-372.zip

KT-12549: Classes within kotlin-compiler-embeddable are shaded but their corresponding META-INF/services files are not

Tracking issue for https://youtrack.jetbrains.com/issue/KT-12549

In gradle-script-kotlin, we have had to rebuild the kotlin-compiler-embeddable jar and publish a custom release of it in order to exclude its problematic META-INF/services/java.nio.charset.spi.CharsetProvider file. The problem is that the file refers to the original name of a class that has since been shaded (repackaged) in the kotlin-compiler-embeddable jar. If the file is not removed (or edited to have the correct content), service loading / class loading errors occur at runtime in Gradle.

This problem was the reason we had to cut 1.0 M1a and is also described in its release notes.

Support upgrading gradle-kotlin-dsl

The goal here is to provide users with a way to upgrade gradle-script-kotlin (say) to a new snapshot or to a milestone release newer than the one that shipped with their current Gradle distribution.

Ultimately, this should be a first-class feature in Gradle itself, i.e. the ability to upgrade any module within the distribution without having to upgrade the distribution itself, but in the meantime, a stopgap approach might be to contribute an upgradeGradleScriptKotlin task that:

  • gets configured via property as to what gradleScriptKotlinVersion you want to use
  • resolves that version and its deps (using Gradle’s own resolution mechanism) into $TMPDIR
  • patch the gradle-script-kotlin-classpath.properties file in order to match the Gradle distribution's own set of dependencies (based on dependency resolution rules—see #59 for details)
  • interrogates existing gradle-script-kotlin classpath properties (from $GRADLE_HOME/lib/…)
  • creates a diff between the deps in $TMPDIR and $GRADLE_HOME/lib
  • deletes the delta between them
  • deletes the existing gradle-script-kotlin jar
  • copies the contents of $TMPDIR => $GRADLE_HOME/lib

Create an Android sample project

@anokmik originally wrote:

Hi!

Thanks for an opportunity to use Kotlin for writing Gradle build scripts.

As an Android developer I'm curious if it supports Android for now? If not, then could you, please, tell when this feature might be added?

This issue is now about creating a sample project that will demonstrate how to write an Android-based build using Gradle Script Kotlin.

Thank you!

Hey there,

I just came here to say THANK YOU for all your affort to make this possible.

Keep up the great work.

Kudos! 🎉

Add `action` extension method to ease use of methods that take closures

A major ergonomic issue with the current Gradle API and Kotlin is the lack of equivalence for methods that take groovy.lang.Closure. Feels like the ergonomic equivalent in Kotlin for say Project.copy(groovy.lang.Closure) appears to be a function that takes an extension as an argument fun copy(configure: CopySpec.() -> Unit), which is impossible to express in Java.

I'm interested in what the plan is for that. I see that key project configurations like repositories are getting exactly this treatment today. Is the plan to update the raw Closure definitions with correct type information and generate Kotlin extensions generated for all of these DSL methods? Or convert them to Kotlin for first class support?

Looks like there's always a Action<T> overload, so in the meantime, it'd be useful to have a convenience extension method to make the methods that take Action a little easier to use:

fun <U> Project.action(exec: U.() -> Unit) = Action<U> { exec(it) }

That allows this kind of thing:

copy(action {
    from(files("build.gradle.kts"))
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
})

Rather than the alternatives:

// 1. Slightly clumsy, and problematic with nested closures

copy {
    it.from(files("build.gradle.kts"))
    it.duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

// 2. Better, but for repeated calls a little messy

copy { spec ->
    spec.from(files("build.gradle.kts"))
    spec.duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

// 3. Better still, but nesting is messy too

copy {
    it.run {
        from(files("build.gradle.kts"))
        duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    }
}

Fix '[class]loader constraint violation' errors

During the partial migration of Gradle Script Kotlin's own build (#24), an attempt was made to port the following task from Groovy to Kotlin:

task<Zip>("repackageKotlinCompilerEmbeddable") {
    baseName = "kotlin-compiler-embeddable"
    version = "${kotlinVersion}a"
    extension = "jar"
    entryCompression = ZipEntryCompression.STORED
    from(Callable {
        val files = configurations.getByName("compile").files
        zipTree(files.single { it.name.startsWith(baseName) })
    })
    exclude("META-INF/services/java.nio.charset.spi.CharsetProvider")
    destinationDir = buildDir
    description = "Repackages '$baseName:$version' to remove broken META-INF/services files"
}

It was then reverted, because it caused the following error:

loader constraint violation: when resolving method "org.gradle.script.lang.kotlin.ProjectExtensionsKt.task(Lorg/gradle/api/Project;Ljava/lang/String;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)Lorg/gradle/api/Task;" the class loader (instance of org/jetbrains/kotlin/codegen/GeneratedClassLoader) of the current class, Build_gradle, and the class loader (instance of org/gradle/internal/classloader/MutableURLClassLoader) for the method's defining class, org/gradle/script/lang/kotlin/ProjectExtensionsKt, have different Class objects for the type kotlin/reflect/KClass used in the signature

This issue is about tracking down and fixing that error, and when complete, migrating the task above as originally intended

Support script debugging

In talking with @ligee, basic support for debugging should "already be there", e.g. setting breakpoints, etc. Should just be a matter of passing the correct remote debugging flags to underlying the Gradle process.

  • See what's already possible with debugging
  • Provide feedback to Kotlin team about surfacing first-class support for debugging Gradle build scripts wherever it's missing

KT-11128: Methods in the DSL that have `java.lang.Object` overloads are problematic

Methods in the DSL that have Object overloads are problematic. Kotlin selects the least specific signature https://youtrack.jetbrains.com/issue/KT-11128. For example, this code will call all(Object):

configurations.getByName("compile").resolutionStrategy.componentSelection.all { action ->
}

Hinting that the generic type doesn't help, this still selects ComponentSelectionRules.all(Object) and will fail at runtime:

componentSelection.all { action: ComponentSelection ->
}

So instead, you have to be a little more heavy handed and implement the Action:

componentSelection.all(Action<ComponentSelection> { selection ->
})

The extension I suggest in #7 would help in this case. Hopefully this is fixed to select the most specific overload in Kotlin 1.1.0, but something to watch for.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.