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

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


The following commit(s) were added to refs/heads/NLPCRAFT-108 by this push:
     new 14b912c  WIP.
14b912c is described below

commit 14b912c9a69e129373e77ef94dfa97fb85effb60
Author: Aaron Radzinski <[email protected]>
AuthorDate: Tue Aug 25 11:21:04 2020 -0700

    WIP.
---
 .../nlpcraft/common/ascii/NCAsciiTable.scala       |  42 +++---
 .../model/tools/cmdline/NCCommandLine.scala        | 156 +++++++++++++++++----
 .../nlpcraft/common/ascii/NCAsciiTableSpec.scala   |   2 +-
 3 files changed, 153 insertions(+), 47 deletions(-)

diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/ascii/NCAsciiTable.scala 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/ascii/NCAsciiTable.scala
index e483e50..db86fec 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/ascii/NCAsciiTable.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/ascii/NCAsciiTable.scala
@@ -157,8 +157,10 @@ class NCAsciiTable {
      * @param bottom Bottom margin.
      * @param left Left margin.
      */
-    def margin(top: Int = 0, right: Int = 0, bottom: Int = 0, left: Int = 0) {
+    def margin(top: Int = 0, right: Int = 0, bottom: Int = 0, left: Int = 0): 
NCAsciiTable = {
         margin = Margin(top, right, bottom, left)
+
+        this
     }
 
     /**
@@ -242,12 +244,21 @@ class NCAsciiTable {
     }
 
     /**
+     *
+     * @param style
+     * @param lines
+     * @return
+     */
+    private def mkRowCell(style: String, lines: Any*): Cell =
+        Cell(Style(style), (for (line ← lines) yield 
x(line).grouped(maxCellWidth)).flatten)
+
+    /**
      * Adds single header cell.
      *
      * @param lines One or more cell lines.
      */
     def addHeaderCell(lines: Any*): NCAsciiTable = {
-        hdr :+= Cell(Style(headerStyle), (for (line ← lines) yield 
x(line).grouped(maxCellWidth)).flatten)
+        hdr :+= mkRowCell(headerStyle, lines: _*)
 
         this
     }
@@ -258,7 +269,7 @@ class NCAsciiTable {
      * @param lines One or more row cells. Multiple lines will be printed on 
separate lines.
      */
     def addRowCell(lines: Any*): NCAsciiTable = {
-        curRow :+= Cell(Style(rowStyle), (for (line ← lines) yield 
x(line).grouped(maxCellWidth)).flatten)
+        curRow :+= mkRowCell(rowStyle, lines: _*)
 
         this
     }
@@ -341,9 +352,12 @@ class NCAsciiTable {
         for (_ ← 0 until margin.top)
             tbl ++= " \n"
 
+        def mkRow(crs: String, cor: String): String =
+            s"${space(margin.left)}$crs${dash(cor, 
tableW)}$crs${space(margin.right)}\n"
+
         // Print header, if any.
         if (isHdr) {
-            tbl ++= s"${space(margin.left)}$HDR_CRS${dash(HDR_HOR, 
tableW)}$HDR_CRS${space(margin.right)}\n"
+            tbl ++= mkRow(HDR_CRS, HDR_HOR)
 
             for (i ← 0 until hdrH) {
                 // Left margin and '|'.
@@ -364,10 +378,10 @@ class NCAsciiTable {
                 tbl ++= s"${space(margin.right)}\n"
             }
 
-            tbl ++= s"${space(margin.left)}$HDR_CRS${dash(HDR_HOR, 
tableW)}$HDR_CRS${space(margin.right)}\n"
+            tbl ++= mkRow(HDR_CRS, HDR_HOR)
         }
         else
-            tbl ++= s"${space(margin.left)}$ROW_CRS${dash(ROW_HOR, 
tableW)}$ROW_CRS${space(margin.right)}\n"
+            tbl ++= mkRow(ROW_CRS, ROW_HOR)
 
         // Print rows, if any.
         if (rows.nonEmpty) {
@@ -482,23 +496,19 @@ class NCAsciiTable {
      *
      * @param path File path.
      */
-    def render(path: String): Unit =
-        try
-            managed(new PrintStream(path)) acquireAndGet { ps ⇒
-                ps.print(mkString)
-            }
-        catch {
-            case e: IOException ⇒ throw new NCE(s"Error writing file: $path", 
e)
-        }
+    def render(path: String): Unit = renderPrintStream(new PrintStream(path), 
path)
 
     /**
      * Renders this table to file.
      *
      * @param file File.
      */
-    def render(file: java.io.File): Unit =
+    def render(file: java.io.File): Unit = renderPrintStream(new 
PrintStream(file), file.getAbsolutePath)
+
+
+    private def renderPrintStream(f: => PrintStream, file: String): Unit =
         try
-            managed(new PrintStream(file)) acquireAndGet { ps ⇒
+            managed(f) acquireAndGet { ps ⇒
                 ps.print(mkString)
             }
         catch {
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCommandLine.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCommandLine.scala
index fdd76ab..26458cd 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCommandLine.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCommandLine.scala
@@ -17,6 +17,7 @@
 
 package org.apache.nlpcraft.model.tools.cmdline
 
+import org.apache.nlpcraft.common.ascii.NCAsciiTable
 import org.apache.nlpcraft.common.util.NCUtils
 import org.apache.nlpcraft.common.version.NCVersion
 
@@ -28,55 +29,156 @@ object NCCommandLine extends App {
 
     private final lazy val VER = NCVersion.getCurrent
     private final lazy val SCRIPT = NCUtils.sysEnv("NLPCRAFT_CLI_SCRIPT")
+    private final lazy val SCRIPT_NAME = SCRIPT.getOrElse("NLPCraft CLI")
 
     // Single CLI command.
     case class Command(
-        name: String,
-        desc: String,
+        names: Seq[String],
+        synopsis: String,
+        desc: String = "",
         params: Seq[Parameter] = Seq.empty,
-        examples: Seq[String] = Seq.empty,
-        body: (Seq[String]) => Unit
+        examples: Seq[Example] = Seq.empty,
+        body: Seq[String] => Unit
+    ) {
+        final val extNames = names.flatMap(name => // Safeguard against 
"common" errors.
+            Seq(
+                name,
+                s"-$name",
+                s"--$name",
+                s"/$name",
+                s"\\$name"
+            )
+        )
+    }
+    // Single command's example.
+    case class Example(
+        code: String,
+        desc: String
     )
     // Single command's parameter.
     case class Parameter(
         names: Seq[String],
-        optional: Boolean = false,
+        valueDesc: Option[String] = None,
+        arity: (Int, Int) = (1, 1), // Mandatory by default.
         desc: String
     )
 
     // All supported commands.
     private final val CMDS = Seq(
         Command(
-            name = "help",
-            desc = s"Displays manual page for $NAME.",
-            body = cmdHelp
+            names = Seq("help", "?"),
+            synopsis = s"Displays manual page for $SCRIPT_NAME.",
+            desc =
+                s"""
+                   |By default, without '-all' or '-cmd' parameters, displays 
the abbreviated form of manual
+                   |only listing the commands without parameters or examples.
+                   |""".stripMargin,
+            body = cmdHelp,
+            params = Seq(
+                Parameter(
+                    names = Seq("--cmd", "-c"),
+                    valueDesc = Some("{cmd}"),
+                    arity = (0, 3),
+                    desc = "Set of commands to show the manual for."
+                ),
+                Parameter(
+                    names = Seq("--all", "-a"),
+                    arity = (0, 1),
+                    desc = "Flag to show full manual for all commands."
+                )
+            )
         ),
         Command(
-            name = "version",
-            desc = s"Displays version of $NAME runtime.",
+            names = Seq("version", "ver"),
+            synopsis = s"Displays version of $SCRIPT_NAME runtime.",
             body = cmdVersion
         ),
         Command(
-            name = "repl",
-            desc = s"Starts '$NAME' in interactive REPL mode.",
+            names = Seq("repl"),
+            synopsis = s"Starts '$SCRIPT_NAME' in interactive REPL mode.",
             body = cmdRepl
         )
     )
 
-    private final val HELP_CMD = CMDS.find(_.name == "help").get
-    private final val DFLT_CMD = CMDS.find(_.name == "repl").get
+    private final val HELP_CMD = CMDS.find(_.names.contains("help")).get
+    private final val DFLT_CMD = CMDS.find(_.names.contains("repl")).get
 
     /**
      *
-     * @param params
+     * @param params Parameters, if any, for this command.
      */
     private def cmdHelp(params: Seq[String]): Unit = {
+        log(
+            s"""    |NAME
+                    |    $SCRIPT_NAME - command line interface to control 
NLPCraft.
+                    |
+                    |USAGE
+                    |    $SCRIPT_NAME COMMAND [PARAMETERS]
+                    |
+                    |COMMANDS""".stripMargin
+        )
+
+        if (params.isEmpty) {
+            val tbl = NCAsciiTable().margin(left = 4)
+
+            CMDS.foreach(cmd => tbl += (cmd.names.mkString(", "), 
cmd.synopsis))
+
+            log(tbl.toString)
+        }
+
+
 
+
+
+
+
+
+
+
+
+
+        //            |              |
+//              |    help
+//
+//        , ?
+//              |         Displays the manual.
+//              |
+//              |         PARAMETERS
+//              |             --cmd, -c={cmd}
+//              |                 Optional (zero or more).
+//              |                 Set of commands to show the manual for.
+//              |             --all, -a
+//              |                 Optional.
+//              |                 Flag to show manual for all commands.
+//              |         EXAMPLES
+//              |             $$ $SCRIPT_NAME help repl
+//              |                 Displays help for 'repl' command.
+//              |             $$ $SCRIPT_NAME help -all
+//              |                 Displays help for all commands.
+//              |
+//              |    version, ver
+//              |         Displays the version of $SCRIPT_NAME.
+//              |
+//              |    model-stub
+//              |         Generates JSON or YAML model stubs.
+//              |
+//              |         PARAMETERS
+//              |             --type, -t={json|yaml}
+//              |                 Mandatory.
+//              |             --output, -o={file-path}?
+//              |                 Optional.
+//              |         EXAMPLES
+//              |             $$ $SCRIPT_NAME model-stub --type=json 
--output=/home/user/model.js
+//              |                 Generates JSON model stub into 
'/home/user/model.js' file.
+//              |             $$ $SCRIPT_NAME model-stub -t=yaml
+//              |                 Generates YAML model stub into 'model.js' 
file.
+//              |""".stripMargin
+//        )
     }
 
     /**
      *
-     * @param params
+     * @param params Parameters, if any, for this command.
      */
     private def cmdRepl(params: Seq[String]): Unit = {
 
@@ -84,7 +186,7 @@ object NCCommandLine extends App {
 
     /**
      *
-     * @param params
+     * @param params Parameters, if any, for this command.
      */
     private def cmdVersion(params: Seq[String]): Unit = {
         // Nothing - common header with version will be printed before anyways.
@@ -92,13 +194,14 @@ object NCCommandLine extends App {
 
     private def error(msg: String = ""): Unit = System.err.println(msg)
     private def log(msg: String = ""): Unit = System.out.println(msg)
+
     private def errorHelp(): Unit = SCRIPT match {
         // Running from *.{s|cmd} script.
-        case Some(script) => error(s"Run '$script ${HELP_CMD.name}' to read 
the manual.")
+        case Some(script) => error(s"Run '$script ${HELP_CMD.names}' to read 
the manual.")
         // Running from IDE.
-        case None => error(s"Run the process with '${HELP_CMD.name}' parameter 
to read the manual.")
+        case None => error(s"Run the process with '${HELP_CMD.names}' 
parameter to read the manual.")
     }
-    
+
     /**
      *
      * @param args
@@ -115,18 +218,11 @@ object NCCommandLine extends App {
             NCCommandLine.DFLT_CMD.body(Seq.empty)
         else {
             val cmdName = args.head
-            val extCmdNames = Seq( // Safeguard against "common" errors.
-                cmdName,
-                s"-$cmdName",
-                s"--$cmdName",
-                s"/$cmdName",
-                s"\\$cmdName"
-            )
 
-            CMDS.find(c => extCmdNames.contains(c.name)) match {
-                case Some(cmd) =>
+            CMDS.find(_.extNames.contains(cmdName)) match {
+                case Some(cmd) => cmd.body(args.tail)
                 case None =>
-                    error(s"Unknown '$cmdName' command.")
+                    error(s"Unknown command: $cmdName")
                     errorHelp()
 
                     status = 1
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/common/ascii/NCAsciiTableSpec.scala
 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/common/ascii/NCAsciiTableSpec.scala
index 2b44d93..8081b9d 100644
--- 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/common/ascii/NCAsciiTableSpec.scala
+++ 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/common/ascii/NCAsciiTableSpec.scala
@@ -76,6 +76,6 @@ class NCAsciiTableSpec {
 
         val dur = System.currentTimeMillis() - start
 
-        println(s"Rendered in ${dur}msec.")
+        println(s"Rendered in ${dur}ms.")
     }
 }

Reply via email to