Composing Project Archetyps with SBT AutoPlugins

1,222 views

Published on

A talk give at PNW Scala 2014 about how the Allen Institute for Artificial Intelligence is using the SBT 0.13.5 AutoPlugin architecture to compose plugins for archetypical projects.

Published in: Software
1 Comment
1 Like
Statistics
Notes
No Downloads
Views
Total views
1,222
On SlideShare
0
From Embeds
0
Number of Embeds
15
Actions
Shares
0
Downloads
18
Comments
1
Likes
1
Embeds 0
No embeds

No notes for slide

Composing Project Archetyps with SBT AutoPlugins

  1. 1. Composing Project Archetypes with SBT AutoPlugins Mark Schaake allenai.org “contribute to humanity through high-impact AI research and engineering”
  2. 2. Composing Project Archetypes with SBT AutoPlugins Mark Schaake allenai.org “contribute to humanity through high-impact AI research and engineering”
  3. 3. Combatting Multiple Build Maintenance Hell with Archetype AutoPlugins Mark Schaake allenai.org “contribute to humanity through high-impact AI research and engineering”
  4. 4. “When you have very limited visibility and control over many project builds to the point where you feel paralyzed to maintaining cross- project consistency.” (Multiple Build Maintenance Hell) MBMH • visibility: what libraries, plugins, versions? • control: how to enforce team standards, upgrades? • consistency: minimize context switching
  5. 5. SOA, Inc. • SOA architecture • Scala, Akka, Spray
  6. 6. Svc A Plugins Projects Dependencies
  7. 7. Svc A Plugins Projects Dependencies packager 0.6.0 scalariform 1.3 // native packager for generating deployable artifacts addSbtPlugin( "com.typesafe.sbt" % "sbt-native-packager" % "0.6.0")   // format our code in SBT instead of our editors addSbtPlugin( "com.typesafe.sbt" % "sbt-scalariform" % "1.3.0") project/plugins.sbt
  8. 8. Svc A Plugins Projects Dependencies packager 0.6.0 scalariform 1.3 // native packager for generating deployable artifacts addSbtPlugin( "com.typesafe.sbt" % "sbt-native-packager" % "0.6.0")   // format our code in SBT instead of our editors addSbtPlugin( "com.typesafe.sbt" % "sbt-scalariform" % "1.3.0") project/plugins.sbt akka 2.3.2 spray 1.3.0 dispatch 0.11.1 scala 2.10.2 organization := "com.soa"   name := "service-a"   scalaVersion := "2.10.2"   libraryDependencies ++= Seq( "io.spray" % "spray-can" % "1.3.0", "io.spray" % "spray-routing" % "1.3.0", "com.typesafe.akka" %% "akka-actor" % "2.3.2", "com.typesafe.akka" %% "akka-slf4j" % "2.3.2", "net.databinder" %% "dispatch-core" % "0.11.1", "ch.qos.logback" % "logback-classic" % "1.1.2" ... ) build.sbt
  9. 9. // native packager for generating deployable artifacts addSbtPlugin( "com.typesafe.sbt" % "sbt-native-packager" % "0.6.0")   // format our code in SBT instead of our editors addSbtPlugin( "com.typesafe.sbt" % "sbt-scalariform" % "1.3.0") // native packager for generating deployable artifacts addSbtPlugin( "com.typesafe.sbt" % "sbt-native-packager" % "0.6.0")   // format our code in SBT instead of our editors addSbtPlugin( "com.typesafe.sbt" % "sbt-scalariform" % “1.3.0") addSbtPlugin( “org.scalastyle" %% "scalastyle" % “0.5.0") Svc A Plugins Projects Dependencies akka 2.3.2 spray 1.3.0 dispatch 0.11.1Svc B akka 2.3.4 spray 1.3.1 scala 2.10.2 scala 2.11.1 packager 0.6.0 scalastyle scalariform 1.3 organization := "com.soa"   name := "service-a"   scalaVersion := "2.10.2"   libraryDependencies ++= Seq( "io.spray" % "spray-can" % "1.3.0", "io.spray" % "spray-routing" % "1.3.0", "com.typesafe.akka" %% "akka-actor" % "2.3.2", "com.typesafe.akka" %% "akka-slf4j" % "2.3.2", "net.databinder" %% "dispatch-core" % "0.11.1", "ch.qos.logback" % "logback-classic" % "1.1.2" ... ) build.sbt organization := "com.soa"   name := "service-b"   scalaVersion := "2.11.1"   libraryDependencies ++= Seq( "io.spray" % "spray-can" % "1.3.1", "io.spray" % "spray-routing" % "1.3.1", "com.typesafe.akka" %% "akka-actor" % "2.3.4", "com.typesafe.akka" %% "akka-slf4j" % "2.3.4", "net.databinder" %% "dispatch-core" % "0.11.1", "ch.qos.logback" % "logback-classic" % "1.1.2" ... ) project/plugins.sbt
  10. 10. Svc A Plugins Projects Dependencies akka 2.3.2 spray 1.3.0 dispatch 0.11.1Svc B akka 2.3.4 spray-client 1.3.2 spray 1.3.1 Svc C scala 2.10.2 scala 2.11.1 akka 2.3.6 spray 1.3.2 packager 0.6.0 scalastyle packager 0.7.2 scalariform 1.3 scalariform 1.5
  11. 11. Svc A Plugins Projects Dependencies akka 2.3.2 spray 1.3.0 dispatch 0.11.1Svc B akka 2.3.4 spray-client 1.3.2 spray 1.3.1 Svc C scala 2.10.2 scala 2.11.1 akka 2.3.6 spray 1.3.2 Svc D packager 0.6.0 scalastyle packager 0.7.2 scalariform 1.3 scalariform 1.5
  12. 12. Svc A Plugins Projects Dependencies akka 2.3.2 spray 1.3.0 dispatch 0.11.1Svc B akka 2.3.4 spray-client 1.3.2 spray 1.3.1 Svc C scala 2.10.2 scala 2.11.1 akka 2.3.6 spray 1.3.2 Svc D packager 0.6.0 scalastyle packager 0.7.2 scalariform 1.3 scalariform 1.5 … Lib X Lib Y CLI Z scopt … sbt-release assembly
  13. 13. project/plugins.sbt 6 build.sbt 50 Project build LOC 56 x 26 projects = 1,456 LOC! … … Avg Project Build LOC and mostly boilerplate
  14. 14. project/plugins.sbt 6 build.sbt 50 Project build LOC 56 x 26 projects = 1,456 LOC! … … Avg Project Build LOC and mostly boilerplate MBMH!
  15. 15. and MBMH BuildLOC 500 1,000 1,500 2,000 2,500 Projects 15 30 45 60 Jan March May July Sept Nov Projects Build LOC
  16. 16. and MBMH BuildLOC 500 1,000 1,500 2,000 2,500 Projects 15 30 45 60 Jan March May July Sept Nov Projects Build LOC M
  17. 17. BuildLOC 500 1,000 1,500 2,000 2,500 Projects 15 30 45 60 Jan March May July Sept Nov Projects Build LOC MBMH and MBMH Yay!
  18. 18. Solving MBMH
  19. 19. Solving • Maximize consistency across projects MBMH
  20. 20. Solving • Maximize consistency across projects • Minimize build complexity (LOC) MBMH
  21. 21. Solving • Maximize consistency across projects • Minimize build complexity (LOC) • Maximize agility to evolve standards MBMH
  22. 22. Solving • Maximize consistency across projects • Minimize build complexity (LOC) • Maximize agility to evolve standards • Allow for stragglers (don’t force upgrades) MBMH
  23. 23. Solving • Maximize consistency across projects • Minimize build complexity (LOC) • Maximize agility to evolve standards • Allow for stragglers (don’t force upgrades) • Easy build upgrade path MBMH
  24. 24. Other Considerations
  25. 25. Other Considerations • Archetype settings shared by similar projects
  26. 26. Other Considerations • Archetype settings shared by similar projects • Core settings common to all projects
  27. 27. Other Considerations • Archetype settings shared by similar projects • Core settings common to all projects • Formatting and Style
  28. 28. Other Considerations • Archetype settings shared by similar projects • Core settings common to all projects • Formatting and Style • Generate Git version resource
  29. 29. Solution: Archetype SBT Plugins
  30. 30. Solution: Archetype SBT Plugins • Projects enable a single (versioned) archetype plugin
  31. 31. Solution: Archetype SBT Plugins • Projects enable a single (versioned) archetype plugin • Archetype plugin provides: • core build settings (style, scala version, etc.)
  32. 32. Solution: Archetype SBT Plugins • Projects enable a single (versioned) archetype plugin • Archetype plugin provides: • core build settings (style, scala version, etc.) • archetype build settings (deploy, publish, etc.)
  33. 33. Solution: Archetype SBT Plugins • Projects enable a single (versioned) archetype plugin • Archetype plugin provides: • core build settings (style, scala version, etc.) • archetype build settings (deploy, publish, etc.) • archetype dependencies (e.g. spray, akka, scopt)
  34. 34. Solution: Archetype SBT Plugins • Projects enable a single (versioned) archetype plugin • Archetype plugin provides: • core build settings (style, scala version, etc.) • archetype build settings (deploy, publish, etc.) • archetype dependencies (e.g. spray, akka, scopt) • Project upgraded upgraded by upgrading plugin version
  35. 35. Svc A Plugins Projects Dependencies akka 2.3.2 spray 1.3.0 dispatch 0.11.1Svc B akka 2.3.4 spray-client 1.3.2 spray 1.3.1 Svc C scala 2.10.2 scala 2.11.1 akka 2.3.6 spray 1.3.2 Svc D packager 0.6.0 scalastyle packager 0.7.2 scalariform 1.3 scalariform 1.5 Web Services
  36. 36. web-service 1.0 Svc A akka 2.3.2 spray 1.3.0 dispatch 0.11.1 Svc B Svc C scala 2.10.2 Svc D packager 0.6.0 scalariform 1.3 web-service 2.0 akka 2.3.4 spray 1.3.1 dispatch 0.11.1 scala 2.11.1packager 0.6.0 scalariform 1.3 scalastyle web-service 2.1 akka 2.3.6 spray 1.3.2 spray-client 1.3.2 scala 2.11.1packager 0.7.2 scalariform 1.5 scalastyle <app-specific dependencies> Plugins Projects Dependencies Web Services sbt-revolver sbt-revolver sbt-revolver
  37. 37. web-service 1.0 Svc A Archetype Plugins Projects Svc B Svc C Svc D web-service 2.0 web-service 2.1 library 1.0 library 1.1 cli 1.0 Lib X Lib Y CLI Z … … … web-app 1.0 App W …
  38. 38. web-service 1.0 Svc A Archetype Plugins Projects Svc B Svc C Svc D web-service 2.0 web-service 2.1 library 1.0 library 1.1 cli 1.0 Lib X Lib Y CLI Z … … … web-app 1.0 App W …
  39. 39. Before Archetypes import com.typesafe.sbt.SbtNativePackager._ import org.scalastyle.sbt.ScalastylePlugin scalaVersion := "2.10.2" name := "Proj B" Revolver.settings scalariformSettings ScalariformKeys.preferences := ScalariformKeys.preferences.value .setPreference(DoubleIndentClassDeclaration, true) .setPreference(MultilineScaladocCommentsStartOnFirstLine, true) .setPreference(PlaceScaladocAsterisksBeneathSecondAsterisk, true) ScalastylePlugin.Settings libraryDependencies ++= Seq( "com.typesafe.akka" %% "akka-actor" % "2.3.1", "io.spray" % "spray-can" % "1.3.2", "io.spray" % "spray-routing" % "1.3.2", "io.spray" % "spray-cace" % "1.3.2", "io.spray" % "spray-json" % "1.2.6", "net.databinder.dispatch" %% "dispatch-core" % "0.11.0" ) … addSbtPlugin("com.github.gzeitz" % "sbt-release" % "0.8") addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.2.1") addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.6.4") addSbtPlugin("io.spray" % "sbt-revolver" % "0.6.2") addSbtPlugin("org.allenai.plugins" % "version-injector" % "0.2.2") addSbtPlugin("org.allenai.plugins" % "publisher" % "0.2.2")
  40. 40. Before Archetypes import com.typesafe.sbt.SbtNativePackager._ import org.scalastyle.sbt.ScalastylePlugin scalaVersion := "2.10.2" name := "Proj B" Revolver.settings scalariformSettings ScalariformKeys.preferences := ScalariformKeys.preferences.value .setPreference(DoubleIndentClassDeclaration, true) .setPreference(MultilineScaladocCommentsStartOnFirstLine, true) .setPreference(PlaceScaladocAsterisksBeneathSecondAsterisk, true) ScalastylePlugin.Settings libraryDependencies ++= Seq( "com.typesafe.akka" %% "akka-actor" % "2.3.1", "io.spray" % "spray-can" % "1.3.2", "io.spray" % "spray-routing" % "1.3.2", "io.spray" % "spray-cace" % "1.3.2", "io.spray" % "spray-json" % "1.2.6", "net.databinder.dispatch" %% "dispatch-core" % "0.11.0" ) … addSbtPlugin("com.github.gzeitz" % "sbt-release" % "0.8") addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.2.1") addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.6.4") addSbtPlugin("io.spray" % "sbt-revolver" % "0.6.2") addSbtPlugin("org.allenai.plugins" % "version-injector" % "0.2.2") addSbtPlugin("org.allenai.plugins" % "publisher" % "0.2.2") name := "Proj B" enablePlugins(WebServicePlugin) addSbtPlugin("org.allenai.plugins" % "plugins" % “1.0”) After Archetypes LOC Before 56 LOC After 3 LOC Reduction 95%
  41. 41. Implementing Archetype Plugins
  42. 42. Implementing Archetype Plugins • How to wrap / depend on other plugins?
  43. 43. Implementing Archetype Plugins • How to wrap / depend on other plugins? • How to include core settings in each archetype?
  44. 44. ArchetypePlugins What AI2 Needed Library Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver Web App libraryDependencies: - ai2Webapp settings: - npm:* - reStart dependsOn npm:build - universal:mappings + npm:target CLI libraryDependencies: - scopt
  45. 45. ArchetypePlugins What AI2 Needed Library Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver Web App libraryDependencies: - ai2Webapp settings: - npm:* - reStart dependsOn npm:build - universal:mappings + npm:target CLI libraryDependencies: - scopt AuxiliaryPlugins Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Deploy wrapped plugins: - sbt-native-packager command: - deploy Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Release wrapped plugins: - sbt-release settings: - custom versioning NodeJs commands: - npm <args> - npm:install - npm:build - npm:test - nom:clean settings: - npm:nodeProjectDir - npm:nodeProjectTarget - npm:buildEnvironment - nom:environment Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle
  46. 46. (Vanilla) SBT Plugins? • Loosely defined API • What are the right conventions?
  47. 47. Adding Popular SBT Plugin Settings “To add the default plugin settings, add the following to your build.sbt…”
  48. 48. Adding Popular SBT Plugin Settings “To add the default plugin settings, add the following to your build.sbt…” import com.typesafe.sbt.SbtNativePackager._ import NativePackagerKeys._ packageArchetype.java_application sbt-native-packager org.scalastyle.sbt.ScalastylePlugin.Settings sbt-scalastyle scalariformSettings sbt-scalariform Revolver.settings sbt-revolver
  49. 49. SBT AutoPlugins • The new Plugin standard (since SBT 0.13.5)
  50. 50. SBT AutoPlugins • The new Plugin standard (since SBT 0.13.5) • Well-defined plugin API
  51. 51. SBT AutoPlugins • The new Plugin standard (since SBT 0.13.5) • Well-defined plugin API • Less need for conventions
  52. 52. SBT AutoPlugins • The new Plugin standard (since SBT 0.13.5) • Well-defined plugin API • Less need for conventions • Killer feature: can compose plugins via `requires`
  53. 53. abstract class AutoPlugin { … /** When this AutoPlugin is enabled, all required * plugins will also be enabled automatically prior * to enabling this AutoPlugin. */ def requires: Plugins = empty /** The [[Setting]]s to add in the scope of each * project that activates this AutoPlugin. */ def projectSettings: Seq[Setting[_]] = Nil … } SBT AutoPlugins https://github.com/sbt/sbt/blob/0.13.7/main/src/main/scala/sbt/Plugins.scala
  54. 54. Core Settings AutoPlugin object CoreSettingsPlugin extends AutoPlugin {   override def requires = StylePlugin && VersionInjectorPlugin   override def projectSettings = Seq( scalaVersion := CoreDependencies.defaultScalaVersion, scalacOptions ++= Seq("-target:jvm-1.7", "-Xlint", "-deprecation"), javacOptions ++= Seq("-source", "1.7", "-target", “1.7"), … ) } Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle
  55. 55. Core Settings AutoPlugin When CoreSettingsPlugin is enabled… object CoreSettingsPlugin extends AutoPlugin {   override def requires = StylePlugin && VersionInjectorPlugin   override def projectSettings = Seq( scalaVersion := CoreDependencies.defaultScalaVersion, scalacOptions ++= Seq("-target:jvm-1.7", "-Xlint", "-deprecation"), javacOptions ++= Seq("-source", "1.7", "-target", “1.7"), … ) }
  56. 56. Core Settings AutoPlugin 1. adds projectSettings from StylePlugin and VersionInjector When CoreSettingsPlugin is enabled… object CoreSettingsPlugin extends AutoPlugin {   override def requires = StylePlugin && VersionInjectorPlugin   override def projectSettings = Seq( scalaVersion := CoreDependencies.defaultScalaVersion, scalacOptions ++= Seq("-target:jvm-1.7", "-Xlint", "-deprecation"), javacOptions ++= Seq("-source", "1.7", "-target", “1.7"), … ) }
  57. 57. Core Settings AutoPlugin 1. adds projectSettings from StylePlugin and VersionInjector 2. adds projectSettings from CoreSettings When CoreSettingsPlugin is enabled… object CoreSettingsPlugin extends AutoPlugin {   override def requires = StylePlugin && VersionInjectorPlugin   override def projectSettings = Seq( scalaVersion := CoreDependencies.defaultScalaVersion, scalacOptions ++= Seq("-target:jvm-1.7", "-Xlint", "-deprecation"), javacOptions ++= Seq("-source", "1.7", "-target", “1.7"), … ) }
  58. 58. Composing an Archetype Plugin Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Deploy wrapped plugins: - sbt-native-packager command: - deploy Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle object WebServicePlugin extends AutoPlugin { override def requires = CoreSettingsPlugin && DeployPlugin override def projectSettings = Revolver.settings ++ Seq( libraryDependencies ++= Seq( akkaActor, akkaLogging, sprayCan, sprayRouting, sprayJson, allenAiCommon, allenAiTestkit % "test")) }
  59. 59. Composing an Archetype Plugin Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Deploy wrapped plugins: - sbt-native-packager command: - deploy Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle object WebServicePlugin extends AutoPlugin { override def requires = CoreSettingsPlugin && DeployPlugin override def projectSettings = Revolver.settings ++ Seq( libraryDependencies ++= Seq( akkaActor, akkaLogging, sprayCan, sprayRouting, sprayJson, allenAiCommon, allenAiTestkit % "test")) }
  60. 60. Composing an Archetype Plugin Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Deploy wrapped plugins: - sbt-native-packager command: - deploy Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle object WebServicePlugin extends AutoPlugin { override def requires = CoreSettingsPlugin && DeployPlugin override def projectSettings = Revolver.settings ++ Seq( libraryDependencies ++= Seq( akkaActor, akkaLogging, sprayCan, sprayRouting, sprayJson, allenAiCommon, allenAiTestkit % "test")) }
  61. 61. Composing an Archetype Plugin Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Deploy wrapped plugins: - sbt-native-packager command: - deploy Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle object WebServicePlugin extends AutoPlugin { override def requires = CoreSettingsPlugin && DeployPlugin override def projectSettings = Revolver.settings ++ Seq( libraryDependencies ++= Seq( akkaActor, akkaLogging, sprayCan, sprayRouting, sprayJson, allenAiCommon, allenAiTestkit % "test")) } When WebServicePlugin is enabled…
  62. 62. Composing an Archetype Plugin 1. Style and Versioning applied Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Deploy wrapped plugins: - sbt-native-packager command: - deploy Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle object WebServicePlugin extends AutoPlugin { override def requires = CoreSettingsPlugin && DeployPlugin override def projectSettings = Revolver.settings ++ Seq( libraryDependencies ++= Seq( akkaActor, akkaLogging, sprayCan, sprayRouting, sprayJson, allenAiCommon, allenAiTestkit % "test")) } When WebServicePlugin is enabled…
  63. 63. Composing an Archetype Plugin 1. Style and Versioning applied 2. CoreSettings and Deploy applied Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Deploy wrapped plugins: - sbt-native-packager command: - deploy Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle object WebServicePlugin extends AutoPlugin { override def requires = CoreSettingsPlugin && DeployPlugin override def projectSettings = Revolver.settings ++ Seq( libraryDependencies ++= Seq( akkaActor, akkaLogging, sprayCan, sprayRouting, sprayJson, allenAiCommon, allenAiTestkit % "test")) } When WebServicePlugin is enabled…
  64. 64. Composing an Archetype Plugin 1. Style and Versioning applied 2. CoreSettings and Deploy applied 3. WebService applied Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Deploy wrapped plugins: - sbt-native-packager command: - deploy Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle object WebServicePlugin extends AutoPlugin { override def requires = CoreSettingsPlugin && DeployPlugin override def projectSettings = Revolver.settings ++ Seq( libraryDependencies ++= Seq( akkaActor, akkaLogging, sprayCan, sprayRouting, sprayJson, allenAiCommon, allenAiTestkit % "test")) } When WebServicePlugin is enabled…
  65. 65. ArchetypePluginsAuxiliaryPlugins Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle Deploy wrapped plugins: - sbt-native-packager command: - deploy
  66. 66. ArchetypePluginsAuxiliaryPlugins Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle Release wrapped plugins: - sbt-release settings: - custom versioning Library Deploy wrapped plugins: - sbt-native-packager command: - deploy
  67. 67. ArchetypePluginsAuxiliaryPlugins Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver CLI libraryDependencies: - scopt Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle Release wrapped plugins: - sbt-release settings: - custom versioning Library Deploy wrapped plugins: - sbt-native-packager command: - deploy
  68. 68. ArchetypePluginsAuxiliaryPlugins Web Service libraryDependencies: - akka - spray - spray-json - typesafeConfig - ai2Common - ai2Testkit wrapped plugins: - sbt-revolver CLI libraryDependencies: - scopt Core Settings scalaVersion: 2.10.4 scalacOptions: … conflictManager: strict common library ModuleIDs - ai2Common, ai2Testkit, … - akka, spray, spray-json Versioning tasks: - injectVersion - injectArtifact - injectGit - gitCommitDate - gitRemotes - gitSha1 - gitDescribe Style wrapped plugins: - scalariform - scalastyle settings: - apply scalariform - apply scalastyle Release wrapped plugins: - sbt-release settings: - custom versioning Library Deploy wrapped plugins: - sbt-native-packager command: - deploy Web App libraryDependencies: - ai2Webapp settings: - npm:* - reStart dependsOn npm:build - universal:mappings + npm:target NodeJs commands: - npm <args> - npm:install - npm:build - npm:test - nom:clean settings: - npm:nodeProjectDir - npm:nodeProjectTarget - npm:buildEnvironment - nom:environment
  69. 69. Archetype Plugins in Action
  70. 70. Resources • SBT docs - http://www.scala-sbt.org/0.13/docs/Plugins.html • Tutorial - http://mukis.de/pages/sbt-autoplugins-tutorial/ • AI2 sbt-plugins: https://github.com/allenai/sbt-plugins
  71. 71. Questions Mark Schaake marks@allenai.org @markschaake
  72. 72. Project Archetype Recipe • Create a company “sbt-plugins” project • Wrap third-party plugins (scalariform, scalastyle, etc.) • Define a core settings AutoPlugin that enforces team standards • Define archetype plugins that require core settings and add in archetype-specific settings • Publish to Bintray and serve!

×