What is the reason to add Local Maven Repository to sbt? - sbt

I keep seeing sbt projects with the following resolvers setting in their build definition:
resolvers += "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository"
It's also described in the official documentation of sbt in Resolvers section.
My limited knowledge of using sbt and build management tools in general lets me however consider it as a kind of anti-pattern.
The reason is that if a project declares a dependency on a library in the Local Maven Repository it somehow got downloaded there in the first place so it's available somewhere outside the local maven repository. If it is, why not using the original repository as the source?
If the dependency is not in a public repository, and is a dependency of a project, the project can use dependsOn to declare it without the additional repository in resolvers.
Please advice as I may be missing something obvious that makes the resolvers setting indispensable.

One obvious reason would be if one of your dependencies is a local project built with maven.
One scenario:
You have a project x which you build with sbt
X depends on y. Y is built with maven.
There is a bug in y which you need to fix/test, and you want to regression test x before you check it in.
You build a snapshot of y, and then you can test x before you commit the change to y.

Related

What Is The "Wharf cache default layout" In Artifactory?

From the Artifactory documentation at https://www.jfrog.com/confluence/display/JFROG/Repository+Layouts#RepositoryLayouts-BundledLayouts
Bundled Layouts
Artifactory comes out-of-the-box with a number of default, predefined
layouts requiring no additional configuration:
Maven 2/3
Ivy (default layout)
Gradle (Wharf cache default layout)
Maven 1
What is this "Wharf cache default layout" linked to Gradle?
I can access Maven Central perfectly fine with Gradle so I am confused about what this extra layout is.
Is this Gradle layout identical to a Maven 2/3 layout or is it something else?
If I choose Gradle (Wharf cache default layout) in Artifactory, can I access it with both Gradle and Maven or is there something different about it that restricts it to only Gradle use?
If it does restrict use to Gradle only, why would you use it? (since that appear to make it have fewer features than the Maven 2/3 layout)
If Maven can access it too, why would you use it? (as it seems redundant)
Is there some performance boost or some other difference that is a reason to use it?
Maven is the name for both a build tool and a repository type, while Gradle is only a build tool. Gradle can work against Maven, Gradle, and Ivy repositories.
According to JFrog docs Artifactory can be used as the Gradle build cache by simply creating a generic repository in Artifactory. The Wharf cache default layout which was introduced back in Gradle 1.0 and I believe it was meant as a way for caching local cache in a shared manner. Yet this was long ago, and though the layout does remain there, the way Gradle repos work is more adaptive to their use case:
You can now define a layout for each part; plugins resolver, libs resolver, or libs publisher. Gradle being a build tool, and not repository type, needs a private registry that can adapt, and Artifactory makes it really easy to set up.

Git submodules vs library dependency in scala microservice project

There is multi project sbt build config that contains bunch of microservices in one repo. Each microservice is self-contained. Also there is separate repository called common that contains shared model for the microservices.
What I would to know is how to handle dependencies between common project and microservices that use it.
Does git submodules approach properly fit in this case?
The one possible solution is to create submodule common in main repo and make each microservice dependent on that module:
serviceA.dependsOn(common)
serviceB.dependsOn(common)
...
Another solutions is just to add specific dependency to common to every microservice:
serviceA
.settings(
libraryDependencies ++= Dependencies.common
)
What is the pros/cons each of these approaches?
And what is the proper way to manage shared code relation in general?
Thanks is advance!

References in .NET Core (2.0)

I've tried to add a new reference to my .NET Core project.The strange thing is that I can access also the projects that are involved in my reference. For this example, i should be able to see the Repository project from service, but should not be able to access Entity Project.However , I can still access the entities object from Service.
How comes ?
References in SDK-based projects are fully transitive so - similar to many other package managers like npm or maven - you all the transitive references are available in the project to make sure the app compiles and runs cleanly, e.g. there are no unresolved references when the dependency is referenced and all assemblies are part of the build output and ready to run. (there may even be conflict resolution applied to conflicting version of assemblies resulting in the generation of binding redirects.)
In previous versions, you would need to install NuGet packages or add additional project references to other projects as well to not get build errors or type load exceptions.
Currently there is no perfect workaround if you want your project to do all the things needed to be able to run and resolve conflicts correctly but not pass transitive references to the compiler.
If you only need a dependency to build a project, but not to run it, you can mark a package or project reference as PrivateAssets="All" (add as attribute to the reference in the .csproj file).
If you want to enforce API usage - e.g. for layered APIs, consider writing a roslyn analyzer that will emit warnings if you reference APIs from places you don't want to. this may be suitable for large projects where tooling is needed to maintain the desired architecture.

Sbt resource generation in runtime

I am trying to achieve what a resourceGenerator in Runtime would do: create a resource that is available on the classpath during runtime, however that would not be packaged under the main configuration.
In my specific case, I am trying to create an sbt plugin that facilitates dealing with JNI native libraries. The above mentioned resource would be a "fat" jar containing a shared library, thus it is not required for compilation but only during runtime.
My goal in the end is to publish the standard jar (in the Compile configuration) and publish the fat jar as an extra artifact (in the Runtime configuration). However, during local testing, I would like the shared libraries to be available on the classpath when simply calling run from sbt.
I tried implementing a resourceGenerator in Runtime, however with no success. An alternative approach I could imagine would be to modify runtime:exportedProducts or alter runtime:managedClasspath directly, however I first wanted to know if there is already a way to include resources only in the runtime configuration?

TeamCity working directory of dependency?

If you have a project that builds one project before building the next, but the next needs to know the 'path' of the first build, is it possible to get this?
For example:
Project A has Build Configuration A and Build Configuration B.
Build Configuration B has a dependency on Build Configuration A. From without the Build Configuration B it will need access to the path of Build Configuration A. Is there are a way to obtain this?
Most simple approach would be to define a custom checkout directory in the A and use the same hard-coded value in B.
If you use TeamCity snapshot or artifact dependencies, you can use %dep.btXXX.teamcity.build.checkoutDir% to get checkout directory of the dependency build. However, this will not work in 6.5.0-6.5.5 TeamCity versions, see details and workaround in the issue TW-18715.
However, you should really avoid accessing checkout directory of one build from another. If you need sources of A, you can checkout them in B; if you output of the A's build, then publishing the output as build's artifacts and then using TeamCity artifact dependencies is the way to go. In both cases additionally using TeamCity snapshot dependencies will ensure both builds use the same sources snapshot which is probably what you need.
If you have one agent, and only ever one agent then you could try and use the path from a previous build.
I wouldn't recommend doing this however because if you had two agents, or scaled up in the future to two agents, then it is possible your projects will be built on different agents; this would mean your dependency working directory won't be on the same machine, or it will be outdated as the latest was built elsewhere.
I assume you're after the path of the first build to get its output?
If so, the method we use to share dependencies between projects is to checkin the output from each project into our source control, then every project that requires the output simply has to check them out.

Resources