Open rockjam opened 8 years ago
I believe this is an artifact of using nailgun. The current working directory (from JVM point of view) is the working directory where the JVM was started. In our case that is the nailgun-server which is started by the cbt script. And the cbt script has as working directory the directory you call it from. So the CWD of nailgun will be the CWD you call CBT from when it starts nailgun. As a result anything run via nailgun has the current working directory of the JVM/nailgun, see the following example. It will run the following code:
import java.nio.file.Paths
object Main {
def main(args: Array[String]): Unit = {
println(s"current path is: ${Paths.get("").toAbsolutePath}")
}
}
Result:
XXPM00355799A:~ d061778$ ~/repos/other/cbt/cbt kill
Stopping nailgun
XXPM00355799A:~ d061778$ ~/repos/other/cbt/cbt nonexistingCommand #starts nailgun
Method not found: nonexistingCommand
Methods provided by CBT (but possibly overwritten)
_context apiTarget c classLoaderCache classpath compile compileClasspath
compileDependencies compileStatusFile compileTarget context
crossScalaVersions crossScalaVersionsArray defaultScalaVersion dependencies
dependenciesArray dependencyClasspath dependencyClasspathArray
dependencyTree enableConcurrency exportedClasspath exportedClasspathArray
finalBuild jarTarget lib localJars logEmptySourceDirectories logger
needsUpdate needsUpdateCompat projectDirectory projectName r recursive
rt run runClass scalaMajorVersion scalaTarget scalaVersion scalacOptions
show sourceFiles sources t target targetClasspath test
transitiveDependencies triggerLoopFiles triggerLoopFilesArray usage
zincVersion
XXPM00355799A:~ d061778$ cd tmp/prt/
XXPM00355799A:prt d061778$ ~/repos/other/cbt/cbt run
current path is: /Users/d061778
XXPM00355799A:prt d061778$
See how my code in ~/tmp/prt/
has ~
as CWD because that is where CBT started the nailgun process.
I am not sure how this can be properly resolves. Even if you could change the CWD of a running JVM, this would probably break concurrent compiles/runs even more than now (imaging you change CWD during execution...).
Maybe a forked JVM to run stuff might be an option. Or cbt run
simply has this caveat. I guess it isn't really intended to start your program anyway, and more for checking what your programm does during development.
So cbt does not use java's cwd but tracks it's own w which is passed from the client to the nailgun server. So cbt should be OK with switching cwds if that's possible. It's still hacky and error prone to other code.
We have the same problem. For environment vars and system properties. The are all global to the jvm which makes running multiple apps on the same jvm tricky. Maybe we should write a little library that provides scoped alternatives to these globals which Java / Scala code can use instead of the original globals and which default the the normal globals but persistent runtimes such as nailgun or cbt on top of nailgun can use to scope things. Doesn't help existing Java / Scala code but could at least help us to do better in new projects.
A forked jvm would be another way to solve this, but means no caching of class loaders in between which can mean multiple seconds overhead for switching. cbt direct <task>
does that. It should work as expected.
I found one nasty issue in cbt, when you get wrong current directory. I got two cbt projects.
First:
Second:
Build files are identical:
I don't have running cbt process. In first project(/Users/rockjam/projects/cbt-uber-jar) I call
cbt currentPath
:In second project(/Users/rockjam/projects/cbt-another) I call
cbt currentPath
: