Buscar..


Configuración básica

  1. Cree un archivo llamado SCALA_PROJECT/build.gradle con estos contenidos:

    group 'scala_gradle'
    version '1.0-SNAPSHOT'
    
    apply plugin: 'scala'
    
    repositories {
        jcenter()
        mavenCentral()
        maven {
            url "https://repo.typesafe.com/typesafe/maven-releases"
        }
    }
    
    dependencies {
        compile group: 'org.scala-lang', name: 'scala-library', version: '2.10.6'
    }
    
    
    task  "create-dirs" << {
        sourceSets*.scala.srcDirs*.each { it.mkdirs() }
        sourceSets*.resources.srcDirs*.each { it.mkdirs() }
    }
    
    
  2. Ejecutar gradle tasks para ver las tareas disponibles.

  3. Ejecute gradle create-dirs para crear un directorio src/scala, src/resources .

  4. Ejecute gradle build para compilar el proyecto y descargar dependencias.

Crea tu propio complemento Gradle Scala

Después de pasar por el ejemplo de la Configuración básica , es posible que repita la mayor parte de él en cada uno de los proyectos de Scala Gradle. Huele a código repetitivo ...

¿Qué pasaría si, en lugar de aplicar el complemento de Scala ofrecido por Gradle, pudiera aplicar su propio complemento de Scala, que sería responsable de manejar toda su lógica de compilación común, extendiendo, al mismo tiempo, el complemento ya existente.

Este ejemplo va a transformar la lógica de compilación anterior en un complemento de Gradle reutilizable.

Afortunadamente, en Gradle, puede escribir fácilmente complementos personalizados con la ayuda de la API de Gradle, como se describe en la documentación . Como lenguaje de implementación, puede usar Scala en sí o incluso Java. Sin embargo, la mayoría de los ejemplos que puede encontrar en todos los documentos están escritos en Groovy. Si necesita más muestras de código o quiere comprender qué hay detrás del complemento de Scala, por ejemplo, puede consultar el repositorio de github de Gradle .

Escribiendo el plugin

Requerimientos

El complemento personalizado agregará la siguiente funcionalidad cuando se aplique a un proyecto:

  • un objeto de propiedad scalaVersion , que tendrá dos propiedades predeterminadas reemplazables
    • major = "2.12"
    • menor = "0"
  • una función withScalaVersion , que se aplica a un nombre de dependencia, agregará la versión principal de scala para garantizar la compatibilidad binaria (el operador sbt %% podría sonar una campana, de lo contrario, vaya aquí antes de continuar)
  • una tarea createDirs para crear el árbol de directorios necesario, exactamente como en el ejemplo anterior
Pauta de implementación
  1. cree un nuevo proyecto de Gradle y agregue lo siguiente a build.gradle
apply plugin: 'scala'
apply plugin: 'maven'

repositories {
    mavenLocal()
    mavenCentral()
}

dependencies {
    compile gradleApi()
    compile "org.scala-lang:scala-library:2.12.0"
}

Notas :

  • La implementación del complemento está escrita en Scala, por lo que necesitamos el complemento Gradle Scala.
  • para utilizar el complemento de otros proyectos, se utiliza el complemento Gradle Maven; esto agrega la tarea de install utilizada para guardar el archivo jar en el repositorio local de Maven
  • compile gradleApi() agrega el gradle-api-<gradle_version>.jar a la ruta de gradle-api-<gradle_version>.jar
  1. Crear una nueva clase Scala para la implementación del complemento.
package com.btesila.gradle.plugins 
 
import org.gradle.api.{Plugin, Project}  
 
class ScalaCustomPlugin extends Plugin[Project] {
    override def apply(project: Project): Unit = {
        project.getPlugins.apply("scala")
    }
}

Notas :

  • para implementar un complemento, simplemente extienda el rasgo de Plugin del tipo Project y anule el método de apply
  • dentro del método de aplicación, tiene acceso a la instancia de Project a la que se aplica el complemento y puede usarlo para agregarle lógica de compilación
  • este complemento no hace más que aplicar el ya existente Gradle Scala Plugin
  1. agregar la propiedad del objeto scalaVersion

En primer lugar, creamos una clase ScalaVersion , que contendrá las dos propiedades de la versión

class ScalaVersion {
  var major: String = "2.12"
  var minor: String = "0"
}

Una cosa interesante acerca de los complementos de Gradle es el hecho de que siempre puede agregar o anular propiedades específicas. Un complemento recibe este tipo de información del usuario a través del ExtensionContainer adjunto a una instancia del Project gradle. Para más detalles, mira esto .
Al agregar lo siguiente al método de apply , básicamente estamos haciendo esto:

  • Si no hay una propiedad scalaVersion definida en el proyecto, agregamos una con los valores predeterminados.
  • de lo contrario, obtenemos el existente como instancia de ScalaVersion , para usarlo aún más
var scalaVersion = new ScalaVersion
if (!project.getExtensions.getExtraProperties.has("scalaVersion"))
   project.getExtensions.getExtraProperties.set("scalaVersion", scalaVersion)
else
   scalaVersion = project.getExtensions.getExtraProperties.get("scalaVersion").asInstanceOf[ScalaVersion]

Esto es equivalente a escribir lo siguiente en el archivo de compilación del proyecto que aplica el complemento:

ext {
    scalaVersion.major = "2.12"
    scalaVersion.minor = "0"

}

  1. agregue la biblioteca scala-lang a las dependencias del proyecto, usando scalaVersion
project.getDependencies.add("compile", s"org.scala-lang:scala-library:${scalaVersion.major}.${scalaVersion.minor}")

Esto es equivalente a escribir lo siguiente en el archivo de compilación del proyecto que aplica el complemento:

compile "org.scala-lang:scala-library:2.12.0"
  1. agrega la función withScalaVersion
val withScalaVersion = (lib: String) => {
    val libComp = lib.split(":")
    libComp.update(1, s"${libComp(1)}_${scalaVersion.major}")
    libComp.mkString(":")
}
project.getExtensions.getExtraProperties.set("withScalaVersion", withScalaVersion)
  1. Finalmente, cree la tarea createDirs y agréguela al proyecto.
    Implementar una tarea de Gradle extendiendo DefaultTask :
class CreateDirs extends DefaultTask {
  @TaskAction
  def createDirs(): Unit = {
    val sourceSetContainer = this.getProject.getConvention.getPlugin(classOf[JavaPluginConvention]).getSourceSets

    sourceSetContainer forEach { sourceSet =>
      sourceSet.getAllSource.getSrcDirs.forEach(file => if (!file.getName.contains("java")) file.mkdirs())
    }
  }
}

Nota : el SourceSetContainer tiene información sobre todos los directorios de origen presentes en el proyecto. Lo que hace el complemento Gradle Scala es agregar los conjuntos de fuente adicionales a los de Java, como se puede ver en los documentos del complemento .

Agregue la tarea createDir al proyecto agregando esto al método de apply :

project.getTasks.create("createDirs", classOf[CreateDirs])

Al final, su clase ScalaCustomPlugin debería verse así:

class ScalaCustomPlugin extends Plugin[Project] {
  override def apply(project: Project): Unit = {
    project.getPlugins.apply("scala")

    var scalaVersion = new ScalaVersion
    if (!project.getExtensions.getExtraProperties.has("scalaVersion"))
      project.getExtensions.getExtraProperties.set("scalaVersion", scalaVersion)
    else
      scalaVersion = project.getExtensions.getExtraProperties.get("scalaVersion").asInstanceOf[ScalaVersion]

    project.getDependencies.add("compile", s"org.scala-lang:scala-library:${scalaVersion.major}.${scalaVersion.minor}")

    val withScalaVersion = (lib: String) => {
      val libComp = lib.split(":")
      libComp.update(1, s"${libComp(1)}_${scalaVersion.major}")
      libComp.mkString(":")
    }
    project.getExtensions.getExtraProperties.set("withScalaVersion", withScalaVersion)

    project.getTasks.create("createDirs", classOf[CreateDirs])
  }
}

Instalar el proyecto de plugin en el repositorio local de Maven

Esto se hace realmente fácil ejecutando gradle install
Puede verificar la instalación yendo al directorio del repositorio local, que generalmente se encuentra en ~/.m2/repository

¿Cómo encuentra Gradle nuestro nuevo plugin?

Cada complemento de Gradle tiene un id que se utiliza en la declaración de apply . Por ejemplo, al escribir lo siguiente en el archivo de compilación, se traduce en un desencadenante para Gradle para encontrar y aplicar el complemento con id scala .

apply plugin: 'scala'

De la misma manera, nos gustaría aplicar nuestro nuevo complemento de la siguiente manera,

apply plugin: "com.btesila.scala.plugin"

lo que significa que nuestro complemento tendrá el id com.btesila.scala.plugin .

Para establecer este ID, agregue el siguiente archivo:
src / main / resources / META-INF / gradle-plugin / com.btesil.scala.plugin.properties

implementation-class=com.btesila.gradle.plugins.ScalaCustomPlugin

Después, ejecute de nuevo la gradle install .

Usando el plugin

  1. cree un nuevo proyecto Gradle vacío y agregue lo siguiente al archivo de compilación
buildscript {
    repositories {
        mavenLocal()
        mavenCentral()
    }

    dependencies {
        //modify this path to match the installed plugin project in your local repository
        classpath 'com.btesila:working-with-gradle:1.0-SNAPSHOT'
    }
}

repositories {
    mavenLocal()
    mavenCentral()
}


apply plugin: "com.btesila.scala.plugin"

  1. ejecute gradle createDirs - ahora debería tener todos los directorios de origen generados
  2. reemplaza la versión de Scala agregando esto al archivo de compilación:
ext {
    scalaVersion.major = "2.11"
    scalaVersion.minor = "8"

}
println(project.ext.scalaVersion.major)
println(project.ext.scalaVersion.minor)
  1. agregue una biblioteca de dependencias que sea compatible con los binarios de la versión Scala
dependencies {
    compile withScalaVersion("com.typesafe.scala-logging:scala-logging:3.5.0")
}

¡Eso es! Ahora puede usar este complemento en todos sus proyectos sin repetir el mismo texto tradicional.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow