built.sbt without .repositories file - scala

My question is pretty simple. Let us consider, that I had a scala project, based on SBT. So, when I'm opening my project in IntelliJ IDEA, SBT tries to resolve dependencies during project, downloads *.jar files .ivy2\cache folder and compiles normally. My repositories file:
[repositories]
local
mynewproxy: http://proxy/myproject
The problem is I want to add some specific flags, that will be response to various ways of building - particulary describes various proxy to my repo. But replacing repositories file is not a convinient way, and I want to put my repo-settings directly to build.sbt file;
And there where my problems begin:
Is it possible not to use repositories file (just remove from .sbt folder) and put all it's information to build.sbt?
What I have to wrote in build.sbt instead local in repositories file?
Thanks!

These are called resolvers in sbt-parlance. The relevant section of the sbt docs should be enough to get you started on configuring them.

Related

How to split build.sbt in a Play Framework Project?

I am not sure how to split the build.sbt file in a Play project. Usually in the Play projects I have seen only one build.sbt file, but the project I am referring to have multiple build files in addition to the build.sbt file like:
build.checkstyle.sbt
build.findbugs.sbt
build.junit.sbt
I am not sure if they have split the build.sbt file or is it something else all together. Can anybody help me understand what is happening here?
One more thing is I know what are the purpose of these files like the checkstyle file is used for code style checking and the junit file is for the unit testing. These functions are working perfectly fine, but what I am struggling to understand is how/where did they configure it. I mean these files are not imported by the base build.sbt file so how is the configuration done?
This is just how sbt works. It scans your project for .sbt files, not only a build.sbt file. From sbt docs:
Any time files ending in .scala or .sbt are used, naming them build.sbt and Build.scala are conventions only. This also means that multiple files are allowed.
So, basically, at the mentioned project, people decided that it would be better to split the settings in different files. There is nothing special to do and sbt will handle that for you. Another example is Playframework itself:
https://github.com/playframework/playframework/tree/master/framework
See how it have a build.sbt and a version.sbt files. This is also just a convention so that you can configure the project version at a separated file (which is understood by some sbt plugins, like sbt-release).

Maven setting.xml equivalent for sbt

To keep artifacts separate, origin of packages differentiated and my development environments clean; I use separate settings.xml files for groups of projects. So and I invoke maven with command as:
mvn -s $PROJECT_ROOT/mvn_settings.xml compile
How can I configure sbt in a similar way? My workplace provides an internally hosted JFrog repository which has sbt and Ivy plugins enabled. I have tried looking up search engine with various keyword but couldn't find matching documentation.
I use IntelliJ Idea CE with Scala plugin, if this is relevant.
Edit 1: I want to be able to control where my artifacts are stored, their origin and their association with individual projects.
Edit 2: Consider two settings.xml's
For my random project with minimal libs from maven central: https://pastebin.com/nLc1PGa3
My company's projects in one big bin: https://pastebin.com/R6a4jGQC All from separate sources, in their own respective folders. Also I can move my projects independently, not worrying which dependency link might break something else unrelated.
First grouping things by settings.xml in Maven is not the best way to go. Better is to use the repository manager which can have routes to the particular repositories and to separate repositories and their specific intention. (I'm using a single settings.xml for years which has not been changed. Only the configuration in my repository manager is handling that; This makes life easier and also on CI systems).
Based on the docs of sbt you can configure the proxy repositories like this in the ~/.sbt/repositories file:
[repositories]
local
my-ivy-proxy-releases: http://repo.company.com/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
my-maven-proxy-releases: http://repo.company.com/maven-releases/
Though anytime later or soon I would suggest the same practice as by #khmarbaise to be followed in any of the projects that you are building.
Since there seems to be no point of keeping different folders for repositories if they are from the same group and artifact or even if they are different with maven/sbt providing the support to build different projects using differently specified dependencies.
Similar to maven there can be a Build Settings Concatenation for build.sbt which would work as -
They are appended in this order:
Settings from Build.settings and Project.settings in your .scala files.
Your user-global settings; for example in ~/.sbt/build.sbt you can define settings affecting all your projects.
Settings injected by plugins, see using plugins coming up next.
Settings from .sbt files in the project.
Build definition projects (i.e. projects inside project) have settings from global plugins (~/.sbt/plugins) added. Using plugins
explains this more. Later settings override earlier ones. The entire
list of settings forms the build definition.
So you can override your global build.sbt to specify the repository path using
"Local Maven" at Path.userHome.asFile.toURI.toURL + ".m2/repository"
You should be able to use a Configuration object to do this.
For example in an .sbt file:
val MyConfig = Configurations.config("my-config").extend(Compile)
(resolvers in MyConfig) := Seq(???)
Then when you use the sbt shell you can call
my-config/compile
And it will use the settings you've declared only for that scope.
Then you can declare as many configurations as needed.
I think you are looking for publishing artifacts to your company's internal JFrog repository.
The relevant JFrog documentation can be found here - https://www.jfrog.com/confluence/display/RTF/SBT+Repositories#SBTRepositories-DeployingArtifacts
I was looking at sbt command line help and I found I can set path to local ivy repository using -ivy option.

Add local dependency jar in SBT-Scalatra project

I am working on a sample scalatra webapp. I have created one more service jar which contains dao and service layer. I want to add this dependency in Scalatra-SBT project. How can i achieve this?
I bundled my service jar using command : SBT package which created a jar. How will i include this jar in web application? Can i add this in build.scala file? or can i copy into any Webapp folder ?
Is it possible to push this jar to local repository and pull it from there when my webapp builds?
Whew! Lots of questions here!
The good news is that SBT can do all of the tasks that you are asking for.
DO NOT copy JAR files around to satisfy dependencies! It will end up in tears, virtually guaranteed. Tools like Ivy and Maven (and by extension, SBT) are here to help.
To push your service jar to a local repo:
The SBT task is publish-local, i.e. sbt publish-local from your service jar's root directory.
You'll see lots of descriptive output, finishing up with lines in the following format:
[info] published services_2.10 to /Users/millhouse/.ivy2/local/services/services_2.10/0.1-SNAPSHOT/jars/services_2.10.jar
You don't need to do anything special in your build.sbt to make this work, as long as you have the name and scalaVersion variables set. Note that this will publish to your local Ivy cache, which is $HOME/.ivy2/local for most people.
To get your Scalatra-SBT webapp to pick up your service jar:
Edit your webapp's project/build.scala, adding this dependency under the libraryDependencies key (there should already be a few dependencies, one per line, put yours somewhere in the middle!):
"services" %% "services" % "0.1-SNAPSHOT",
Perform an sbt clean update and your dependency will be pulled in. If it doesn't work, SBT will give you a list of the places where it looked for the artifacts; compare it closely with the location that they were published to (in the previous step) and you'll probably find a typo; fix it and try again.
Please note that there is a lot more to dependency and release management than I've shown above, but this should be enough to get you going.

(SBT) How to disable default resolver and only use the company internal resolver?

We want to use company internal ivy/maven repository (artifactory) to improve the speed of resolving, and downloading the jar files, and also we want to use it to exchange binary jar files between different teams in our organization.
I know we can force SBT to go through proxy by setting ~/.repositories with
[repositories]
local
my-ivy-proxy-releases: http://repo.alpinenow.com/artifactory/repo/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
my-maven-proxy-releases: http://repo.alpinenow.com/artifactory/repo/
and then launch SBT with -Dsbt.override.build.repos=true. This method works for me.
However, it's kind of cumbersome to ask all the developers to setup this way. We're wondering if we can override the default resolvers completely in Build.scala, and plugin.sbt without extra configuration.
So far, I've tried the following ways without success.
1) In both Build.scala and plugin.sbt, I added
resolvers := "Local Repo" at "http://repo.alpinenow.com/artifactory/repo/",
externalResolvers := Seq(Resolver.url("Local Repo", url("http://repo.alpinenow.com/artifactory/repo"))(Resolver.ivyStylePatterns)),
but it still downloads the jars from typesafe and maven1.
2) I then decided to put repositories file into project folder, and tried to add java option directly inside plugin.sbt, and Build.scala with
System.setProperty("-Dsbt.override.build.repos", "true"),
System.setProperty("-Dsbt.repository.config", "project/repositories"),
but it still doesn't work. I'm curious when the SBT gets the java options for resolvers since obviously, it's before plugin.sbt and Build.scala.
Any idea?
Thanks.
DB Tsai
Project level
According to the documentation we should be using externalResolvers:
https://www.scala-sbt.org/release/docs/Library-Dependencies.html#Overriding+default+resolvers
externalResolvers := Seq(
"Local Repo" at "http://repo.alpinenow.com/artifactory/repo/",
// some more internal Nexus repositories
)
Plugin level
You'll have to do it also in your project folder for plugins like in project/resolvers.sbt.
Global SBT level
And if you also want SBT it self to resolve from a specific repo, you'll need to do as described here:
https://www.scala-sbt.org/1.x/docs/Proxy-Repositories.html
If you depart from the sbt-extras shell script as a replacement for the default launcher script, I guess you could easily modify that with setting up ~/.repositories and adding -Dsbt.override.build.repos=true. Then all you need to do is ensure your developers use that script.
I am always adding SBT build as part of my repo in SVN/GIT, close with code. Then I have no such problems.
It costs about 1MB space so is quite cheap and solves a lot of problems. All developers use identical build tool. Even if I try to create Continues Integration or more advanced Continues Delivery process all SBT configs will be already well configured in my SCM. I will get one source of true :)

SBT: Simplest way to separate plugins.sbt

This is a very simple question, but I surprisingly havn't gotten an answer for it yet.
Simply put, in most non trivial SBT projects you will have a plugins.sbt file that contains plugins that are required to run your project (like a web container plugin if your SBT project is a website). However in the same file (plugins.sbt), plugins which have nothing to do with actually running your project (such as ensime/intellij/eclipse project generators) are also typically placed in plugins.sbt
I have seen this behavior for many SBT projects which are placed into github
This ideally speaking is not the correct way to do things, ideally plugins which have nothing to do with actually running/compiling your project should be in a separate file which is put into a .gitignore
What is the idiomatic SBT way of dealing with this (I assume it should be something that consists of having 2 separate plugins.sbt files, one with actual project plugins and the other with IDE generators and whatnot)
You can install plugins globally by placing them in ~/.sbt/0.13/plugins/. .sbt or .scala files located here are loaded for every project that you have.
You can also use addSbtPlugin() in a .sbt file to add other plugins.
Check out http://www.scala-sbt.org/release/docs/Getting-Started/Using-Plugins.html