How to read the modified setting defined in my own sbt plugin - sbt

I tried to create my own sbt plugin by following this guide, and had the following code:
build.sbt in myplugin
sbtPlugin := true
lazy val plugin = (project in file(".")).
settings(
name := "myplugin",
version := "0.1-SNAPSHOT",
scalaVersion := "2.10.4"
)
HelloPlugin.scala in myplugin
package sbthello
import sbt._
import Keys._
object HelloPlugin extends AutoPlugin {
object autoImport {
val greeting = settingKey[String]("greeting")
val obfuscate = taskKey[String]("Obfuscates files.")
}
import autoImport._
lazy val baseSettings: Seq[Def.Setting[_]] = Seq(
greeting := "Hi!",
obfuscate := {
println(greeting.value)
greeting.value + " value"
}
)
override val projectSettings =
inConfig(Compile)(baseSettings)
}
the build.sbt in test project is
lazy val usage = (project in file("."))
.enablePlugins(HelloPlugin).
settings(
name := "sbt-test",
version := "0.1",
scalaVersion := "2.10.4")
.settings(
greeting := "Hello"
)
with the files above, the execution result is:
> show obfuscate
Hi!
[info] Hi! value
> show greeting
[info] Hello
the obfuscate task cannot read the "Hello" value
if modify greeting := "Hi!" in HelloPlugin.scala to greeting in obfuscate := "Hi!",
the obfuscate task can read the "Hello" value now
> show greeting
[info] Hello
> show obfuscate
Hello
[info] Hello value
but now I cannot remove greeting := "Hello" in buildInDemo.sbt, or else it will have such errors:
[error] References to undefined settings:
[error]
[error] compile:greeting from compile:obfuscate ((sbthello.HelloPlugin) HelloPlugin.scala:40)
[error] Did you mean compile:obfuscate::greeting ?
[error]
[error] compile:greeting from compile:obfuscate ((sbthello.HelloPlugin) HelloPlugin.scala:40)
[error] Did you mean compile:obfuscate::greeting ?
[error]

configuration scoping
override val projectSettings =
inConfig(Compile)(baseSettings)
This scopes all the settings in baseSettings into Compile configuration. So it's the same as saying:
Define greeting in Compile setting.
Refer to the greeting in Compile setting from obfuscate in Compile task.
So in build.sbt you should customize as
greeting in Compile := "Hello"
You can access this setting from the shell as:
> compile:greeting
If you don't want the behavior, don't put baseSettings in inConfig(...).
task and configuration scoping
greeting in obfuscate is task scoping. So combined with inConfig(...) that'll require
greeting in (Compile, obfuscate) := "Hello"
to customize.
For more details see Scopes.

Related

FlyWay plugin with sbt

I'm trying to apply FlyWay plugin by sbt build configuration.
In plugins.sbt
In my build.sbt:
lazy val CustomConfig = config("custom") extend Runtime
lazy val customSettings: Seq[Def.Setting[_]] = Seq(
flywayUser := "andrej",
flywayPassword := "123456",
flywayUrl := "jdbc:postgresql://localhost:5432/database",
flywayLocations += "db/migration"
)
lazy val flyWay = (project in file("."))
.settings(inConfig(CustomConfig)(FlywayPlugin.flywayBaseSettings(CustomConfig) ++
customSettings): _*)
In resources.db.migration-directory sql-file is created.
And trying to run migration to database it with command: sbt flywayMigrate
But it returns the following errors:
[error] Expected ';'
[error] Not a valid command: flywayMigrate
[error] No such setting/task
[error] flywayMigrate
[error] ^
Looks like you did not enable the plugin.
Add following line to your project/plugin.sbt
addSbtPlugin("io.github.davidmweber" % "flyway-sbt" % "7.4.0")
and enable the plugin in you build.sbt file:
enablePlugins(FlywayPlugin)

sbt says "not a valid command" but plugin enabled

I have a plugin called sonar, which is developed and published as an AutoPlugin:
object Sonar extends AutoPlugin {
object autoImport {
lazy val sonar = taskKey[Unit]("sonar")
}
import autoImport._
override def trigger = allRequirements
lazy val sonarTask = Def.task {
<snip task code here which runs sonarqube scanner>
}
}
We then have a project which uses that plugin, with plugins.sbt that looks like this:
resolvers ++= Seq(
"Nexus Snapshot repo" at "url here"
)
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")
addSbtPlugin("packagename" % "sonar" % "1.0-SNAPSHOT")
And build.sbt like this:
name := "hashing-library"
organization := "org name here"
scalaVersion := "2.12.6"
autoScalaLibrary := false
crossPaths := false
resolvers += "Nexus Release repo" at "https://nexusurl/content/repositories/releases/"
resolvers += "nexus Snapshot repo" at "https://nexusurl/content/repositories/snapshots/"
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")
// Publishing options:
publishMavenStyle := true
publishArtifact in Test := false
pomIncludeRepository := { x => false }
publishTo := {
val nexus = "nexus url here"
if (isSnapshot.value)
Some("sonatype-snapshots" at nexus + "content/repositories/snapshots")
else
Some("sonatype-releases" at nexus + "content/repositories/releases")
}
When I try to run sbt plugins, it says the plugin is enabled:
<snip output>
packagename.sonar.Sonar: enabled in hashingLibrary
So why is it that my plugin is enabled, but I cannot run sbt sonar? When I do, it says:
[info] Set current project to hashing-library (in build file:/home/work/hashing-library/)
[error] Not a valid command: sonar
[error] Not a valid project ID: sonar
[error] Expected ':'
[error] Not a valid key: sonar
[error] sonar
[error]
(Obviously org names and url's have been removed to protect confidentiality of my client, but hopefully that doesn't impact my question!)
The missing part of your plugin is the connection between the sonar task key and the sonarTask task implementation, i.e. you need to say somewhere that the key is set to the value of the implementation. You normally do it by overriding project settings in the plugin:
override def projectSettings = Seq(
sonar := sonarTask.value
)

release snapshots to ojo from sbt

I have "Common.scala" in project dir:
import sbt.Keys._
import sbt._
import bintray.BintrayKeys._
object Common {
val commonSettings = Seq(
organization := "com.github.kondaurovdev",
scalaVersion := "2.11.8",
scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature"),
publishLocal := (),
parallelExecution := false
)
val doNotPublishSettings = Seq(
publish := {},
publishLocal := {}
)
def getPublishSettings(_version: String) = {
if (_version.endsWith("-SNAPSHOT")) {
{
println("is snapshot!")
Seq(
publishTo := Some("Artifactory Realm" at "http://oss.jfrog.org/artifactory/oss-snapshot-local"),
bintrayReleaseOnPublish := false,
credentials := List(Path.userHome / ".bintray" / ".artifactory").filter(_.exists).map(Credentials(_))
)
}
} else {
{
println("is release")
Seq(
bintrayOmitLicense := true,
bintrayRepository := "maven",
publishArtifact in Test := false,
pomExtra :=
<developers>
<developer>
<id>kondaurovdev</id>
<name>Alexander Kondaurov</name>
<email>kondaurov.dev#gmail.com</email>
</developer>
</developers>
)
}
} ++ Seq(
licenses += ("MIT", url("http://opensource.org/licenses/MIT"))
)
}
def myProject(name: String, _version: String = "0.1.1-SNAPSHOT", deps: Seq[ModuleID] = Seq(), settings: Seq[Def.SettingsDefinition] = Seq(), path: Option[String] = None): Project = {
Project(name, file(path.getOrElse(name)))
.settings(
commonSettings ++
getPublishSettings(_version)
)
.settings(
libraryDependencies ++= deps,
version := _version
)
.settings(
settings: _*
)
}
}
And i have thus projects in "build.sbt":
lazy val snippets: Project = {
Common.myProject("snippets", deps = Seq(
Deps.specs2,
Deps.Log.slf4j
))
}
When i try "snippets/publish" i get this errors:
> snippets/publish
[info] Wrote /Users/alexanderkondaurov/Projects/kondaurov/scala/snippets/target/scala-2.11/snippets_2.11-0.1-SNAPSHOT.pom
[info] :: delivering :: com.github.kondaurovdev#snippets_2.11;0.1-SNAPSHOT :: 0.1-SNAPSHOT :: integration :: Sat Jan 21 14:42:01 MSK 2017
[info] delivering ivy file to /Users/alexanderkondaurov/Projects/kondaurov/scala/snippets/target/scala-2.11/ivy-0.1-SNAPSHOT.xml
[error] Unable to find credentials for [Artifactory Realm # oss.jfrog.org].
[trace] Stack trace suppressed: run last snippets/*:bintrayEnsureLicenses for the full output.
[trace] Stack trace suppressed: run last snippets/*:publish for the full output.
[error] (snippets/*:bintrayEnsureLicenses) you must define at least one license for this project. Please choose one or more of
[error] AFL-3.0, AGPL-V3, APL-1.0, APSL-2.0, Apache-1.0, Apache-1.1, Apache-2.0, Artistic-License-2.0, Attribution, BSD, BSD New, BSD Simplified, BSL-1.0, Bouncy-Castle, CA-TOSL-1.1, CDDL-1.0, CPAL-1.0, CPL-1.0, CPOL-1.02, CUAOFFICE-1.0, Codehaus, Day, Day-Addendum, ECL2, EUDATAGRID, EUPL-1.1, Eclipse-1.0, Eiffel-2.0, Entessa-1.0, Fair, Frameworx-1.0, GPL-2.0, GPL-2.0+CE, GPL-3.0, HSQLDB, Historical, IBMPL-1.0, IPAFont-1.0, ISC, IU-Extreme-1.1.1, JA-SIG, JSON, JTidy, LGPL-2.1, LGPL-3.0, Lucent-1.02, MIT, MPL-2.0, MS-PL, MS-RL, MirOS, Motosoto-0.9.1, Mozilla-1.1, Multics, NASA-1.3, NAUMEN, NOSL-3.0, NTP, Nethack, Nokia-1.0a, OCLC-2.0, OSL-3.0, Openfont-1.1, Opengroup, PHP-3.0, PostgreSQL, Public Domain, Public Domain - SUN, PythonPL, PythonSoftFoundation, QTPL-1.0, RPL-1.5, Real-1.0, RicohPL, SUNPublic-1.0, SimPL-2.0, Sleepycat, Sybase-1.0, TMate, Unlicense, UoI-NCSA, VovidaPL-1.0, W3C, WTFPL, Xnet, ZLIB, ZPL-2.0, wxWindows
[error] (snippets/*:publish) java.io.IOException: Access to URL http://oss.jfrog.org/artifactory/oss-snapshot-local/com/github/kondaurovdev/snippets_2.11/0.1-SNAPSHOT/snippets_2.11-0.1-SNAPSHOT.pom was refused by the server: Unauthorized
[error] Total time: 2 s, completed Jan 21, 2017 2:42:03 PM
>
I don't get it why it complains about license, i've included MIT license..
I followed by this article: http://szimano.org/automatic-deployments-to-jfrog-oss-and-bintrayjcentermaven-central-via-travis-ci-from-sbt/
ADDED:
I fixed this license issue by moving
"licenses += ("MIT", url("http://opensource.org/licenses/MIT"))" right after "credentials += ..."
now it look like:
Seq(
publishTo := Some("Artifactory Realm" at "https://oss.jfrog.org/artifactory/oss-snapshot-local"),
bintrayReleaseOnPublish := false,
credentials := List(Path.userHome / ".bintray" / ".artifactory").filter(_.exists()).map(Credentials(_)),
licenses += ("MIT", url("http://opensource.org/licenses/MIT"))
)
That's strange.. Credentials file looks like:
realm = Artifactory Realm
host = oss.jfrog.org
user = *********
password = ***********
And i understood that in order to upload snapshots package it has to be approved by making request to support service. They will create folder for your package. This procedure needs to be done for for every package, are you kidding guys?
I have an account here "https://oss.sonatype.org/". I've there namespace and can upload as many packages as i need, i've expected the same behaviour in OJO. I'm not making approve request to support service every time when i've new package
Setting credentials in ~/.sbt/ is the way forward. Credentials can be in the build.sbt, however username, password is left in plaintext as well as ip address of repository sever.
To set credentials via a configuration file you can use:
credentials += Credentials(Path.userHome / ".sbt" / ".credentials")
This picks up credentials in a file called .credentials which is stored in my ~/.sbt/ dir.
To set credentials in the Credentials obj you can use something like:
credentials += Credentials("Artifactory Realm", "http://<ip>:<port>/artifactory/<repo-key>", "<username>", "<password>")
It's also important to make sure that publishTo has been set with the relevant resolver. An example of which is:
publishTo := Some("Artifactory Realm" at "http://<ip>:<port>/artifactory/<repo-key>
To configure a proxy. The following can be added to a file called repositories stored in ~/.sbt/. An example configuration may look like this:
[repositories]
local
my-ivy-proxy-releases: http://<host>:<port>/artifactory/<repo-key>/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
my-maven-proxy-releases: http://<host>:<port>/artifactory/<repo-key>/

SBT Assembly Plugin Error

I'm trying to run sbt assembly on my project but I get error saying:
[error] Not a valid command: assembly
[error] Not a valid project ID: assembly
[error] Expected ':' (if selecting a configuration)
[error] Not a valid key: assembly
[error] assembly
[error] ^
I have the following structure:
MyProject
- project
- assembly.sbt
- build.properties
- BuildSettings.scala
- MyProjectBuild.scala
- src
- main
- com
- mypkg
- MyMainClass.scala
I have the following in my assembly.sbt:
resolvers += Resolver.url("artifactory", url("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases"))(Resolver.ivyStylePatterns)
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
// dont upgrade to 0.12.0 as there is assembly conflict
My build.properties is:
sbt.version=0.13.6
My BuildSettings.scala is:
import sbt._
import Keys._
object BuildSettings {
lazy val basicSettings = Seq[Setting[_]](
organization := "com.eon.vpp",
version := "0.1.0-SNAPAHOT",
description := "vpp metrics producer to a kafka instance",
scalaVersion := "2.11.7",
scalacOptions := Seq("-deprecation", "-encoding", "utf8"),
resolvers ++= Dependencies.resolutionRepos
)
// sbt-assembly settings for building one fat jar
import sbtassembly.Plugin._
import AssemblyKeys._
lazy val sbtAssemblySettings = assemblySettings ++ Seq(
jarName in assembly := {
name.value + "-" + version.value + ".jar"
},
// META-INF discarding
mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) =>
{
case PathList("META-INF", xs # _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
}
)
lazy val buildSettings = basicSettings ++ sbtAssemblySettings
}
Any suggestions as to why is this error?
Yes, I figured out what the problem was. I had to move the plugins.sbt file inside the project folder. It was that simple!

How do I specify scope in build.sbt

I have a variable libDir defined in Global & when I try to use it inside one of the sub-projects (with specifying the scope), it fails with:
[info] Loading project definition from /Users/chichu/ws/tip/TestMain/project
References to undefined settings:
*/*:libDir from Streaming/*:install (/Users/chinchu/ws/tip/TestMain/build.sbt:124)
Did you mean TestRoot/*:libDir ?
Here's the snippet from build.sbt:
===
def Streaming(name: String, dir: String,
archiveName: String, main: String): Project = {
...
...
install := {
val jarName = assembly.value
sbt.IO.copyFile(jarName, (libDir in Global).value) // copy over the jar
}
}
..
..
lazy val installDir = SettingKeyFile
libDir := baseDirectory.value / "install/lib"
==
Why is it not able to resolve "libDir" even when I specify "in Global" ? I also tried "libDir in TestRoot" & it reports "error: not found: value TestRoot"
Thanks
-C
The specification says, that if you define a setting like this:
libDir := baseDirectory.value / "install/lib"
It will set a task and a configuration scope to Global, but a project scope will be set to current project (that is a root project in your case).
When you refer to your setting as libDir in Global, you set configuration scope to Global but still, you are in the current build, that is some project, that tries to define the install setting.
You should define your libDir like this:
libDir in Global := baseDirectory.value / "install/lib"
which will set also the project scope to Global.
Example build.sbt
lazy val installDir = settingKey[File]("ff")
lazy val install = taskKey[Unit]("prints install")
installDir in Global := baseDirectory.value / "install/lib"
val projectA = project.in(file("projectA")).settings(
install := {
val install = (installDir in Global).value
println(install)
}
)
val projectB = project
Alternative Solution
Alternatively you could give a root project an explicit id, that is in your main build.sbt add a line
val root = Project("root", file("."))
then in your install task refer to Global in that project (root is a name of the project)
(libDir in Global in root).value
Example build.sbt
lazy val installDir = settingKey[File]("ff")
lazy val install = taskKey[Unit]("prints install")
installDir := baseDirectory.value / "install/lib"
lazy val root = Project("root", file("."))
lazy val projectA = project.in(file("projectA")).settings(
install := {
val install = (installDir in Global in root).value
println(install)
}
)
lazy val projectB = project

Resources