mridulm commented on code in PR #2699:
URL: https://github.com/apache/celeborn/pull/2699#discussion_r1733985029


##########
cli/src/main/scala/org/apache/celeborn/cli/common/CliLogging.scala:
##########
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.celeborn.cli.common
+
+import Console.{GREEN, RED, RESET}
+
+trait CliLogging {
+
+  def log(msg: String): Unit = {
+    Console.println(msg)
+  }
+
+  def logInfo(msg: String): Unit = {
+    Console.println(s"${RESET}${GREEN}${msg}")
+  }
+
+  def log(obj: Any): Unit = {
+    Console.println(obj)
+  }

Review Comment:
   nit: keep the `log` messages together



##########
cli/src/main/scala/org/apache/celeborn/cli/common/CliVersionProvider.scala:
##########
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.celeborn.cli.common
+
+import java.nio.file.{Files, Paths}
+
+import scala.io.Source
+import scala.util.matching.Regex
+
+import picocli.CommandLine.IVersionProvider
+
+class CliVersionProvider extends IVersionProvider with CliLogging {
+
+  override def getVersion: Array[String] = {
+    val versionFile = Paths.get(sys.env.getOrElse("CELEBORN_HOME", "") + 
"/RELEASE")
+    val prefix = "Celeborn CLI"
+    if (Files.exists(versionFile)) {
+      val versionPattern: Regex = """Celeborn\s+\S+""".r
+      val source = Source.fromFile(versionFile.toFile)
+      val fileContent = source.getLines().mkString(" ")
+      val version = versionPattern.findFirstIn(fileContent) match {
+        case Some(v) => Array(s"$prefix - $v")
+        case _ =>
+          logError(
+            "Could not resolve version of Celeborn since RELEASE file did not 
contain version info.")

Review Comment:
   Does this need to be an error ? (same for below)



##########
cli/src/main/scala/org/apache/celeborn/cli/common/CommonOptions.scala:
##########
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.celeborn.cli.common
+
+import picocli.CommandLine.{Command, Option, Spec}
+import picocli.CommandLine.Model.CommandSpec
+
+@Command
+class CommonOptions {
+
+  @Spec var spec: CommandSpec = _ // injected by picocli
+
+  @Option(
+    names = Array("--hostport"),
+    paramLabel = "host:port",
+    description = Array("The host and port"))
+  private[cli] var hostPort: String = _
+
+  @Option(
+    names = Array("--host-list"),
+    paramLabel = "h1,h2,h3...",
+    description = Array("List of hosts to pass to the command"))
+  private[cli] var hostList: String = _

Review Comment:
   QQ: What is expectation if there are multiple --host-list specified ? Will 
it give an error ? concat all of them ?



##########
cli/src/main/scala/org/apache/celeborn/cli/common/CliVersionProvider.scala:
##########
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.celeborn.cli.common
+
+import java.nio.file.{Files, Paths}
+
+import scala.io.Source
+import scala.util.matching.Regex
+
+import picocli.CommandLine.IVersionProvider
+
+class CliVersionProvider extends IVersionProvider with CliLogging {
+
+  override def getVersion: Array[String] = {
+    val versionFile = Paths.get(sys.env.getOrElse("CELEBORN_HOME", "") + 
"/RELEASE")
+    val prefix = "Celeborn CLI"
+    if (Files.exists(versionFile)) {
+      val versionPattern: Regex = """Celeborn\s+\S+""".r
+      val source = Source.fromFile(versionFile.toFile)
+      val fileContent = source.getLines().mkString(" ")

Review Comment:
   We dont need to concat all the lines together.
   Use `source.getLines().find` to find the first line matching the pattern.



##########
cli/src/main/scala/org/apache/celeborn/cli/config/CliConfigManager.scala:
##########
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.celeborn.cli.config
+
+import java.io.{File, PrintWriter}
+
+import scala.io.Source
+
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.module.scala.DefaultScalaModule
+
+import org.apache.celeborn.cli.config.CliConfigManager.cliConfigFilePath
+
+case class CliConfig(@JsonProperty("cliConfigData") cliConfigData: Map[String, 
String])
+
+object CliConfigManager {
+  val cliConfigFilePath = s"${sys.env.getOrElse("CELEBORN_CONF_DIR", 
"HOME")}/celeborn-cli.conf"
+}
+
+class CliConfigManager {
+
+  private val mapper = new ObjectMapper().registerModule(DefaultScalaModule)

Review Comment:
   Move `mapper` to object



##########
cli/src/main/scala/org/apache/celeborn/cli/config/CliConfigManager.scala:
##########
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.celeborn.cli.config
+
+import java.io.{File, PrintWriter}
+
+import scala.io.Source
+
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.module.scala.DefaultScalaModule
+
+import org.apache.celeborn.cli.config.CliConfigManager.cliConfigFilePath
+
+case class CliConfig(@JsonProperty("cliConfigData") cliConfigData: Map[String, 
String])
+
+object CliConfigManager {
+  val cliConfigFilePath = s"${sys.env.getOrElse("CELEBORN_CONF_DIR", 
"HOME")}/celeborn-cli.conf"
+}
+
+class CliConfigManager {
+
+  private val mapper = new ObjectMapper().registerModule(DefaultScalaModule)
+  def loadConfig(): Option[CliConfig] = {
+    val file = new File(cliConfigFilePath)
+    if (!file.exists()) {
+      None
+    } else {
+      try {
+        val source = Source.fromFile(cliConfigFilePath)
+        val jsonString = source.getLines().mkString
+        source.close()
+        Some(mapper.readValue(jsonString, classOf[CliConfig]))

Review Comment:
   We have this repeated pattern here:
   ```
   val source = Source.fromFile(name) // some closeable
   // processing source
   source.close() // close once done
   ```
   
   We can add a `Utils.tryWithResources`:
   ```
   def tryWithResources[R <: Closeable, U](f: => R)(func: R => U): U = {
     val res = f
     try {
       func(f)
     } finally {
       if (null != res) {
         res.close()
       }
     }
   }
   ```
   
   This will result in:
   
   ```suggestion
           Utils.tryWithResources(Source.fromFile(cliConfigFilePath)) { source 
=>
             val jsonString = source.getLines().mkString
             Some(mapper.readValue(jsonString, classOf[CliConfig]))
           }
   ```



##########
cli/src/main/scala/org/apache/celeborn/cli/config/CliConfigManager.scala:
##########
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.celeborn.cli.config
+
+import java.io.{File, PrintWriter}
+
+import scala.io.Source
+
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.module.scala.DefaultScalaModule
+
+import org.apache.celeborn.cli.config.CliConfigManager.cliConfigFilePath
+
+case class CliConfig(@JsonProperty("cliConfigData") cliConfigData: Map[String, 
String])
+
+object CliConfigManager {

Review Comment:
   It is not clear to me who manages the config file that `CliConfigManager` is 
using.
   If it is end user - what is the schema they are expecting ?
   If it is CLI tool - typically, the celeborn deployment directory will be 
read only - so how is this expected to be created/updated



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to