WIP - adding example to cross-rewrite#466
WIP - adding example to cross-rewrite#466ShaneDelmore wants to merge 13 commits intocvogt:masterfrom
Conversation
| class Build(val context: Context) extends BaseBuild{ outer => | ||
| override def defaultScalaVersion = "2.11.8" | ||
| class Build(val context: Context) extends BaseBuild { outer => | ||
| override def defaultScalaVersion = "2.12.1" |
There was a problem hiding this comment.
I changed the default because I thought people might like to write code in the latest version and backwards compile.
| override def test: Dependency = { | ||
| new BasicBuild(context) with ScalaTest { | ||
| override def dependencies = outer +: super.dependencies | ||
| override def defaultScalaVersion = "2.12.1" |
There was a problem hiding this comment.
Is this correct that I need to override version for test build (why would I ever want to test on a different version?)
Or should my test be extending my main project somehow to have access to the code in it?
There was a problem hiding this comment.
you overwrote defautScalaVersion is class Build, but here you are instantiating class BasicBuild. That's fine, but it doesn't magically pick up on what you overwrote in Build. So if you want this as 2.12.1 you need to provide that info here somehow.
| val fromTo = lib.autoRelative(outer.sources).collect { | ||
| case (location, relative) if location.isFile => | ||
| location -> projectDirectory / "src" / relative | ||
| } |
There was a problem hiding this comment.
scalafmt must have changed all of this slightly. Would you be interested in a pr adding a .scalafmt config to the project?
There was a problem hiding this comment.
Not completely warmed up to scalafmt yet. I played around with it a bit, but it currently does not allow me to produce code that I find as readable as scalariform. So for now I have settled on Scalariform for CBT and there is a preconfigured plugins.scalariform plugin you can add as a dependency to your BuildBuild, allowing you to mix in Scalariform into your build, which adds a preconfigured task scalariform, which by default is not run on compile, but can be easily added (in which case one has to call scalariform.apply there, because it is lazy).
There was a problem hiding this comment.
(had a longer discussion with olaf around the limitations of scalafmt for my personal preferred style a few weeks ago)
There was a problem hiding this comment.
No problem. I don't mind using scalariform but I may take a shot at making a .scalafmt.conf that matches your scalariform preferences just to see if I can.
There was a problem hiding this comment.
Scalafmt does not have any settings which mimic scalariform, they're very different formatters.
| object Main { | ||
| def main(args: Array[String]): Unit = { | ||
| //For 2.11.8 rewrite to case match | ||
| Disjunction.intOrString.map(println) |
There was a problem hiding this comment.
I could either rewrite this to a case statement for scalaz 2.11.8 (I don't believe they have an either enrichment for map) or I could change the type to /. Either one would require the semantic mirror which I am not clear is actually available based on @olafurpg comment about ExplicitImplicit being available. I will experiment more once I get tests to pass.
There was a problem hiding this comment.
I think a semantic mirror is available, just not the Scalafix Mirror, which ExplicitImplicit is currently coded against.
plugins/scalatest/ScalaTest.scala
Outdated
| ExitCode.Success | ||
| } | ||
| override def dependencies = super.dependencies ++ Resolver( mavenCentral ).bind( ScalaDependency("org.scalatest","scalatest","2.2.4") ) | ||
| override def dependencies = super.dependencies ++ Resolver( mavenCentral ).bind( ScalaDependency("org.scalatest","scalatest","3.0.1") ) |
There was a problem hiding this comment.
There is no 2.x version of Scalatest for scala 2.12 so I bumped to scalatest 3.0.1.
plugins/scalatest/build/build.scala
Outdated
| :+ context.cbtDependency | ||
| ) ++ Resolver( mavenCentral ).bind( | ||
| ScalaDependency("org.scalatest","scalatest","2.2.4") | ||
| ScalaDependency("org.scalatest","scalatest","3.0.1") |
There was a problem hiding this comment.
I haven't looked into this yet but don't like that there are these duplicated strings in multiple files. Maybe I need to create a Dependencies.scala file to share them.
| val fromTo = lib.autoRelative(outer.sources).collect { | ||
| case (location, relative) if location.isFile => | ||
| location -> projectDirectory / "src" / relative | ||
| } |
There was a problem hiding this comment.
(had a longer discussion with olaf around the limitations of scalafmt for my personal preferred style a few weeks ago)
| object Main { | ||
| def main(args: Array[String]): Unit = { | ||
| //For 2.11.8 rewrite to case match | ||
| Disjunction.intOrString.map(println) |
There was a problem hiding this comment.
I think a semantic mirror is available, just not the Scalafix Mirror, which ExplicitImplicit is currently coded against.
| override def defaultScalaVersion = "2.12.1" | ||
|
|
||
| override def test: Dependency = { | ||
| new BasicBuild(context) with ScalaTest { |
There was a problem hiding this comment.
you need to add override def projectDirectory = outer.projectDirectory / "test" here, so it can find your source files. Otherwise it only looks in context.workingDirectory and context.workingDirectory / "src". context.workingDirectory is the default for BaseBuild.projectDirectory and the directory one up from the build.scala file. I'd suggest you look start looking into the source code a little bit. CBT makes that quite easy :).
|
the tests check for the existence of a cats AND scalaz crossbuilds, which is why this still fails ;). |
|
Ah, that makes sense. That should be easy enough for me to resolve Saturday. |
| Replace(Symbol("_root_.Disjunction."), q"Test"), | ||
| Rename(q"intOrString", q"xor"), | ||
| //And this works again. What is different about import rewrites vs the others? | ||
| RemoveGlobalImport(importer"scala.concurrent.Future") |
There was a problem hiding this comment.
I am not sure if I am missing something or if there is a bug in scalafix, but import releated rewrites work and others do not. I can't tell what the difference is yet. I looked back through scalafix code and these are all instances of TreePatch. Once the patching works this should be as simple as adding scalaz./, replacing Either with / and Right with /-
| //None of these work, why? | ||
| Replace(Symbol("_root_.scala.util.Either."), q"\/"), | ||
| Replace(Symbol("_root_.Disjunction."), q"Test"), | ||
| Rename(q"intOrString", q"xor"), |
There was a problem hiding this comment.
Rename should probably be called RenameThisInstance (or similar) because it's reference based, I opened scalacenter/scalafix#109 to track that change. To replace call-sites of a specific definition you want to use Replace, which is symbol based.
| //This works | ||
| AddGlobalImport(importer"scalaz._"), | ||
| //None of these work, why? | ||
| Replace(Symbol("_root_.scala.util.Either."), q"\/"), |
There was a problem hiding this comment.
Have you tried Mirror.database.toString to double check that this symbol matches the symbol you want to rewrite? Otherwise, please open an issue in scalafix and I can take a look at it next week.
There was a problem hiding this comment.
The type of scala.util.Either is actually scala.package.Either. Printing out the mirror.database helped, thanks @olafurpg
plugins/scalafix/Scalafix.scala
Outdated
| println("printing mirror database messages") | ||
| println(ctx.mirror.database) | ||
| println("end printing") | ||
| assert(ctx.mirror.database.toString.trim != "", "I do not believe the database should be empty here") |
There was a problem hiding this comment.
@olafurpg The semantic db appears to be empty here even though sources is not. Do you think the semantic db is being constructed incorrectly, or that I should open a scalameta issue on this?
There was a problem hiding this comment.
The project source files need to be compiled with the scalahost compiler plugin for the database to be built, so the Scalameta plugin needs to be mixed in the root build. The mirror is composed of a classpath (pointing to at least one directory containing semanticdb files) and a sourcepath (pointing to scala source files). In this case, the classpath does not contain any semanticdb files, maybe the Mirror constructor should fail in that case.
There was a problem hiding this comment.
I do believe fail fast would be better here, but this should be enough to advice to get me back on track. 👍
| ) | ||
| } | ||
|
|
||
| def context(file: File): ( RewriteCtx[Mirror], RewriteCtx[ScalafixMirror] ) = ( |
There was a problem hiding this comment.
RewriteCtx[ScalafixMirror] is not necessary here, ScalafixMirror will go away in favor of Mirror.
| import scalafix.util.TokenPatch._ | ||
|
|
||
| class Build(val context: Context) extends BaseBuild{ outer => | ||
| class Build(val context: Context) extends BaseBuild { outer => |
There was a problem hiding this comment.
There's missing a with Scalameta here to inject the scalahost compiler plugin, which generates semanticdb files under target/.
There was a problem hiding this comment.
Doh! Thanks for catching that.
| val fromTo = lib.autoRelative(outer.sources).collect { | ||
| case (location, relative) if location.isFile => | ||
| location -> projectDirectory / "src" / relative | ||
| } |
There was a problem hiding this comment.
Scalafmt does not have any settings which mimic scalariform, they're very different formatters.
plugins/scalafix/Scalafix.scala
Outdated
| println("printing mirror database messages") | ||
| println(ctx.mirror.database) | ||
| println("end printing") | ||
| assert(ctx.mirror.database.toString.trim != "", "I do not believe the database should be empty here") |
There was a problem hiding this comment.
The project source files need to be compiled with the scalahost compiler plugin for the database to be built, so the Scalameta plugin needs to be mixed in the root build. The mirror is composed of a classpath (pointing to at least one directory containing semanticdb files) and a sourcepath (pointing to scala source files). In this case, the classpath does not contain any semanticdb files, maybe the Mirror constructor should fail in that case.
| //Over time I would hope to build up a community libraryof rewrites so many of the transforms would be pulled from | ||
| //a library instead of declared in the build | ||
| } | ||
|
|
There was a problem hiding this comment.
Ignore everything below here, I didn't mean to commit it.
would contain wrong classLoader when switching scalaVersions)
otherwise those libraries wouldn’t find the classes we might have to reconsider this eventually
running something, not the one that may end up in a cache
rather than the more obscure context object
(there is still a test failure, where the code hasn’t been rewritten properly, but that’s ok. One step at a time.)
|
I forgot all about this PR. Will try to take a look at it in a few days and see if I can figure out why tests fail. |
This is not even close to ready, just making a pr to see if I am on the right track.