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

Strict Deps smart mode #335

Open
natansil opened this issue Nov 10, 2017 · 11 comments
Open

Strict Deps smart mode #335

natansil opened this issue Nov 10, 2017 · 11 comments
Labels
dep-tracking Strict/unused deps, label collections related issues

Comments

@natansil
Copy link
Contributor

natansil commented Nov 10, 2017

We want to improve the current state of the dependency analyzer compiler plugin for strict deps,
Currently the plugin looks at which jars were loaded by the compiler, in order to assess if the target should be a direct dependency. This strategy is quite coarse-grained and over-approximates which targets are needed.

In order to improve the plugin, the proposal by @gkk-stripe is to utilize code from Zinc that analyzes source code which has much higher accuracy.

Plan is to use the zinc code callbacks mechanism to output the dependencies to a file and have a separate action that emits the relevant error messages to the user of missing dependencies

@gkossakowski
Copy link

Adding a bit more detail: the plan is to take Dependency.scala from zinc and copy it to rules_scala. I think this is a great way to test the idea of using zinc's dependency analysis for strict deps implementation. However, once validated, i think the best would be to refactor zinc so it can output dependencies in its protobuf format without involving the rest of incremental compilation. The cost of maintaing a fork of Depedency.scala long term will be high: it's a very tricky logic.

@ittaiz
Copy link
Member

ittaiz commented Nov 13, 2017 via email

@gkossakowski
Copy link

gkossakowski commented Nov 13, 2017 via email

@natansil
Copy link
Contributor Author

natansil commented Mar 1, 2018

Hi @gkk-stripe ,
I'm starting to take another look at this as I hope to try and get some headway here next week.
I'm sitting with @ittaiz and trying to refresh our memory and would appreciate your help.
We think that we need to have Dependency.scala accept a callback that we write which will only care about callback.binaryDependency and will emit the results to a file to be later processed by a different action.
Does that sound about right?
It seems that callback.binaryDependency happens for both external class files and external jars and we're not sure how to differentiate between the two, any thoughts?

@gkossakowski
Copy link

Yes, it sounds right about having Dependency.scala and the callback.

In what case would you see dependencies on .class files? Everything in bazel is packaged into jars, isn't it?

@natansil
Copy link
Contributor Author

natansil commented Mar 4, 2018

I think you are correct about your statement on bazel.

So in sbt it's different?

@gkossakowski
Copy link

gkossakowski commented Mar 4, 2018 via email

@natansil
Copy link
Contributor Author

natansil commented Mar 5, 2018

@gkossakowski,
I'm having some difficulty introducing the CallbackGlobal to existing setup of rules_scala plugin (as a c'tor param).

we are testing the plugin by using Global to compile sample sources.
Global in turn uses Plugin.scala code that tries to create a plugin instance by calling c'tor with Global type param and fails:

java.lang.NoSuchMethodException: third_party.plugin.src.main.io.bazel.rulesscala.dependencyanalyzer.DependencyAnalyzer.<init>(scala.tools.nsc.Global)

I've tried using toolbox to compile the sample code instead, but still get the same error:

scala.tools.reflect.ToolBoxError: reflective compilation has failed: cannot initialize the compiler due to java.lang.NoSuchMethodException: third_party.plugin.src.main.io.bazel.rulesscala.dependencyanalyzer.DependencyAnalyzer.<init>(scala.tools.nsc.Global)

Sample code here

Seems like CallbackGlobal is tightly coupled to ZincCompiler and does not work with the standard scala compiler.

am I correct?

@natansil
Copy link
Contributor Author

natansil commented Mar 6, 2018

Hi @gkk-stripe ,
For the time being I've decided to discard the callback part I've mentioned in my last comment and focus on incorporating the dependency analysis and use it synchronously.

When running rules_scala tests using the new analysis i've noticed a case where the dependency expressions is missed by the tree traversal pattern matching.

the expression is of kind: classOf[org.apache.commons.lang3.ArrayUtils]
None of the current cases (Import, Select, TypeTree) matches.

Can you please direct me to which tree type I should use to match against for this kind of expression?

@gkossakowski
Copy link

gkossakowski commented Mar 6, 2018

Removing callback is fine. In zinc/sbt it's there to isolate the two scala versions: one used to compile and run sbt and the other one used for compiling the scala project. In bazel you have only one scala version at the time so you don't need to worry about cross-classloader boundries.

Regarding matching on classOf, it's expressed as a Literal(Constant(...)) inside of the compiler.

@gkossakowski
Copy link

I just looked briefly at the zinc's source code and it seems like this is a bug in zinc. Nice catch!
It would be good to file a bug report against zinc. The fix will be very simple, though.

@liucijus liucijus added the dep-tracking Strict/unused deps, label collections related issues label Mar 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dep-tracking Strict/unused deps, label collections related issues
Projects
None yet
Development

No branches or pull requests

4 participants