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

Default working directory for forked vs non-forked runs/tests are different #3892

Closed
er1c opened this issue Jan 17, 2018 · 12 comments
Closed

Default working directory for forked vs non-forked runs/tests are different #3892

er1c opened this issue Jan 17, 2018 · 12 comments

Comments

@er1c
Copy link
Contributor

@er1c er1c commented Jan 17, 2018

Issue

The default working directory changes when fork := true, is specified.

Example command: sbt "project subproject" "runMain foo.foo.App"

Non fork:

Uses the top-level project directory as the working directory.

With fork in Test := true,:

Uses the subproject directory as the working directory.

Expectation

I would expect the default behavior to be consistent.

sbt version: 1.1.0


Original ticket for referencing conversation thread

I have a multi-project sbt file that I recently added the fork in (Compile, run) := true option on.

One of the first issues that popped up was the process wouldn't read a local file "localdir/localfiles.txt" - basically the working directory wasn't set to the project directory. This was easily fixed by manually specifying a working directory such as baseDirectory in (Compile, run) := file(".")

I would expect this to be a default behavior, rather than needing to be explicit. IntelliJ recently (in the last year or two?) also added a "Use project home as compile server working directory" which is the same/similar behavior I would expect.

an sbt "project subproject" "runMain foo.foo.App" will also use the top-level directory as the working directory

@dwijnand
Copy link
Member

@dwijnand dwijnand commented Jan 18, 2018

I'm not 100% certain if that should be the default, but as I was recently looking at how forking does things I think the change would have to be to change

https://github.com/sbt/sbt/blob/v1.1.0/main/src/main/scala/sbt/Defaults.scala#L752

to workingDirectory = Some((baseDirectory in ThisBuild).value)

@er1c
Copy link
Contributor Author

@er1c er1c commented Jan 18, 2018

If I understand how the code currently works, the subdirectory project is being set to the working directory? I can, of course, make an argument for that being the more "correct" behavior. But the behavior still "diverges" from the above example of running sbt "project subproject" "runMain foo.foo.App" and the top-level project directory will effectively be the working directory for a non-forked runMain

@dwijnand
Copy link
Member

@dwijnand dwijnand commented Jan 18, 2018

Yes I see what you mean. I'd have to look into the history of forking to see if it's possible to understand why this default was chosen.

Thanks for the analysis.

@mpollmeier
Copy link
Contributor

@mpollmeier mpollmeier commented Feb 23, 2019

Thank you, this workaround helped me fix another long-lasting pain: in multi-projects, tests would run in either sbt or intellij. It works in both if your subproject/build.sbt specifies

Test/baseDirectory := (ThisBuild/Test/run/baseDirectory).value

Slightly more context: http://www.michaelpollmeier.com/2019/02/20/sbt-subprojects-tests-intellij

@matanster
Copy link

@matanster matanster commented Dec 29, 2019

Just to exemplify the possible workaround in yet another way ― in the subproject:

.settings(baseDirectory in run := (baseDirectory in LocalRootProject).value)

This will override the runtime working directory (such as, when you run a main).

@matanster
Copy link

@matanster matanster commented Dec 29, 2019

Just curious whether this behavior ever changed in newer versions. I think that parity between interactive sbt sessions and using the sbt command for running tests or mains ― is a major plus. Especially if this kind of harmony also extends to IntelliJ.

@er1c
Copy link
Contributor Author

@er1c er1c commented Dec 29, 2019

@matanster I think SBT maybe inconsistent between forked and non-forked runs, but I'm not sure if this behavior changed at all.

There is a semi-related bloop issue here: scalacenter/bloop#1098

I don't think it would be a desirable to port the whole task/config/project axis scoping rules from sbt to bloop.

This ticket should probably be renamed/updated or something to instead just be "Make working directory consistent between forked and non-forked runs". Bloop wants to standardize on the sub-project as the working directory, so SBT probably should standardize on that too (e.g. make the change @dwijnand suggested) which still allows for the baseDirectory override option in a build.sbt/

@matanster
Copy link

@matanster matanster commented Dec 29, 2019

May I suggest:

Make sub-project working directory consistent regardless of fork / no fork and interactive sbt v.s. sbt as a command line, while having IntelliJ integration overall consistent with such change

But I wonder if there are additional similar aspects in which the variance exists along these two axes ... because it makes sense to maintain parallels in the design.

@matanster
Copy link

@matanster matanster commented Dec 29, 2019

What are the relationships between sbt and sbt-bloop?! do you also have to worry about sbt-bloop compatibility here?

@er1c
Copy link
Contributor Author

@er1c er1c commented Dec 29, 2019

What are the relationships between sbt and sbt-bloop?! do you also have to worry about sbt-bloop compatibility here?

Bloop can read build.sbt files and create bloop-configs so that it can support most sbt projects.

The previous example/link is that sbt and bloop diverge supporting the "task/config/project axis scoping rules in sbt" for specifying the working directory. However, bloop is more consistent, in that it always uses the subproject for the working directory. The default sbt working directory is different whether you specify fork := true or not.

build.sbt Examples

"Native" SBT command working directory override

baseDirectory in (Test) := file("./test"),
vs
baseDirectory in (Compile, run) := file("."),

Bloop (in the build.sbt) working directory override

javaOptions += s"-Duser.dir=${baseDirectory.in(ThisBuild).value}"

Having a different test vs run is not supported by bloop (I think) /cc @jvican

@er1c er1c changed the title SBT should default the current project directory as the working directory of forked runs Default working directory for forked vs non-forked runs/tests are different Dec 29, 2019
@eed3si9n
Copy link
Member

@eed3si9n eed3si9n commented Dec 29, 2019

The fork vs non-fork working directory discussion seems to be a duplicate of #1032

@er1c
Copy link
Contributor Author

@er1c er1c commented Dec 30, 2019

Closing, duplicate of: #1032

@er1c er1c closed this Dec 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants