All Downloads are FREE. Search and download functionalities are using the official Maven repository.

polynote.app.package.scala Maven / Gradle / Ivy

The newest version!
package polynote

import java.io.File

import polynote.kernel.{BaseEnv, GlobalEnv, Kernel}
import polynote.kernel.environment.Config
import polynote.kernel.interpreter.Interpreter
import polynote.kernel.logging.Logging
import zio.{Has, URIO, ZIO, ZLayer}

import scala.annotation.tailrec

package object app {
  type Environment = zio.ZEnv with Logging
  type MainArgs = Has[Args]

  object MainArgs {
    def access: URIO[MainArgs, Args] = ZIO.access[MainArgs](_.get)
  }

  case class Args(
    command: String = "server",
    configFile: File = new File("config.yml"),
    watchUI: Boolean = false,
    rest: List[String] = Nil
  )

  object Args {
    def parse(args: List[String]): ZLayer[Any, Throwable, MainArgs] = {
      val (command, remaining) = parseFirst(args)
      ZLayer.fromEffect(
        ZIO.fromEither(
          parseArgsEither(remaining, Args(command = command))
        ))
    }

    @tailrec
    private def parseFirst(args: List[String]): (String, List[String]) = args match {
      case Nil => ("server", Nil)
      case mainClass :: rest if mainClass startsWith "polynote." => parseFirst(rest)
      case flag :: rest if flag startsWith "-" => ("server", flag :: rest)
      case cmd :: rest => (cmd, rest)
    }

    @tailrec
    private def parseArgsEither(args: List[String], current: Args = Args()): Either[Throwable, Args] = args match {
      case Nil => Right(current)
      case ("--config" | "-c") :: filename :: rest => parseArgsEither(rest, current.copy(configFile = new File(filename)))
      case ("--watch" | "-w") :: rest => parseArgsEither(rest, current.copy(watchUI = true))
      case mainClass :: rest if mainClass startsWith "polynote." => parseArgsEither(rest, current) // class name might be arg0 in some circumstances
      case "--config" :: Nil => Left(new IllegalArgumentException("No config path specified. Usage: `--config path/to/config.yml`"))
      case other :: rest => parseArgsEither(rest, current.copy(rest = current.rest :+ other))
    }
  }

  val globalEnv: ZLayer[BaseEnv with MainArgs with Kernel.Factory, Throwable, GlobalEnv] =
    ((ZLayer.identity[BaseEnv] ++ ZLayer.identity[MainArgs] ++ Config.layer) >>> (ZLayer.identity[Config] ++ Interpreter.Factories.load)) ++
      ZLayer.identity[Kernel.Factory]
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy