You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by ar...@apache.org on 2020/10/14 03:25:30 UTC

[incubator-nlpcraft] 21/23: WIP.

This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git

commit ba21c9caf07b7c5323ec8c94875dbe14340039db
Author: Aaron Radzinski <ar...@datalingvo.com>
AuthorDate: Tue Oct 13 19:58:19 2020 -0700

    WIP.
---
 .../nlpcraft/model/tools/cmdline/NCCli.scala       | 97 +++++++++++-----------
 .../apache/nlpcraft/model/NCIntentSampleSpec.scala |  1 +
 2 files changed, 48 insertions(+), 50 deletions(-)

diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCli.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCli.scala
index 3e5cdb8..f8efcb2 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCli.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCli.scala
@@ -38,19 +38,18 @@ import java.util.Date
 import java.io._
 import java.nio.charset.StandardCharsets
 import java.nio.file.Paths
-import java.time.Instant
 import java.util.regex.Pattern
 
 import org.apache.commons.io.input.{ReversedLinesFileReader, Tailer, TailerListenerAdapter}
 import org.apache.commons.lang3.time.DurationFormatUtils
 import org.apache.http.util.EntityUtils
 import org.jline.builtins.Commands
-import org.jline.reader.Completer
+import org.jline.reader.{Candidate, Completer, EndOfFileException, Highlighter, LineReader, LineReaderBuilder, ParsedLine, UserInterruptException}
 import org.jline.reader.impl.DefaultParser
 import org.jline.terminal.{Terminal, TerminalBuilder}
-import org.jline.reader.{Candidate, EndOfFileException, LineReader, LineReaderBuilder, ParsedLine, UserInterruptException}
 import org.jline.reader.impl.DefaultParser.Bracket
 import org.jline.reader.impl.history.DefaultHistory
+import org.jline.utils.AttributedString
 import org.jline.utils.InfoCmp.Capability
 import resource.managed
 
@@ -69,6 +68,8 @@ object NCCli extends App {
 
     //noinspection RegExpRedundantEscape
     private final val TAILER_PTRN = Pattern.compile("^.*NC[a-zA-Z0-9]+ started \\[[\\d]+ms\\]$")
+    private final val CMD_NAME = Pattern.compile("(^\\s*[\\w-]+)(\\s)")
+    private final val CMD_PARAM = Pattern.compile("(\\s--?[\\w-]+)([= ]?)")
 
     // Number of server services that need to be started + 1 progress start.
     // Used for progress bar functionality.
@@ -143,6 +144,10 @@ object NCCli extends App {
             s"Missing mandatory parameter $C${"'" + cmd.params.find(_.id == paramId).get.names.head + "'"}$RST, " +
             s"type $C'help --cmd=${cmd.name}'$RST to get help."
         )
+    case class MissingMandatoryJsonParameters(cmd: Command, path: String)
+        extends IllegalArgumentException(
+            s"Missing mandatory JSON parameter for $C${"'" + cmd.name + s" --path=$path'"}$RST, type $C'help --cmd=${cmd.name}'$RST to get help."
+        )
     case class InvalidParameter(cmd: Command, paramId: String)
         extends IllegalArgumentException(
             s"Invalid parameter $C${"'" + cmd.params.find(_.id == paramId).get.names.head + "'"}$RST, " +
@@ -473,7 +478,6 @@ object NCCli extends App {
         var isServerOnline: Boolean = false,
         var accessToken: Option[String] = None,
         var serverLog: Option[File] = None,
-        var lastOkInput: Option[String] = None,
         var probes: List[Probe] = Nil // List of connected probes.
     )
 
@@ -1832,38 +1836,40 @@ object NCCli extends App {
         var first = true
         val buf = new StringBuilder()
 
+        val spec = REST_SPEC.find(_.path == path).getOrElse(throw InvalidParameter(cmd, "path"))
+
+        var mandatoryParams = spec.params.filter(!_.optional)
+
         for (arg ← synthArgs) {
             val jsName = arg.parameter.id
 
-            REST_SPEC.find(_.path == path) match {
-                case Some(spec) ⇒
-                    spec.params.find(_.name == jsName) match {
-                        case Some(param) ⇒
-                            if (!first)
-                                buf ++= ","
+            spec.params.find(_.name == jsName) match {
+                case Some(param) ⇒
+                    mandatoryParams = mandatoryParams.filter(_.name != jsName)
 
-                            first = false
+                    if (!first)
+                        buf ++= ","
 
-                            buf ++= "\"" + jsName +"\":"
+                    first = false
 
-                            val value = arg.value.getOrElse(throw InvalidJsonParameter(cmd, arg.parameter.names.head))
+                    buf ++= "\"" + jsName + "\":"
 
-                            param.kind match {
-                                case STRING ⇒ buf ++= "\"" + U.escapeJson(stripQuotes(value)) + "\""
-                                case OBJECT | ARRAY ⇒ buf ++= stripQuotes(value)
-                                case BOOLEAN | NUMERIC ⇒ buf ++= value
-                            }
+                    val value = arg.value.getOrElse(throw InvalidJsonParameter(cmd, arg.parameter.names.head))
 
-                        case None ⇒ throw InvalidJsonParameter(cmd, jsName)
+                    param.kind match {
+                        case STRING ⇒ buf ++= "\"" + U.escapeJson(stripQuotes(value)) + "\""
+                        case OBJECT | ARRAY ⇒ buf ++= stripQuotes(value)
+                        case BOOLEAN | NUMERIC ⇒ buf ++= value
                     }
 
-                case None ⇒ throw InvalidParameter(cmd, "path")
+                case None ⇒ throw InvalidJsonParameter(cmd, jsName)
             }
         }
 
-        val json = s"{${buf.toString()}}"
+        if (mandatoryParams.nonEmpty)
+            throw MissingMandatoryJsonParameters(cmd, path)
 
-        httpRest(cmd, path, json)
+        httpRest(cmd, path, s"{${buf.toString()}}")
     }
 
     /**
@@ -2099,35 +2105,30 @@ object NCCli extends App {
             }
         }
 
-        class ReplHistory extends DefaultHistory {
-            /**
-             *
-             * @param time
-             * @param line
-             */
-            override def add(time: Instant, line: String): Unit = {
-                // No-op.
-            }
+        class ReplHighlighter extends Highlighter {
+            override def highlight(reader: LineReader, buffer: String): AttributedString =
+                AttributedString.fromAnsi(
+                    CMD_NAME.matcher(
+                        CMD_PARAM.matcher(
+                            buffer
+                        )
+                        .replaceAll(c("$1") + "$2")
+                    )
+                    .replaceAll(bo(g("$1")) + "$2")
+                )
 
-            /**
-             *
-             */
-            def submitLastLine(): Unit =
-                state.lastOkInput match {
-                    case Some(line) ⇒ super.add(Instant.now(), line)
-                    case None ⇒ ()
-                }
+            override def setErrorPattern(errorPattern: Pattern): Unit = ()
+            override def setErrorIndex(errorIndex: Int): Unit = ()
         }
 
-        val hist = new ReplHistory()
-
         val reader = LineReaderBuilder
             .builder
             .appName("NLPCraft")
             .terminal(term)
             .completer(completer)
             .parser(parser)
-            .history(hist)
+            .highlighter(new ReplHighlighter())
+            .history(new DefaultHistory())
             .variable(LineReader.SECONDARY_PROMPT_PATTERN, s"${g("...>")} ")
             .variable(LineReader.INDENTATION, 2)
             .build
@@ -2179,15 +2180,10 @@ object NCCli extends App {
                     .trim()
 
                 if (line.nonEmpty)
-                    try {
+                    try 
                         doCommand(splitBySpace(line), repl = true)
-
-                        state.lastOkInput = if (exitStatus == 0) Some(line) else None
-                    }
                     catch {
                         case e: SplitError ⇒
-                            state.lastOkInput = None
-
                             val idx = e.index
                             val lineX = line.substring(0, idx) + r(line.substring(idx, idx + 1) ) + line.substring(idx + 1)
                             val dashX = c("-" * idx) + r("^") + c("-" * (line.length - idx - 1))
@@ -2197,8 +2193,6 @@ object NCCli extends App {
                             error(s"  ${r("+-")} $dashX")
                     }
             }
-
-            hist.submitLastLine()
         }
 
         U.stopThread(pinger)
@@ -2475,6 +2469,9 @@ object NCCli extends App {
             val value = if (parts.size == 1) None else Some(parts(1).trim)
             val hasSynth = cmd.params.exists(_.synthetic)
 
+            if (name.endsWith("=")) // Missing value or extra '='.
+                throw mkError()
+
             cmd.findParameterByNameOpt(name) match {
                 case None ⇒
                     if (hasSynth)
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/NCIntentSampleSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/NCIntentSampleSpec.scala
index d9872af..5b3804a 100644
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/NCIntentSampleSpec.scala
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/NCIntentSampleSpec.scala
@@ -6,6 +6,7 @@ import org.apache.nlpcraft.model.tools.test.NCTestAutoModelValidator
 import org.junit.jupiter.api.Test
 
 import scala.collection.JavaConverters._
+import scala.language.implicitConversions
 
 /**
   * Sample annotation test model.