VirtusLab / scala-cli

Scala CLI is a command-line tool to interact with the Scala language. It lets you compile, run, test, and package your Scala code (and more!)
https://scala-cli.virtuslab.org
Apache License 2.0
546 stars 127 forks source link

Assertion Error while loading JAR from URL: "contains invalid '/'" #3220

Open sankalpgambhir opened 1 week ago

sankalpgambhir commented 1 week ago

Version(s) 1.5.0 originally, but tested on main as well (my first time building scala-cli, so take it with a pinch of salt)

Describe the bug When trying to provide a fallback JAR URL for a dependency, scala-cli fails to process the URL correctly, raising a "contains invalid '/'" assertion failure.

To Reproduce Use the following snippet (the dep url is taken from scala-cli docs here):

//> using dep tabby:tabby:0.2.3,url=https://github.com/bjornregnell/tabby/releases/download/v0.2.3/tabby_3-0.2.3.jar

println("Hello, scala-cli")
> scala-cli ../dep-test.sc   
Error: java.lang.AssertionError: module name //github.com/bjornregnell/tabby/releases/download/v0.2.3/tabby_3-0.2.3.jar contains invalid '/'
For more details, please see '$HOME/.cache/scalacli/virtual-projects/c9/project-0073d09a/.scala-build/stacktraces/1728042792-8010526352619289440.log'

The JAR does exist at this URL. Using my own dep and URL also does not work.

Expected behaviour The JAR should be correctly imported from the given URL.

sankalpgambhir commented 1 week ago

Additionally, here is the generated stack trace (also attached):

Stack trace ```java java.lang.AssertionError: module name //github.com/bjornregnell/tabby/releases/download/v0.2.3/tabby_3-0.2.3.jar contains invalid '/' coursier.core.Validation$.$anonfun$assertValid$1(Definitions.scala:421) scala.util.Either.fold(Either.scala:198) coursier.core.Validation$.assertValid(Definitions.scala:421) coursier.core.Module.(Definitions.scala:42) coursier.core.Module$.apply(Definitions.scala:81) coursier.package$Module$.apply(package.scala:52) scala.build.internal.Util$ModuleOps$.toCs$extension(Util.scala:45) scala.build.internal.Util$DependencyOps$.toCs$extension(Util.scala:66) scala.build.internal.Util$ScalaDependencyOps$.toCs$extension(Util.scala:87) scala.build.internal.Util$ScalaDependencyOps$.toCs$extension(Util.scala:91) scala.build.internal.Util$PositionedScalaDependencyOps$.$anonfun$2(Util.scala:107) scala.build.Positioned.map(Positioned.scala:15) scala.build.internal.Util$PositionedScalaDependencyOps$.toCs$extension(Util.scala:107) scala.build.Artifacts$.coursierDeps$$anonfun$1(Artifacts.scala:518) scala.collection.immutable.List.map(List.scala:251) scala.collection.immutable.List.map(List.scala:79) scala.build.Artifacts$.coursierDeps(Artifacts.scala:519) scala.build.Artifacts$.fetchAnyDependenciesWithResult$$anonfun$1(Artifacts.scala:571) scala.build.EitherCps$Helper.apply(EitherCps.scala:19) scala.build.Artifacts$.fetchAnyDependenciesWithResult(Artifacts.scala:607) scala.build.Artifacts$.apply$$anonfun$1(Artifacts.scala:371) scala.build.EitherCps$Helper.apply(EitherCps.scala:19) scala.build.Artifacts$.apply(Artifacts.scala:467) scala.build.options.BuildOptions.artifacts$$anonfun$1(BuildOptions.scala:468) scala.build.EitherCps$Helper.apply(EitherCps.scala:19) scala.build.options.BuildOptions.artifacts(BuildOptions.scala:471) scala.build.Build$.prepareBuild$$anonfun$1(Build.scala:1035) scala.build.EitherCps$Helper.apply(EitherCps.scala:19) scala.build.Build$.prepareBuild(Build.scala:1078) scala.build.Build$.buildOnce$$anonfun$1(Build.scala:1099) scala.build.EitherCps$Helper.apply(EitherCps.scala:19) scala.build.Build$.buildOnce(Build.scala:1145) scala.build.Build$.build$$anonfun$2(Build.scala:448) scala.build.EitherCps$Helper.apply(EitherCps.scala:19) scala.build.Build$.build(Build.scala:475) scala.build.Build$.doBuildScope$1$$anonfun$1(Build.scala:314) scala.build.EitherCps$Helper.apply(EitherCps.scala:19) scala.build.Build$.doBuildScope$1(Build.scala:317) scala.build.Build$.doBuild$1$$anonfun$1(Build.scala:319) scala.build.EitherCps$Helper.apply(EitherCps.scala:19) scala.build.Build$.doBuild$1(Build.scala:377) scala.build.Build$.buildScopes$1$$anonfun$1(Build.scala:381) scala.build.EitherCps$Helper.apply(EitherCps.scala:19) scala.build.Build$.buildScopes$1(Build.scala:408) scala.build.Build$.build$$anonfun$1(Build.scala:410) scala.build.EitherCps$Helper.apply(EitherCps.scala:19) scala.build.Build$.build(Build.scala:422) scala.build.Build$.build$$anonfun$3$$anonfun$1(Build.scala:590) scala.util.Either.flatMap(Either.scala:360) scala.build.compiler.ScalaCompilerMaker.withCompiler(ScalaCompilerMaker.scala:37) scala.build.compiler.ScalaCompilerMaker.withCompiler$(ScalaCompilerMaker.scala:9) scala.build.compiler.BloopCompilerMaker.withCompiler(BloopCompilerMaker.scala:14) scala.build.Build$.build$$anonfun$3(Build.scala:613) scala.build.EitherCps$Helper.apply(EitherCps.scala:19) scala.build.Build$.build(Build.scala:616) scala.cli.commands.run.Run$.runCommand(Run.scala:338) scala.cli.commands.default.Default.runCommand(Default.scala:61) scala.cli.commands.default.Default.runCommand(Default.scala:40) scala.cli.commands.ScalaCommand.run(ScalaCommand.scala:388) scala.cli.commands.ScalaCommand.run(ScalaCommand.scala:369) caseapp.core.app.CaseApp.main(CaseApp.scala:157) scala.cli.commands.ScalaCommand.main(ScalaCommand.scala:354) caseapp.core.app.CommandsEntryPoint.main(CommandsEntryPoint.scala:169) scala.cli.ScalaCliCommands.main(ScalaCliCommands.scala:125) scala.cli.ScalaCli$.main0(ScalaCli.scala:296) scala.cli.ScalaCli$.main(ScalaCli.scala:119) scala.cli.ScalaCli.main(ScalaCli.scala) ```

scalacli-invalid-url-stack-trace.log

sankalpgambhir commented 1 week ago

Thanks to @SimonGuilloud for spotting that the following actually works with the example above, moving the dep from the file to the cli:

> scala-cli dep-test.sc --dependency "tabby:tabby:0.2.3,url=https://github.com/bjornregnell/tabby/releases/download/v0.2.3/tabby_3-0.2.3.jar"
Downloading 2 dependencies
Compiling project (Scala 3.5.0, JVM (17))
Compiled project (Scala 3.5.0, JVM (17))
Hello, scala-cli