diff --git a/scalafix-cli/src/main/scala/scalafix/cli/CliRunner.scala b/scalafix-cli/src/main/scala/scalafix/cli/CliRunner.scala index 9314f946c..43c112faf 100644 --- a/scalafix-cli/src/main/scala/scalafix/cli/CliRunner.scala +++ b/scalafix-cli/src/main/scala/scalafix/cli/CliRunner.scala @@ -141,6 +141,7 @@ sealed abstract case class CliRunner( case WriteMode.WriteFile => val outFile = replacePath(input.original.path) if (isUpToDate(input)) { + Files.createDirectories(outFile.toNIO) Files.write(outFile.toNIO, fixed.getBytes(input.original.charset)) ExitStatus.Ok } else { @@ -449,13 +450,22 @@ object CliRunner { } val resolvedPathReplace: Configured[AbsolutePath => AbsolutePath] = try { - val outFromPattern = Pattern.compile(outFrom.getOrElse("")) - def replacePath(file: AbsolutePath): AbsolutePath = - AbsolutePath( - outFromPattern - .matcher(file.toString()) - .replaceAll(outTo.getOrElse(""))) - Ok(replacePath _) + (outFrom, outTo) match { + case (None, None) => Ok(identity[AbsolutePath]) + case (Some(from), Some(to)) => + val outFromPattern = Pattern.compile(from) + def replacePath(file: AbsolutePath): AbsolutePath = + AbsolutePath(outFromPattern.matcher(file.toString()).replaceAll(to)) + Ok(replacePath _) + case (Some(from), _) => + ConfError + .msg(s"--out-from $from must be accompanied with --out-to") + .notOk + case (_, Some(to)) => + ConfError + .msg(s"--out-to $to must be accompanied with --out-from") + .notOk + } } catch { case e: PatternSyntaxException => ConfError.msg(s"Invalid regex '$outFrom'! ${e.getMessage}").notOk diff --git a/scalafix-tests/unit/src/test/scala/scalafix/cli/BaseCliTest.scala b/scalafix-tests/unit/src/test/scala/scalafix/cli/BaseCliTest.scala index dd4902f16..ad53b30df 100644 --- a/scalafix-tests/unit/src/test/scala/scalafix/cli/BaseCliTest.scala +++ b/scalafix-tests/unit/src/test/scala/scalafix/cli/BaseCliTest.scala @@ -61,9 +61,9 @@ trait BaseCliTest extends FunSuite with DiffAssertions { out = new PrintStream(out) )) val obtained = StringFS.dir2string(root) + assert(exit == expectedExit) assertNoDiff(obtained, expectedLayout) outputAssert(out.toString) - assert(exit == expectedExit) } } @@ -106,9 +106,9 @@ trait BaseCliTest extends FunSuite with DiffAssertions { if (fileIsFixed) BuildInfo.outputSourceroot else BuildInfo.inputSourceroot ).resolve(removeImportsPath)) + assert(exit == expectedExit) assertNoDiff(obtained, expected) outputAssert(out.toString()) - assert(exit == expectedExit) } } diff --git a/scalafix-tests/unit/src/test/scala/scalafix/cli/CliSyntaxTest.scala b/scalafix-tests/unit/src/test/scala/scalafix/cli/CliSyntaxTest.scala index c884be8e0..6884a1b47 100644 --- a/scalafix-tests/unit/src/test/scala/scalafix/cli/CliSyntaxTest.scala +++ b/scalafix-tests/unit/src/test/scala/scalafix/cli/CliSyntaxTest.scala @@ -212,4 +212,29 @@ class CliSyntaxTest extends BaseCliTest { assert(output.contains("No files to fix!") && output.contains("dir")) } ) + + check( + name = "--out-from --out-to change output path", + originalLayout = """ + |/src/shared/a.scala + |object a { def foo { println(1) } } + |""".stripMargin, + args = List( + "-r", + ProcedureSyntax.toString, + "--out-from", + "shared", + "--out-to", + "fixed", + "src" + ), + expectedLayout = """ + |/src/fixed/a.scala + |object a { def foo: Unit = { println(1) } } + | + |/src/shared/a.scala + |object a { def foo { println(1) } } + |""".stripMargin, + expectedExit = ExitStatus.Ok + ) }