mirror of
https://github.com/fluencelabs/aqua.git
synced 2025-03-15 11:40:50 +00:00
Run builtin services directly from aqua run
(#552)
This commit is contained in:
parent
5bd30c7918
commit
7b61247ade
@ -20,17 +20,30 @@ import scalajs.js
|
|||||||
|
|
||||||
import scala.concurrent.ExecutionContext
|
import scala.concurrent.ExecutionContext
|
||||||
|
|
||||||
sealed trait AquaPath
|
sealed trait AquaPath {
|
||||||
|
def getPath[F[_]: Async](): F[Path]
|
||||||
|
}
|
||||||
|
|
||||||
// Path for package relative files
|
// Path for package relative files
|
||||||
case class PackagePath(path: String) extends AquaPath
|
case class PackagePath(path: String) extends AquaPath {
|
||||||
|
def getPath[F[_]: Async](): F[Path] = PlatformOpts.getPackagePath(path)
|
||||||
|
}
|
||||||
|
|
||||||
// Path for absolute or call path relative files
|
// Path for absolute or call path relative files
|
||||||
case class RelativePath(path: Path) extends AquaPath
|
case class RelativePath(path: Path) extends AquaPath {
|
||||||
|
def getPath[F[_]: Async](): F[Path] = path.pure[F]
|
||||||
|
}
|
||||||
|
|
||||||
|
object PackagePath {
|
||||||
|
// path to a builtin file in aqua package
|
||||||
|
val builtin: PackagePath = PackagePath("../aqua-lib/builtin.aqua")
|
||||||
|
}
|
||||||
|
|
||||||
// All info to run any aqua function
|
// All info to run any aqua function
|
||||||
case class RunInfo(
|
case class RunInfo(
|
||||||
common: GeneralOptions,
|
common: GeneralOptions,
|
||||||
func: CliFunc,
|
func: CliFunc,
|
||||||
input: AquaPath,
|
input: Option[AquaPath],
|
||||||
imports: List[Path] = Nil,
|
imports: List[Path] = Nil,
|
||||||
argumentGetters: Map[String, VarJson] = Map.empty,
|
argumentGetters: Map[String, VarJson] = Map.empty,
|
||||||
services: List[Service] = Nil,
|
services: List[Service] = Nil,
|
||||||
@ -50,15 +63,9 @@ class SubCommandBuilder[F[_]: Async](
|
|||||||
riF.flatMap {
|
riF.flatMap {
|
||||||
case Validated.Valid(ri) =>
|
case Validated.Valid(ri) =>
|
||||||
LogFormatter.initLogger(Some(ri.common.logLevel.compiler))
|
LogFormatter.initLogger(Some(ri.common.logLevel.compiler))
|
||||||
(ri.input match {
|
RunCommand.execRun(
|
||||||
case PackagePath(p) => PlatformOpts.getPackagePath(p)
|
ri
|
||||||
case RelativePath(p) => p.pure[F]
|
)
|
||||||
}).flatMap { path =>
|
|
||||||
RunCommand.execRun(
|
|
||||||
ri,
|
|
||||||
path
|
|
||||||
)
|
|
||||||
}
|
|
||||||
case i @ Validated.Invalid(_) =>
|
case i @ Validated.Invalid(_) =>
|
||||||
i.pure[F]
|
i.pure[F]
|
||||||
}
|
}
|
||||||
@ -103,7 +110,7 @@ object SubCommandBuilder {
|
|||||||
name,
|
name,
|
||||||
header,
|
header,
|
||||||
GeneralOptions.opt.map { c =>
|
GeneralOptions.opt.map { c =>
|
||||||
RunInfo(c, CliFunc(funcName), path)
|
RunInfo(c, CliFunc(funcName), Some(path))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import cats.data.Validated.{invalidNec, validNec}
|
|||||||
import cats.data.{Chain, NonEmptyList, Validated, ValidatedNec}
|
import cats.data.{Chain, NonEmptyList, Validated, ValidatedNec}
|
||||||
import cats.effect.IO
|
import cats.effect.IO
|
||||||
import cats.effect.kernel.{Async, Clock}
|
import cats.effect.kernel.{Async, Clock}
|
||||||
|
import cats.syntax.applicative.*
|
||||||
import cats.syntax.flatMap.*
|
import cats.syntax.flatMap.*
|
||||||
import cats.syntax.functor.*
|
import cats.syntax.functor.*
|
||||||
import cats.syntax.monad.*
|
import cats.syntax.monad.*
|
||||||
@ -27,11 +28,12 @@ import cats.syntax.traverse.*
|
|||||||
import fs2.io.file.{Files, Path}
|
import fs2.io.file.{Files, Path}
|
||||||
import scribe.Logging
|
import scribe.Logging
|
||||||
|
|
||||||
|
import scala.concurrent.duration.Duration
|
||||||
import scala.scalajs.js
|
import scala.scalajs.js
|
||||||
|
|
||||||
// Function compiler
|
// Function compiler
|
||||||
class FuncCompiler[F[_]: Files: AquaIO: Async](
|
class FuncCompiler[F[_]: Files: AquaIO: Async](
|
||||||
input: Path,
|
input: Option[AquaPath],
|
||||||
imports: List[Path],
|
imports: List[Path],
|
||||||
transformConfig: TransformConfig,
|
transformConfig: TransformConfig,
|
||||||
withRunImport: Boolean = false
|
withRunImport: Boolean = false
|
||||||
@ -46,9 +48,7 @@ class FuncCompiler[F[_]: Files: AquaIO: Async](
|
|||||||
.fold(
|
.fold(
|
||||||
contexts
|
contexts
|
||||||
.collectFirstSome(_.allFuncs.get(func.name))
|
.collectFirstSome(_.allFuncs.get(func.name))
|
||||||
)(ab =>
|
)(ab => contexts.collectFirstSome(_.abilities.get(ab).flatMap(_.allFuncs.get(func.name))))
|
||||||
contexts.collectFirstSome(_.abilities.get(ab).flatMap(_.allFuncs.get(func.name)))
|
|
||||||
)
|
|
||||||
.map(validNec)
|
.map(validNec)
|
||||||
.getOrElse(
|
.getOrElse(
|
||||||
Validated.invalidNec[String, FuncArrow](
|
Validated.invalidNec[String, FuncArrow](
|
||||||
@ -123,28 +123,53 @@ class FuncCompiler[F[_]: Files: AquaIO: Async](
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def compileToContext(
|
||||||
|
path: Path,
|
||||||
|
imports: List[Path],
|
||||||
|
config: AquaCompilerConf = AquaCompilerConf(transformConfig.constantsList)
|
||||||
|
) = {
|
||||||
|
val sources = new AquaFileSources[F](path, imports)
|
||||||
|
CompilerAPI
|
||||||
|
.compileToContext[F, AquaFileError, FileModuleId, FileSpan.F](
|
||||||
|
sources,
|
||||||
|
SpanParser.parser,
|
||||||
|
config
|
||||||
|
)
|
||||||
|
.map(_.leftMap(_.map(_.show)))
|
||||||
|
}
|
||||||
|
|
||||||
|
private def compileBuiltins() = {
|
||||||
|
for {
|
||||||
|
path <- PackagePath.builtin.getPath()
|
||||||
|
context <- compileToContext(path, Nil)
|
||||||
|
} yield {
|
||||||
|
context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Compile and get only one function
|
// Compile and get only one function
|
||||||
def compile(
|
def compile(
|
||||||
func: CliFunc,
|
func: CliFunc,
|
||||||
jsonServices: List[JsonService]
|
jsonServices: List[JsonService],
|
||||||
|
withBuiltins: Boolean = false
|
||||||
): F[ValidatedNec[String, (FuncArrow, List[Service])]] = {
|
): F[ValidatedNec[String, (FuncArrow, List[Service])]] = {
|
||||||
for {
|
for {
|
||||||
prelude <- Prelude.init[F](withRunImport)
|
prelude <- Prelude.init[F](withRunImport)
|
||||||
sources = new AquaFileSources[F](input, prelude.importPaths ++ imports)
|
// compile builtins and add it to context
|
||||||
// compile only context to wrap and call function later
|
builtinsV <-
|
||||||
compileResult <- Clock[F].timed(
|
if (withBuiltins) compileBuiltins()
|
||||||
CompilerAPI
|
else validNec[String, Chain[AquaContext]](Chain.empty).pure[F]
|
||||||
.compileToContext[F, AquaFileError, FileModuleId, FileSpan.F](
|
compileResult <- input.map { ap =>
|
||||||
sources,
|
// compile only context to wrap and call function later
|
||||||
SpanParser.parser,
|
Clock[F].timed(ap.getPath().flatMap(p => compileToContext(p, prelude.importPaths ++ imports)))
|
||||||
AquaCompilerConf(transformConfig.constantsList)
|
}.getOrElse((Duration.Zero, validNec[String, Chain[AquaContext]](Chain.empty)).pure[F])
|
||||||
)
|
|
||||||
.map(_.leftMap(_.map(_.show)))
|
|
||||||
)
|
|
||||||
(compileTime, contextV) = compileResult
|
(compileTime, contextV) = compileResult
|
||||||
} yield {
|
} yield {
|
||||||
logger.debug(s"Compile time: ${compileTime.toMillis}ms")
|
logger.debug(s"Compile time: ${compileTime.toMillis}ms")
|
||||||
contextV.andThen(c => findFunctionAndServices(c, func, jsonServices))
|
// add builtins to the end of context
|
||||||
|
contextV.andThen(c => builtinsV.map(bc => c ++ bc)) andThen (c =>
|
||||||
|
findFunctionAndServices(c, func, jsonServices)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ object IpfsOpts extends Logging {
|
|||||||
RunInfo(
|
RunInfo(
|
||||||
common,
|
common,
|
||||||
CliFunc(UploadFuncName, LiteralRaw.quote(path) :: Nil),
|
CliFunc(UploadFuncName, LiteralRaw.quote(path) :: Nil),
|
||||||
PackagePath(IpfsAqua)
|
Option(PackagePath(IpfsAqua))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -64,7 +64,7 @@ object DistOpts extends Logging {
|
|||||||
RunInfo(
|
RunInfo(
|
||||||
common,
|
common,
|
||||||
CliFunc(RemoveFuncName, LiteralRaw.quote(srvId) :: Nil),
|
CliFunc(RemoveFuncName, LiteralRaw.quote(srvId) :: Nil),
|
||||||
PackagePath(DistAqua)
|
Option(PackagePath(DistAqua))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -77,7 +77,7 @@ object DistOpts extends Logging {
|
|||||||
RunInfo(
|
RunInfo(
|
||||||
common,
|
common,
|
||||||
CliFunc(CreateServiceFuncName, LiteralRaw.quote(blueprintId) :: Nil),
|
CliFunc(CreateServiceFuncName, LiteralRaw.quote(blueprintId) :: Nil),
|
||||||
PackagePath(DistAqua)
|
Option(PackagePath(DistAqua))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -106,7 +106,7 @@ object DistOpts extends Logging {
|
|||||||
RunInfo(
|
RunInfo(
|
||||||
common,
|
common,
|
||||||
CliFunc(AddBlueprintFuncName, addBlueprintRequestVar :: Nil),
|
CliFunc(AddBlueprintFuncName, addBlueprintRequestVar :: Nil),
|
||||||
PackagePath(DistAqua),
|
Option(PackagePath(DistAqua)),
|
||||||
Nil,
|
Nil,
|
||||||
Map(
|
Map(
|
||||||
addBlueprintRequestVar.name -> VarJson(
|
addBlueprintRequestVar.name -> VarJson(
|
||||||
@ -151,7 +151,7 @@ object DistOpts extends Logging {
|
|||||||
RunInfo(
|
RunInfo(
|
||||||
common,
|
common,
|
||||||
CliFunc(DeployFuncName, args),
|
CliFunc(DeployFuncName, args),
|
||||||
PackagePath(DistAqua),
|
Option(PackagePath(DistAqua)),
|
||||||
Nil,
|
Nil,
|
||||||
// hack: air cannot use undefined fields, fill undefined arrays with nils
|
// hack: air cannot use undefined fields, fill undefined arrays with nils
|
||||||
Map(srvName -> VarJson(srvArg, c))
|
Map(srvName -> VarJson(srvArg, c))
|
||||||
|
@ -77,7 +77,7 @@ object RemoteInfoOpts {
|
|||||||
ListInterfacesFuncName,
|
ListInterfacesFuncName,
|
||||||
Nil
|
Nil
|
||||||
),
|
),
|
||||||
PackagePath(NetworkAqua)
|
Option(PackagePath(NetworkAqua))
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
RunInfo(
|
RunInfo(
|
||||||
@ -86,7 +86,7 @@ object RemoteInfoOpts {
|
|||||||
ListInterfacesByPeerFuncName,
|
ListInterfacesByPeerFuncName,
|
||||||
peer.map(LiteralRaw.quote).getOrElse(ValueRaw.InitPeerId) :: Nil
|
peer.map(LiteralRaw.quote).getOrElse(ValueRaw.InitPeerId) :: Nil
|
||||||
),
|
),
|
||||||
PackagePath(NetworkAqua)
|
Option(PackagePath(NetworkAqua))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -99,7 +99,7 @@ object RemoteInfoOpts {
|
|||||||
RunInfo(
|
RunInfo(
|
||||||
common,
|
common,
|
||||||
CliFunc(GetInterfaceFuncName, LiteralRaw.quote(serviceId) :: Nil),
|
CliFunc(GetInterfaceFuncName, LiteralRaw.quote(serviceId) :: Nil),
|
||||||
PackagePath(NetworkAqua)
|
Option(PackagePath(NetworkAqua))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -112,7 +112,7 @@ object RemoteInfoOpts {
|
|||||||
RunInfo(
|
RunInfo(
|
||||||
common,
|
common,
|
||||||
CliFunc(GetModuleInterfaceFuncName, LiteralRaw.quote(serviceId) :: Nil),
|
CliFunc(GetModuleInterfaceFuncName, LiteralRaw.quote(serviceId) :: Nil),
|
||||||
PackagePath(NetworkAqua)
|
Option(PackagePath(NetworkAqua))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -64,7 +64,7 @@ object RunCommand extends Logging {
|
|||||||
*/
|
*/
|
||||||
def run[F[_]: Files: AquaIO: Async](
|
def run[F[_]: Files: AquaIO: Async](
|
||||||
func: CliFunc,
|
func: CliFunc,
|
||||||
input: Path,
|
input: Option[AquaPath],
|
||||||
imports: List[Path],
|
imports: List[Path],
|
||||||
runConfig: RunConfig,
|
runConfig: RunConfig,
|
||||||
transformConfig: TransformConfig
|
transformConfig: TransformConfig
|
||||||
@ -72,7 +72,7 @@ object RunCommand extends Logging {
|
|||||||
val funcCompiler = new FuncCompiler[F](input, imports, transformConfig, withRunImport = true)
|
val funcCompiler = new FuncCompiler[F](input, imports, transformConfig, withRunImport = true)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
funcArrowV <- funcCompiler.compile(func, runConfig.jsonServices)
|
funcArrowV <- funcCompiler.compile(func, runConfig.jsonServices, true)
|
||||||
callResult <- Clock[F].timed {
|
callResult <- Clock[F].timed {
|
||||||
funcArrowV match {
|
funcArrowV match {
|
||||||
case Validated.Valid((funcCallable, jsonServices)) =>
|
case Validated.Valid((funcCallable, jsonServices)) =>
|
||||||
@ -112,7 +112,6 @@ object RunCommand extends Logging {
|
|||||||
*/
|
*/
|
||||||
def execRun[F[_]: Async](
|
def execRun[F[_]: Async](
|
||||||
runInfo: RunInfo,
|
runInfo: RunInfo,
|
||||||
inputPath: Path
|
|
||||||
): F[ValidatedNec[String, Unit]] = {
|
): F[ValidatedNec[String, Unit]] = {
|
||||||
val common = runInfo.common
|
val common = runInfo.common
|
||||||
LogFormatter.initLogger(Some(common.logLevel.compiler))
|
LogFormatter.initLogger(Some(common.logLevel.compiler))
|
||||||
@ -121,7 +120,7 @@ object RunCommand extends Logging {
|
|||||||
RunCommand
|
RunCommand
|
||||||
.run[F](
|
.run[F](
|
||||||
runInfo.func,
|
runInfo.func,
|
||||||
inputPath,
|
runInfo.input,
|
||||||
runInfo.imports,
|
runInfo.imports,
|
||||||
RunConfig(common, runInfo.argumentGetters, runInfo.services ++ builtinServices, runInfo.jsonServices, runInfo.pluginsPaths),
|
RunConfig(common, runInfo.argumentGetters, runInfo.services ++ builtinServices, runInfo.jsonServices, runInfo.pluginsPaths),
|
||||||
transformConfig(common.on, common.constants, common.flags.noXor, common.flags.noRelay)
|
transformConfig(common.on, common.constants, common.flags.noXor, common.flags.noRelay)
|
||||||
|
@ -51,16 +51,19 @@ object RunOpts extends Logging {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def runOptsCompose[F[_]: Files: Concurrent]
|
def runOptsCompose[F[_]: Files: Concurrent]
|
||||||
: Opts[F[ValidatedNec[String, (Path, List[Path], FuncWithData, Option[NonEmptyList[JsonService]], List[String])]]] = {
|
: Opts[F[ValidatedNec[String, (Option[AquaPath], List[Path], FuncWithData, Option[NonEmptyList[JsonService]], List[String])]]] = {
|
||||||
(
|
(
|
||||||
AppOpts.inputOpts[F],
|
AppOpts.wrapWithOption(AppOpts.inputOpts[F]),
|
||||||
AppOpts.importOpts[F],
|
AppOpts.importOpts[F],
|
||||||
ArgOpts.funcWithArgsOpt[F],
|
ArgOpts.funcWithArgsOpt[F],
|
||||||
AppOpts.wrapWithOption(JsonService.jsonServiceOpt),
|
AppOpts.wrapWithOption(JsonService.jsonServiceOpt),
|
||||||
AppOpts.wrapWithOption(Plugin.opt)
|
AppOpts.wrapWithOption(Plugin.opt)
|
||||||
).mapN { case (inputF, importF, funcWithArgsF, jsonServiceOp, pluginsOp) =>
|
).mapN { case (inputF, importF, funcWithArgsF, jsonServiceOp, pluginsOp) =>
|
||||||
for {
|
for {
|
||||||
inputV <- inputF
|
inputV: ValidatedNec[String, Option[AquaPath]] <-
|
||||||
|
inputF.map(_.map(_.map(p => Option(RelativePath(p))))).getOrElse {
|
||||||
|
validNec[String, Option[AquaPath]](None).pure[F]
|
||||||
|
}
|
||||||
importV <- importF
|
importV <- importF
|
||||||
funcWithArgsV <- funcWithArgsF
|
funcWithArgsV <- funcWithArgsF
|
||||||
jsonServiceV <- jsonServiceOp
|
jsonServiceV <- jsonServiceOp
|
||||||
@ -93,7 +96,7 @@ object RunOpts extends Logging {
|
|||||||
RunInfo(
|
RunInfo(
|
||||||
common,
|
common,
|
||||||
funcWithArgs.func,
|
funcWithArgs.func,
|
||||||
RelativePath(input),
|
input,
|
||||||
imps,
|
imps,
|
||||||
funcWithArgs.getters,
|
funcWithArgs.getters,
|
||||||
Nil,
|
Nil,
|
||||||
|
@ -120,7 +120,7 @@ object ScriptOpts extends Logging {
|
|||||||
val tConfig = TransformConfig(relayVarName = None, wrapWithXor = false)
|
val tConfig = TransformConfig(relayVarName = None, wrapWithXor = false)
|
||||||
val funcCompiler =
|
val funcCompiler =
|
||||||
new FuncCompiler[F](
|
new FuncCompiler[F](
|
||||||
input,
|
Option(RelativePath(input)),
|
||||||
imports,
|
imports,
|
||||||
tConfig,
|
tConfig,
|
||||||
withRunImport = true
|
withRunImport = true
|
||||||
@ -173,7 +173,7 @@ object ScriptOpts extends Logging {
|
|||||||
RunInfo(
|
RunInfo(
|
||||||
common,
|
common,
|
||||||
CliFunc(AddFuncName, scriptVar :: intervalArg :: Nil),
|
CliFunc(AddFuncName, scriptVar :: intervalArg :: Nil),
|
||||||
PackagePath(ScriptAqua),
|
Option(PackagePath(ScriptAqua)),
|
||||||
Nil,
|
Nil,
|
||||||
Map(
|
Map(
|
||||||
"script" -> VarJson(
|
"script" -> VarJson(
|
||||||
@ -227,7 +227,7 @@ object ScriptOpts extends Logging {
|
|||||||
RunInfo(
|
RunInfo(
|
||||||
common,
|
common,
|
||||||
CliFunc(RemoveFuncName, LiteralRaw.quote(scriptId) :: Nil),
|
CliFunc(RemoveFuncName, LiteralRaw.quote(scriptId) :: Nil),
|
||||||
PackagePath(ScriptAqua)
|
Option(PackagePath(ScriptAqua))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user