From 952e1bfe02cd12b7882aae97ee0901094c7a38c7 Mon Sep 17 00:00:00 2001 From: James Iry Date: Wed, 16 Jan 2013 16:47:15 -0800 Subject: SI-4602 Make fsc absolutize source file names The fsc server was using a path supplied by the client to turn things like class path values into absolute paths. But it wasn't absolutizing the source file names supplied to the compiler which lead to SI-4602. This commit adds that absolutizing bit and cleans the logic up a bit so that the settings object isn't told a path that it already knows. A test is included that simulates changing directory by forcing two different -current-dir settings on two different compile sessions on the same server process. --- .../scala/tools/nsc/OfflineCompilerCommand.scala | 2 +- .../scala/tools/nsc/settings/FscSettings.scala | 23 ++++++--- test/files/run/t4602.scala | 57 ++++++++++++++++++++++ 3 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 test/files/run/t4602.scala diff --git a/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala b/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala index 8a3c531ff0..caf6ad14cf 100644 --- a/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala +++ b/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala @@ -33,7 +33,7 @@ class OfflineCompilerCommand(arguments: List[String], settings: FscSettings) ext } else { // Otherwise we're on the server and will use it to absolutize the paths. - settings.absolutize(currentDir.value) + settings.absolutize() } } diff --git a/src/compiler/scala/tools/nsc/settings/FscSettings.scala b/src/compiler/scala/tools/nsc/settings/FscSettings.scala index 06ebc20d3e..5c852ae07c 100644 --- a/src/compiler/scala/tools/nsc/settings/FscSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/FscSettings.scala @@ -38,14 +38,25 @@ class FscSettings(error: String => Unit) extends Settings(error) { private def holdsPath = Set[Settings#Setting]( d, dependencyfile, pluginsDir, Ygenjavap ) + + override def processArguments(arguments: List[String], processAll: Boolean): (Boolean, List[String]) = { + val (r, args) = super.processArguments(arguments, processAll) + // we need to ensure the files specified with relative locations are absolutized based on the currentDir + (r, args map {a => absolutizePath(a)}) + } + + /** + * Take an individual path and if it's not absolute turns it into an absolute path based on currentDir. + * If it's already absolute then it's left alone. + */ + private[this] def absolutizePath(p: String) = (Path(currentDir.value) resolve Path(p)).normalize.path - /** All user set settings rewritten with absolute paths. */ - def absolutize(root: Path) { - def rewrite(p: String) = (root resolve Path(p)).normalize.path + /** All user set settings rewritten with absolute paths based on currentDir */ + def absolutize() { userSetSettings foreach { - case p: OutputSetting => p.outputDirs setSingleOutput AbstractFile.getDirectory(rewrite(p.value)) - case p: PathSetting => p.value = ClassPath.map(p.value, rewrite) - case p: StringSetting => if (holdsPath(p)) p.value = rewrite(p.value) + case p: OutputSetting => p.outputDirs setSingleOutput AbstractFile.getDirectory(absolutizePath(p.value)) + case p: PathSetting => p.value = ClassPath.map(p.value, absolutizePath) + case p: StringSetting => if (holdsPath(p)) p.value = absolutizePath(p.value) case _ => () } } diff --git a/test/files/run/t4602.scala b/test/files/run/t4602.scala new file mode 100644 index 0000000000..73ba231ccf --- /dev/null +++ b/test/files/run/t4602.scala @@ -0,0 +1,57 @@ +import java.io.{File, FileOutputStream, BufferedOutputStream, FileWriter, ByteArrayOutputStream, PrintStream} +import tools.nsc.{CompileClient, CompileServer} +import java.util.concurrent.{CountDownLatch, TimeUnit} + +object Test extends App { + val startupLatch = new CountDownLatch(1) + // we have to explicitly launch our server because when the client launches a server it uses + // the "scala" shell command meaning whatever version of scala (and whatever version of libraries) + // happens to be in the path gets used + val t = new Thread(new Runnable { + def run() = { + CompileServer.execute(() => startupLatch.countDown(), Array[String]()) + } + }) + t setDaemon true + t.start() + if (!startupLatch.await(2, TimeUnit.MINUTES)) + sys error "Timeout waiting for server to start" + + val baos = new ByteArrayOutputStream() + val ps = new PrintStream(baos) + + val outdir = scala.reflect.io.Directory(sys.props("partest.output")) + + val dirNameAndPath = (1 to 2).toList map {number => + val name = s"Hello${number}" + val dir = outdir / number.toString + (dir, name, dir / s"${name}.scala") + } + + dirNameAndPath foreach {case (dir, name, path) => + dir.createDirectory() + val file = path.jfile + val out = new FileWriter(file) + try + out.write(s"object ${name}\n") + finally + out.close + } + + val success = (scala.Console withOut ps) { + dirNameAndPath foreach {case (path, name, _) => + CompileClient.process(Array("-verbose", "-current-dir", path.toString, s"${name}.scala")) + } + + CompileClient.process(Array("-shutdown")) + } + + // now make sure we got success and the correct normalized paths + val msg = baos.toString() + + assert(success, s"got a failure. Full results were: \n${msg}") + dirNameAndPath foreach {case (_, _, path) => + val expected = s"Input files after normalizing paths: ${path}" + assert(msg contains expected, s"could not find '${expected}' in output. Full results were: \n${msg}") + } +} -- cgit v1.2.3 From 3cbb0029e98304c7bd86b4854086d67f0e06b6b4 Mon Sep 17 00:00:00 2001 From: James Iry Date: Sun, 27 Jan 2013 10:16:15 -0800 Subject: SI-4602 Disable unreliable test of fsc path absolutization The included test for fsc path absolutization almost certainly has the same reliability problem as a similar test that was disabled in https://github.com/scala/scala/pull/1985 . Disabling the test until I can figure out a reliable way to test fsc in an our continuous integration environment. --- test/files/disabled/run/t4602.scala | 57 +++++++++++++++++++++++++++++++++++++ test/files/run/t4602.scala | 57 ------------------------------------- 2 files changed, 57 insertions(+), 57 deletions(-) create mode 100644 test/files/disabled/run/t4602.scala delete mode 100644 test/files/run/t4602.scala diff --git a/test/files/disabled/run/t4602.scala b/test/files/disabled/run/t4602.scala new file mode 100644 index 0000000000..73ba231ccf --- /dev/null +++ b/test/files/disabled/run/t4602.scala @@ -0,0 +1,57 @@ +import java.io.{File, FileOutputStream, BufferedOutputStream, FileWriter, ByteArrayOutputStream, PrintStream} +import tools.nsc.{CompileClient, CompileServer} +import java.util.concurrent.{CountDownLatch, TimeUnit} + +object Test extends App { + val startupLatch = new CountDownLatch(1) + // we have to explicitly launch our server because when the client launches a server it uses + // the "scala" shell command meaning whatever version of scala (and whatever version of libraries) + // happens to be in the path gets used + val t = new Thread(new Runnable { + def run() = { + CompileServer.execute(() => startupLatch.countDown(), Array[String]()) + } + }) + t setDaemon true + t.start() + if (!startupLatch.await(2, TimeUnit.MINUTES)) + sys error "Timeout waiting for server to start" + + val baos = new ByteArrayOutputStream() + val ps = new PrintStream(baos) + + val outdir = scala.reflect.io.Directory(sys.props("partest.output")) + + val dirNameAndPath = (1 to 2).toList map {number => + val name = s"Hello${number}" + val dir = outdir / number.toString + (dir, name, dir / s"${name}.scala") + } + + dirNameAndPath foreach {case (dir, name, path) => + dir.createDirectory() + val file = path.jfile + val out = new FileWriter(file) + try + out.write(s"object ${name}\n") + finally + out.close + } + + val success = (scala.Console withOut ps) { + dirNameAndPath foreach {case (path, name, _) => + CompileClient.process(Array("-verbose", "-current-dir", path.toString, s"${name}.scala")) + } + + CompileClient.process(Array("-shutdown")) + } + + // now make sure we got success and the correct normalized paths + val msg = baos.toString() + + assert(success, s"got a failure. Full results were: \n${msg}") + dirNameAndPath foreach {case (_, _, path) => + val expected = s"Input files after normalizing paths: ${path}" + assert(msg contains expected, s"could not find '${expected}' in output. Full results were: \n${msg}") + } +} diff --git a/test/files/run/t4602.scala b/test/files/run/t4602.scala deleted file mode 100644 index 73ba231ccf..0000000000 --- a/test/files/run/t4602.scala +++ /dev/null @@ -1,57 +0,0 @@ -import java.io.{File, FileOutputStream, BufferedOutputStream, FileWriter, ByteArrayOutputStream, PrintStream} -import tools.nsc.{CompileClient, CompileServer} -import java.util.concurrent.{CountDownLatch, TimeUnit} - -object Test extends App { - val startupLatch = new CountDownLatch(1) - // we have to explicitly launch our server because when the client launches a server it uses - // the "scala" shell command meaning whatever version of scala (and whatever version of libraries) - // happens to be in the path gets used - val t = new Thread(new Runnable { - def run() = { - CompileServer.execute(() => startupLatch.countDown(), Array[String]()) - } - }) - t setDaemon true - t.start() - if (!startupLatch.await(2, TimeUnit.MINUTES)) - sys error "Timeout waiting for server to start" - - val baos = new ByteArrayOutputStream() - val ps = new PrintStream(baos) - - val outdir = scala.reflect.io.Directory(sys.props("partest.output")) - - val dirNameAndPath = (1 to 2).toList map {number => - val name = s"Hello${number}" - val dir = outdir / number.toString - (dir, name, dir / s"${name}.scala") - } - - dirNameAndPath foreach {case (dir, name, path) => - dir.createDirectory() - val file = path.jfile - val out = new FileWriter(file) - try - out.write(s"object ${name}\n") - finally - out.close - } - - val success = (scala.Console withOut ps) { - dirNameAndPath foreach {case (path, name, _) => - CompileClient.process(Array("-verbose", "-current-dir", path.toString, s"${name}.scala")) - } - - CompileClient.process(Array("-shutdown")) - } - - // now make sure we got success and the correct normalized paths - val msg = baos.toString() - - assert(success, s"got a failure. Full results were: \n${msg}") - dirNameAndPath foreach {case (_, _, path) => - val expected = s"Input files after normalizing paths: ${path}" - assert(msg contains expected, s"could not find '${expected}' in output. Full results were: \n${msg}") - } -} -- cgit v1.2.3