Cross-building a project dependent on different versions of specific library - scala

I need to build different versions of a project that depend on different versions of specific libraries. These library versions are compatible on a source level. So I want to build com.company:myproject-mylib-1.0_2.12:1.0.0 that depends on com.company:mylib:1.0 and com.company:myproject-mylib-2.0_2.12:1.0.0 that depends on com.company:mylib:2.0. One of the ways I can think of is using environment variable to store library version, is there a more elegant way?

Well, one of these you have to set explicitly, then the other one can be calculated:
libraryDependencies += "com.company" % "mylib" % (if (name.value.endsWith("1.0")) "1.0" else "2.0")`
Then during build you could do something like:
sbt> ;compile;publish // <- e.g. for v 1.0
sbt> set name := "myproject-mylib-2.0"
sbt> ;compile;publish // <- e.g. for v 2.0
If you want it more principled you could define a new key:
val isNew = settingKey[Boolean]("Are we building a new version of a library")
Global / isNew := false
name := if (isNew.value) "myproject-mylib-2.0" else "myproject-mylib-1.0"
libraryDependencies += "com.company" % "mylib" % (if (isNew.value) "2.0" else "1.0")`
which you would build like
sbt> ;compile;publish // <- for v 1.0
sbt> set isNew := true
sbt> ;compile;publish // <- for v 2.0
or from command line
sbt compile publish "set isNew := true" compile publish

Related

How to create a Powerset of MSetList?

I am creating an MSetList P with elements of type String, and I would like to obtain the Powerset of P. I am not being able to figure it out.
Code below.
Thanks for your help :-)
Require Import
Coq.MSets.MSetList
Coq.Strings.String
Coq.Structures.OrdersEx.
Module set := Make OrdersEx.String_as_OT.
Definition P := set.add "A"%string (set.add "B"%string (set.add "C"%string (set.add "D"%string set.empty))).
Compute P.
Answer was provided on the Coq Discourse Forum by Yves Bertot
The construction of set shows that you are using the Make function
with a module as argument. If you type Print Make., you see that
this is a functor taking a module of type OrderedType as argument,
and it produces a module with many fields, among which t, eq,
eq_equiv, lt, lt_strorder, lt_compat, compare,
compare_spec, and eq_dec. If you type Print OrderedType., you
see that these field are the ones required to make an OrderedType.
So Make constructs all the fields that would be required to call Make
again, thus producing the powerset.
You can just type :
Module pset := Make set.
and you will simply obtain a structure of sets, whose elements are in
set.t. The following example was tested with coq 8.15.
Require Import
Coq.MSets.MSetList
Coq.Strings.String
Coq.Structures.OrdersEx.
Module set := Make OrdersEx.String_as_OT.
Module pset := Make set.
Definition set1 := set.add "A"%string set.empty.
Definition set2 := set.add "B"%string set.empty.
Definition set3 := set.add "C"%string set1.
Definition pset1 := pset.add set1 (pset.add set2 pset.empty).
Compute pset.mem set3 pset1.
Compute pset.mem set2 pset1.

What happened to CrossVersion.fullMapped in sbt 1.x (or specifically 1.2.8)?

In fact, I don't see any of the xMapped functions in the new release of the librarymanagement repository.
I get this error:
build.sbt:84: error: value fullMapped is not a member of object sbt.librarymanagement.CrossVersion
"org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.fullMapped{
for the following usage:
,addCompilerPlugin( // For circe generic:
"org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.fullMapped{
_ => scalaVersionSelect
}
)
CrossVersion.fullMapped wasn't kept in its sbt 0.13 form because sbt 1.x wanted to be able to serialize its key types (and CrossVersion is a transitive part of that object graph).
It was replaced by CrossVersion.fullWith, which instead of taking a general String => String function takes a String prefix and a String suffix to prepend/append to the Scala binary version.
But given you're discarding the input to use scalaVersionSelect then you don't even need CrossVersion.fullWith and can just use CrossVersion.constant, as in:
addCompilerPlugin(
"org.scalamacros" % "paradise" % "2.1.1"
cross CrossVersion.constant(scalaVersionSelect)
)

SBT: dynamically detect building platform

I am trying dynamically change reference to the jars dependency I am using in my project, depending on the platform (Windows or Linux)
So, its a very trivial scenario,
How can I implement this simple check in the build.sbt ?
Potential approach is to pattern match on System.getProperty("os.name") within a custom defined setting like so
val configureDependencyByPlatform = settingKey[ModuleID]("Dynamically change reference to the jars dependency depending on the platform")
configureDependencyByPlatform := {
System.getProperty("os.name").toLowerCase match {
case mac if mac.contains("mac") => "org.example" %% "somelib-mac" % "1.0.0"
case win if win.contains("win") => "org.example" %% "somelib-win" % "1.0.0"
case linux if linux.contains("linux") => "org.example" %% "somelib-linux" % "1.0.0"
case osName => throw new RuntimeException(s"Unknown operating system $osName")
}
}
and then add the evaluated setting to libraryDependencies as follows
libraryDependencies ++= Seq(
configureDependencyByPlatform.value,
"org.scalatest" %% "scalatest" % "3.0.5",
...
)

SBT Compiler crash using Scala-Breeze

I am writing a code to perform kernel K-Means (aka https://en.wikipedia.org/wiki/K-means_clustering, but with a trick). I need to generate data, and as a first simple generator I tried to implement a Gaussian Mixture Model. Here are my code:
package p02kmeans
import breeze.linalg._
import breeze.stats.distributions._
/**
* First data generation is simple, gaussian mixture model.
*/
object Data {
class GaussianClassParam (
val mean: Double,
val sd: Double)
/**
* #param proportion marginal probability for each label
* #param param param[j][k] returns the GaussianClassParam for the k class of the j variable
* #param nObs number of observations to be generated
* #result DenseMatrix_ij where i is the observation index and j is the variable number
*/
def gaussianMixture(
proportion: DenseVector[Double],
param: Vector[Vector[GaussianClassParam]],
nObs: Int)
: DenseMatrix[Double] = {
val nVar = param.size
val multiSampler = Multinomial(proportion) // sampler for the latent class
val varSamplerVec = param.map(v => v.map(c => Gaussian(c.mean, c.sd)))
val zi = DenseVector.fill[Int](nObs)(multiSampler.sample)
val data = DenseMatrix.tabulate[Double](nObs, nVar)((i, j) => varSamplerVec(j)(zi(i)).sample)
return data
}
}
When I try to compile my code (I use Scala-Ide and sbt eclipse on Windows 10) I get 2 errors:
Error in Scala compiler: assertion failed: List(method apply$mcI$sp, method apply$mcI$sp)
SBT builder crashed while compiling. The error message is 'assertion failed: List(method apply$mcI$sp, method apply$mcI$sp)'. Check Error Log for details.
The error is triggered by the line:
val data = DenseMatrix.tabulate[Double](nObs, nVar)((i, j) => varSamplerVec(j)(zi(i)).sample)
And disappear with:
val data = DenseMatrix.tabulate[Double](nObs, nVar)((i, j) => 12.0)
Could you help me debug this ?
My sbt configuration:
name := "Sernel"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies ++= Seq(
"org.scalanlp" %% "breeze" % "0.13.1",
"org.scalanlp" %% "breeze-natives" % "0.13.1",
"org.scalanlp" %% "breeze-viz" % "0.13.1"
)
I have the same errors on my OSX setup.
If you want to test the whole package (as, if you want to reproduce the error), the code is available on Github: https://github.com/vkubicki/sernel, and I am available to provide directions :).
It seems like it's a compiler bug (I suppose in scala macroses as Breeze is using those). You could try to perform total clean in the project (maybe even including .ivy2 folder - this could be a difference between your MacOS and Windows setup) and also update your scala to 2.11.11 (or maybe even 2.12.x)
However, similar issue with Scala 2.11.6 (and something tells me it's inherited in subsequent versions of Scala) wasn't fixed: https://issues.scala-lang.org/browse/SI-9284
So probably, you'll have to repeatedly perform cleaning sometimes or maybe try some other NumPy analogs like: scalala, Nd4j/Ndjs.
It could also help to try another IDE (IDEA/Atom) or try to use "bare" SBT as Eclipse is probably interfering by calling Scala's compiler front-end.

How do I use the contents of an array as a variable name?

Currently I store the contents of an array into a variable, then set that variable up using two % and store a value. My current code looks like this:
Test := {asdf: "blah"}
Temp := Test["asdf"]
%Temp% := "boo"
; above line is be the same as blah := "boo", but blah came from a variable
msgbox %blah% ; outputs "boo"
I don't like having to use the Temp variable like this.
The following compiles but blah stays blank:
(Test["asdf"]) := "boo"
%Test%["asdf"] := "boo"
The following gives me a compile error:
%(Test["asdf"])% := "boo"
I have a vague idea that it should be possible but I just can't find the syntax for it. How do I directly use the array instead of having to put it in a temp variable?
Just figured it out.
The problem here is creating variables using dynamic data may cause invalid variable names to be created. All sorts of ways to screw up here (spaces, UTF-8 code, etc).
One safer way is to use Associative Arrays:
Output := Object()
Test := {asdf: "blah"}
Output[(Test["asdf"])] := "boo"
msgbox % Output["blah"]
There are less restrictions on keys than variable names.
globalWrapper(NameOfTheGlobalVar, LocalVar) {
global
%NameOfTheGlobalVar% := LocalVar
}
Test := {asdf: "blah"}
globalWrapper(Test["asdf"], "boo")
msgbox %blah% ; outputs "boo"