Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document local rules for sbt builds #1173

Merged
merged 2 commits into from
Jul 2, 2020
Merged

Conversation

bjaglin
Copy link
Collaborator

@bjaglin bjaglin commented Jun 21, 2020

Merge only when scalacenter/sbt-scalafix#121 is released

This is the public documentation for scalacenter/sbt-scalafix#100. It's a bit late as I found scalacenter/sbt-scalafix#121 to be key for any non-2.12 project to use it. Since the original PR was not thoroughly reviewed/advertized, I guess it would be nice to iterate on the implementation itself (that we have been using internally with ScalafixTestkitPlugin on a multi-project build), as documentation highlights possible improvements & shortcomings.

I decided to create a separate section as a first step, since integrating it in the current tutorial was quite demanding. Depending on the main target for Scalafix rules development (lib or application authors?), this could become the main tutorial.

@bjaglin bjaglin force-pushed the local-rules branch 2 times, most recently from 22c30a2 to 7f89d37 Compare June 21, 2020 22:59
Comment on lines +163 to +205
+ .dependsOn(`scalafix-rules` % ScalafixConfig)
+lazy val `scalafix-input` = (project in file("scalafix/input"))
+ .disablePlugins(ScalafixPlugin)
+lazy val `scalafix-output` = (project in file("scalafix/output"))
+ .disablePlugins(ScalafixPlugin)
+lazy val `scalafix-rules` = (project in file("scalafix/rules"))
+ .disablePlugins(ScalafixPlugin)
+ .settings(
+ libraryDependencies +=
+ "ch.epfl.scala" %%
+ "scalafix-core" %
+ _root_.scalafix.sbt.BuildInfo.scalafixVersion
+ )
+lazy val `scalafix-tests` = (project in file("scalafix/tests"))
+ .settings(
+ libraryDependencies +=
+ "ch.epfl.scala" %
+ "scalafix-testkit" %
+ _root_.scalafix.sbt.BuildInfo.scalafixVersion %
+ Test cross CrossVersion.full,
+ scalafixTestkitOutputSourceDirectories :=
+ sourceDirectories.in(`scalafix-output`, Compile).value,
+ scalafixTestkitInputSourceDirectories :=
+ sourceDirectories.in(`scalafix-input`, Compile).value,
+ scalafixTestkitInputClasspath :=
+ fullClasspath.in(`scalafix-input`, Compile).value,
+ scalafixTestkitInputScalacOptions :=
+ scalacOptions.in(`scalafix-input`, Compile).value,
+ scalafixTestkitInputScalaVersion :=
+ scalaVersion.in(`scalafix-input`, Compile).value
+ )
+ .dependsOn(`scalafix-input`, `scalafix-rules`)
+ .enablePlugins(ScalafixTestkitPlugin)
Copy link
Collaborator Author

@bjaglin bjaglin Jun 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff is nice but hard to copy/paste, so I wonder if it's not better to leave it raw when 95% of the lines are additions, and the snippet is big

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could have the final file here (instead of the diff).
By the way, I like your comments/questions you add on your own PR, I find this quite useful and helpful for the review.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, I like your comments/questions you add on your own PR, I find this quite useful and helpful for the review.

Thanks! However, sometimes they give context that should be captured in the git history as a source/commit comment instead, so I am trying to always question them since they can be an anti-pattern for long-term maintainability.

@bjaglin bjaglin marked this pull request as ready for review June 21, 2020 23:14
@bjaglin bjaglin requested review from olafurpg and mlachkar June 21, 2020 23:14
## Single-project sbt build

If you do not have any sub-project in your build, custom rules should be
defined under the Scalafix Ivy configuration sources directory, which by
Copy link
Collaborator Author

@bjaglin bjaglin Jun 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we found this to be a problem with IntelliJ's built-in compiler (for any integration, not just single-project), as unknown Ivy configurations fallback to Compile without any proper eviction, potentially resulting in different versions of the same artifact in the classpath. I'll follow up in another PR with some notes & recommendations when that's a problem.

Comment on lines +118 to +122
+ libraryDependencies +=
+ "ch.epfl.scala" %%
+ "scalafix-core" %
+ _root_.scalafix.sbt.BuildInfo.scalafixVersion %
+ ScalafixConfig
Copy link
Collaborator Author

@bjaglin bjaglin Jun 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could make this automatic, as long as we update https://github.com/scalacenter/sbt-scalafix/blob/60199fdae7bb9c56b9d09969b0889923a6b39108/src/main/scala/scalafix/sbt/ScalafixPlugin.scala#L201-L202 to avoid always invalidating the default tool classpath. Thoughts?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get it. It's normal to add scalafix-core to library dependencies?

Copy link
Collaborator Author

@bjaglin bjaglin Jun 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be OK to add scalafix-core to library dependencies in the ScalafixConfig Ivy configuration, since anything there is meant to be rules, which require types from there.

Another downside is that it would potentially expose classpath collisions in IntelliJ mentioned in https://github.com/scalacenter/scalafix/pull/1173/files#r443266186 to all plugin users, whether or not they use local rules.

+│ │   ├── Test1.scala
+│ │   ├── Test2.scala
+│ │   └── ...
+│ ├── rules/src
Copy link
Collaborator Author

@bjaglin bjaglin Jun 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be

Suggested change
+│ ├── rules/src
+│ ├── rules/scalafix

to potentially benefit from automatic addition of scalafix-core, but it would drift from the current template and would make the sbt dependsOn more awkward (scalafix->scalafix), so I decided to stick to it.

Copy link
Collaborator

@mlachkar mlachkar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for the last build.sbt, we could have the entire file, but it's optional.
Otherwise, I find this documentation clear and exhaustive.
Thanks

.

Comment on lines +163 to +205
+ .dependsOn(`scalafix-rules` % ScalafixConfig)
+lazy val `scalafix-input` = (project in file("scalafix/input"))
+ .disablePlugins(ScalafixPlugin)
+lazy val `scalafix-output` = (project in file("scalafix/output"))
+ .disablePlugins(ScalafixPlugin)
+lazy val `scalafix-rules` = (project in file("scalafix/rules"))
+ .disablePlugins(ScalafixPlugin)
+ .settings(
+ libraryDependencies +=
+ "ch.epfl.scala" %%
+ "scalafix-core" %
+ _root_.scalafix.sbt.BuildInfo.scalafixVersion
+ )
+lazy val `scalafix-tests` = (project in file("scalafix/tests"))
+ .settings(
+ libraryDependencies +=
+ "ch.epfl.scala" %
+ "scalafix-testkit" %
+ _root_.scalafix.sbt.BuildInfo.scalafixVersion %
+ Test cross CrossVersion.full,
+ scalafixTestkitOutputSourceDirectories :=
+ sourceDirectories.in(`scalafix-output`, Compile).value,
+ scalafixTestkitInputSourceDirectories :=
+ sourceDirectories.in(`scalafix-input`, Compile).value,
+ scalafixTestkitInputClasspath :=
+ fullClasspath.in(`scalafix-input`, Compile).value,
+ scalafixTestkitInputScalacOptions :=
+ scalacOptions.in(`scalafix-input`, Compile).value,
+ scalafixTestkitInputScalaVersion :=
+ scalaVersion.in(`scalafix-input`, Compile).value
+ )
+ .dependsOn(`scalafix-input`, `scalafix-rules`)
+ .enablePlugins(ScalafixTestkitPlugin)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could have the final file here (instead of the diff).
By the way, I like your comments/questions you add on your own PR, I find this quite useful and helpful for the review.

Comment on lines +118 to +122
+ libraryDependencies +=
+ "ch.epfl.scala" %%
+ "scalafix-core" %
+ _root_.scalafix.sbt.BuildInfo.scalafixVersion %
+ ScalafixConfig
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get it. It's normal to add scalafix-core to library dependencies?

@bjaglin
Copy link
Collaborator Author

bjaglin commented Jun 24, 2020

For information, I am going to write an article on my company's blog https://medium.com/teads-engineering to explain in details our usage Scalafix and what lead to this feature upstream (and the others I contributed, but I feel like this one is a bit more special). Maybe this is something we can integrate also, either here or in an upcoming 1.0 release post?

@bjaglin bjaglin merged commit 05c2ad1 into scalacenter:master Jul 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants