2013-06-11 1 views
2

J'écris un plugin SBT qui ajoute une commande et souhaite que les utilisateurs puissent configurer cette commande en définissant des variables dans leur build.sbt. Quel est le moyen le plus simple d'y parvenir?SBT plugin - Configuration définie par l'utilisateur pour la commande via leur build.sbt

Voici un exemple simplifié de ce que le plug-in ressemble à:

import sbt.Keys._ 
import sbt._ 

object MyPlugin extends Plugin { 

    override lazy val settings = Seq(commands += Command.args("mycommand", "myarg")(myCommand)) 

    def myCommand = (state: State, args: Seq[String]) => { 

    //Logic for command... 

    state 
    } 
} 

Je voudrais que quelqu'un soit en mesure d'ajouter le suivi de leur dossier build.sbt:

newSetting := "light" 

Comment puis-je rendre ceci disponible comme variable String depuis l'intérieur de la commande myCommand ci-dessus?

Répondre

6

Jetez un oeil à l'exemple ici: http://www.scala-sbt.org/release/docs/Extending/Plugins.html#example-plugin

Dans cet exemple, une tâche et les paramètres sont définis:

val newTask = TaskKey[Unit]("new-task") 
val newSetting = SettingKey[String]("new-setting") 

val newSettings = Seq(
    newSetting := "test", 
    newTask <<= newSetting map { str => println(str) } 
) 

Un utilisateur de votre plugin pourrait alors fournir leur propre valeur du paramètre newSetting dans leur build.sbt:

newSetting := "light" 

EDIT

Voici un autre exemple, plus proche de ce que vous allez pour:

Build.scala:

import sbt._             
import Keys._            

object HelloBuild extends Build {       

    val newSetting = SettingKey[String]("new-setting", "a new setting!") 

    val myTask = TaskKey[State]("my-task")     

    val mySettings = Seq(         
     newSetting := "default",        
     myTask <<= (state, newSetting) map { (state, newSetting) => 
     println("newSetting: " + newSetting)     
     state 
     } 
    ) 

    lazy val root = 
     Project(id = "hello", 
       base = file("."), 
       settings = Project.defaultSettings ++ mySettings)    
} 

Avec cette configuration, vous pouvez exécuter my-task à l'invite de SBT, et vous 'll voir newSetting: default imprimé à la console.

Vous pouvez modifier ce paramètre dans build.sbt:

newSetting := "modified" 

Maintenant, lorsque vous exécutez my-task à l'invite de SBT, vous verrez newSetting: modified imprimé à la console.

EDIT 2

est ici une version autonome de l'exemple ci-dessus: https://earldouglas.com/ext/stackoverflow.com/questions/17038663/

+0

Merci!Je vais essayer ça. – theon

+0

J'ai essayé, mais je n'ai pas eu beaucoup de joie. TBH, je ne suis pas sûr de ce qu'est un 'TaskKey', donc je pense que je dois en lire plus à ce sujet. J'ai édité la question pour être plus précis sur mon cas d'utilisation, qui est un plugin SBT qui ajoute un 'Command' SBT et ajouté un exemple de code de ce que j'ai actuellement. Faites-moi savoir si vous avez des idées où je pourrais me tromper. – theon

+0

Trouvé une assez bonne documentation [ici] (http://www.scala-sbt.org/release/docs/Detailed-Topics/Tasks.html#define-the-key) et les tâches et les commandes semblent assez similaires. (Également mentionné [ici] (https://groups.google.com/forum/#!msg/simple-build-tool/vgxkDSgOnlc/BQyKT7nOYnQJ)) Je pense que demain j'essaierai de migrer loin d'utiliser 'Command's pour en utilisant 'Task's. – theon

2

Je l'ai accepté @ la réponse de James comme il m'a vraiment aidé. Je me suis éloigné de l'utilisation d'une commande en faveur d'une tâche (voir this mailing list thread). En fin de mon plugin regardé quelque chose comme ceci:

package packge.to.my.plugin 

import sbt.Keys._ 
import sbt._ 

object MyPlugin extends Plugin { 

    import MyKeys._ 

    object MyKeys { 
    val myTask = TaskKey[Unit]("runme", "This means you can run 'runme' in the SBT console") 
    val newSetting = SettingKey[String]("newSetting") 
    } 

    override lazy val settings = Seq (
    newSetting := "light", 
    myTask <<= (state, newSetting) map myCommand 
) 

    def myCommand(state: State, newSetting: String) { 
    //This code runs when the user types the "runme" command in the SBT console 
    //newSetting is "light" here unless the user overrides in their build.sbt (see below) 
    state.log.info(newSetting) 
    } 
} 

Pour remplacer la newSetting dans le build.sbt d'un projet qui utilise ce plugin:

import packge.to.my.plugin.MyKeys._ 

newSetting := "Something else" 

La déclaration d'importation manquante me avait bloqué pendant un certain temps!

+0

Êtes-vous sûr que l'importation est autorisée dans un fichier '.sbt'? – fommil

+0

Oui, même si cela doit être au sommet du fichier. – theon

Questions connexes