From d42a0b160b78efe81bd0757c1c45d2ddcb559ef8 Mon Sep 17 00:00:00 2001 From: Chris Kipp Date: Wed, 24 Aug 2022 21:15:51 +0200 Subject: [PATCH] feat: add in ability to specify the output type This allows the user to pass in `--output dump.lsif` or just `dump.lsif` or another valid output type to output other types than the default scip which was happening before. If used the same way as before with no argument the behavior is the same. Refs: https://github.com/sourcegraph/scip-java/issues/482 --- build.sc | 8 +++- itest/src/minimal/build.sc | 9 +++++ plugin/src/io/kipp/mill/scip/Scip.scala | 51 +++++++++++++++++++++---- 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/build.sc b/build.sc index 5a55289..efbc97e 100644 --- a/build.sc +++ b/build.sc @@ -93,7 +93,13 @@ object itest extends MillIntegrationTestModule { T { Seq( PathRef(testBase / "minimal") -> Seq( - TestInvocation.Targets(Seq("generate"), noServer = true) + TestInvocation.Targets(Seq("generate"), noServer = true), + TestInvocation.Targets(Seq("lsif"), noServer = true), + TestInvocation.Targets( + Seq("fail"), + noServer = true, + expectedExitCode = 1 + ) ) ) } diff --git a/itest/src/minimal/build.sc b/itest/src/minimal/build.sc index d073da8..0b0e896 100644 --- a/itest/src/minimal/build.sc +++ b/itest/src/minimal/build.sc @@ -35,3 +35,12 @@ def generate(ev: Evaluator) = T.command { // Then we ensure that the index.scip file was actually created assertEquals(os.exists(scipFile), true) } + +def lsif(ev: Evaluator) = T.command { + val scipFile = Scip.generate(ev, "dump.lsif")() + assertEquals(os.exists(scipFile), true) +} + +def fail(ev: Evaluator) = T.command { + Scip.generate(ev, "wrong.format") +} diff --git a/plugin/src/io/kipp/mill/scip/Scip.scala b/plugin/src/io/kipp/mill/scip/Scip.scala index 3645729..3154366 100644 --- a/plugin/src/io/kipp/mill/scip/Scip.scala +++ b/plugin/src/io/kipp/mill/scip/Scip.scala @@ -6,7 +6,9 @@ import com.sourcegraph.scip_semanticdb.ScipSemanticdb import com.sourcegraph.scip_semanticdb.ScipSemanticdbOptions import mill._ import mill.api.Logger +import mill.api.Result import mill.define.ExternalModule +import mill.define.Task import mill.eval.Evaluator import mill.main.EvaluatorScopt import mill.scalalib.JavaModule @@ -26,9 +28,12 @@ object Scip extends ExternalModule { * producing semanticDB. Once we fully have all the semanticDB we call * ScipSemanticdb to slurp it all up and create a SCIP index. */ - def generate(ev: Evaluator) = T.command { + def generate(ev: Evaluator, output: String = "index.scip") = T.command { + val log = T.ctx().log + val outputFormat = validateFormat(output)() + val semanticdbVersion = ScipBuildInfo.semanticDBVersion val modules = computeModules(ev) @@ -200,8 +205,33 @@ object Scip extends ExternalModule { } .map(_.path) - createScip(log, T.dest, T.workspace, projects) - T.dest / "index.scip" + createScip(log, T.dest, T.workspace, projects, output, outputFormat) + T.dest / output + } + + /** Given an output string, determine that a ScipOutputFormat can be + * determined from it. + * + * @param output + * the given output from the user + * @return + * the parsed output format to be generated + */ + private def validateFormat(output: String): Task[ScipOutputFormat] = T.task { + val format = ScipOutputFormat.fromFilename(output) + if (format == ScipOutputFormat.UNKNOWN) { + val msg = + s"""Detected an unknown output type. You'll want to use one of the following: + | + | - *.lsif + | - *.lsif-protobuf + | - *.scip + | - *.scip.ndjson + |""".stripMargin + Result.Failure(msg) + } else { + format + } } /** After all the semanticDB has been produced we can create the SCIP index @@ -215,14 +245,21 @@ object Scip extends ExternalModule { * The current workspace root * @param projects * Full classpath of the project to be used for cross-project navigation. + * @param output + * The name out of the output file + * @param outputFormat + * The format of the output */ private def createScip( log: Logger, dest: Path, workspace: Path, - projects: Seq[Path] + projects: Seq[Path], + output: String, + outputFormat: ScipOutputFormat ): Unit = { - val scipFile = dest / "index.scip" + + val scipFile = dest / output val reporter = new ScipReporter(log) val toolInfo = LsifToolInfo @@ -233,7 +270,7 @@ object Scip extends ExternalModule { .setVersion(ScipBuildInfo.semanticDBJavaVersion) .build() - log.info(s"Creating a index.scip in ${scipFile}") + log.info(s"Creating a ${output} in ${scipFile}") // So this is maybe a bit opinionated here, but we're only writing this to // disk for easier debugging. Normally scip-java can read this up to when @@ -260,7 +297,7 @@ object Scip extends ExternalModule { reporter, toolInfo, "java", - ScipOutputFormat.TYPED_PROTOBUF, + outputFormat, true, // parallel -- this is fine classPathEntries .map(_.toPackageInformation)