Permalink
Browse files

Refactor all.

  • Loading branch information...
1 parent 85ffcf0 commit c44d02a75f1098988395e6fcada23f25ac6a3796 @zhongl zhongl committed Jun 2, 2012
Showing with 383 additions and 2,285 deletions.
  1. +202 −0 LICENSE.txt
  2. +0 −91 agent/src/main/java/com/github/zhongl/housemd/Options.java
  3. +0 −43 agent/src/test/scala/com/github/zhongl/housemd/AgentSpec.scala
  4. +0 −48 agent/src/test/scala/com/github/zhongl/housemd/OptionsSpec.scala
  5. +0 −36 cmdl/src/main/scala/com/github/zhongl/command/Application.scala
  6. +0 −145 cmdl/src/main/scala/com/github/zhongl/command/Command.scala
  7. +0 −30 cmdl/src/main/scala/com/github/zhongl/command/Converters.scala
  8. +0 −23 cmdl/src/main/scala/com/github/zhongl/command/ConvertingException.scala
  9. +0 −23 cmdl/src/main/scala/com/github/zhongl/command/MissingParameterException.scala
  10. +0 −38 cmdl/src/main/scala/com/github/zhongl/command/PrintOut.scala
  11. +0 −104 cmdl/src/main/scala/com/github/zhongl/command/Shell.scala
  12. +0 −60 cmdl/src/main/scala/com/github/zhongl/command/Suite.scala
  13. +0 −38 cmdl/src/main/scala/com/github/zhongl/command/SuiteAppcation.scala
  14. +0 −23 cmdl/src/main/scala/com/github/zhongl/command/UnknownOptionException.scala
  15. +0 −63 cmdl/src/test/scala/com/github/zhongl/command/ApplicationSpec.scala
  16. +0 −180 cmdl/src/test/scala/com/github/zhongl/command/CommandSpec.scala
  17. +0 −97 cmdl/src/test/scala/com/github/zhongl/command/ShellSpec.scala
  18. +0 −48 cmdl/src/test/scala/com/github/zhongl/command/SuiteSpec.scala
  19. +0 −119 console/src/main/scala/com/github/zhongl/housemd/cli/Commands.scala
  20. +0 −55 console/src/main/scala/com/github/zhongl/housemd/cli/Completers.scala
  21. +0 −63 console/src/main/scala/com/github/zhongl/housemd/cli/Console.scala
  22. +0 −28 console/src/main/scala/com/github/zhongl/housemd/cli/Output.scala
  23. +0 −30 console/src/main/scala/com/github/zhongl/housemd/cli/VirtualMachine.scala
  24. +0 −29 console/src/main/scala/com/github/zhongl/housemd/cli/annotation/Argument.java
  25. +0 −30 console/src/main/scala/com/github/zhongl/housemd/cli/annotation/Command.java
  26. +0 −29 console/src/main/scala/com/github/zhongl/housemd/cli/annotation/Option.java
  27. +0 −30 console/src/main/scala/com/github/zhongl/housemd/cli/package.scala
  28. +0 −106 console/src/main/scala/com/github/zhongl/housemd/closures/Closure.scala
  29. +0 −49 console/src/main/scala/com/github/zhongl/housemd/closures/ClosureExecutor.scala
  30. +0 −65 console/src/main/scala/com/github/zhongl/housemd/closures/Loaded.scala
  31. +0 −26 console/src/main/scala/com/github/zhongl/housemd/logging/Level.scala
  32. +0 −50 console/src/main/scala/com/github/zhongl/housemd/logging/Loggable.scala
  33. +0 −170 console/src/test/scala/com/github/zhongl/housemd/cli/CommandsSpec.scala
  34. +0 −29 console/src/test/scala/com/github/zhongl/housemd/cli/NoneCompleter.scala
  35. +0 −59 console/src/test/scala/com/github/zhongl/housemd/closures/ListMapByPatternTest.scala
  36. +0 −74 console/src/test/scala/com/github/zhongl/housemd/closures/LoadedSpec.scala
  37. +0 −68 console/src/test/scala/com/github/zhongl/housemd/logging/AssertLog.scala
  38. +26 −56 project/Build.scala
  39. 0 {console → }/src/main/scala/com/github/zhongl/housemd/Advice.java
  40. +18 −15 {agent/src/main/java → src/main/scala}/com/github/zhongl/housemd/Agent.java
  41. 0 {console → }/src/main/scala/com/github/zhongl/housemd/ClassDecorator.scala
  42. 0 {console → }/src/main/scala/com/github/zhongl/housemd/Context.scala
  43. 0 {console → }/src/main/scala/com/github/zhongl/housemd/DetailWriter.scala
  44. +1 −1 {console → }/src/main/scala/com/github/zhongl/housemd/Duck.scala
  45. +3 −2 {console → }/src/main/scala/com/github/zhongl/housemd/HouseMD.scala
  46. +77 −0 src/main/scala/com/github/zhongl/housemd/Loaded.scala
  47. 0 {console → }/src/main/scala/com/github/zhongl/housemd/Reflections.scala
  48. 0 {console → }/src/main/scala/com/github/zhongl/housemd/StackWriter.scala
  49. +3 −3 {console → }/src/main/scala/com/github/zhongl/housemd/Trace.scala
  50. 0 {console → }/src/main/scala/com/github/zhongl/housemd/Utils.scala
  51. +52 −0 src/test/scala/com/github/zhongl/housemd/LoadedSpec.scala
  52. 0 {console → }/src/test/scala/com/github/zhongl/housemd/ReflectionsSpec.scala
  53. +1 −9 {console → }/src/test/scala/com/github/zhongl/housemd/TraceSpec.scala
  54. 0 {console → }/src/test/scala/com/github/zhongl/housemd/UtilsTest.scala
View
202 LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
View
91 agent/src/main/java/com/github/zhongl/housemd/Options.java
@@ -1,91 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl</a>
- */
-class Options {
- private final Map<String, String> map;
-
- private Options(Map<String, String> map) {
- this.map = map;
- }
-
- public static Options parse(String arguments) {
- final Map<String, String> map = new HashMap<String, String>();
- for (String option : arguments.split("\\s+")) {
- String[] pair = option.split("=");
- map.put(pair[0], pair[1]);
- }
- return new Options(map);
- }
-
- /**
- * @return urls for URLClassLoader to find classes.
- * @see java.net.URLClassLoader
- */
- public URL[] classLoaderUrls() {
- String value = map.get("class.loader.urls");
- String[] split = value.split(":");
- Set<URL> urls = new HashSet<URL>();
- try {
- for (String path : split) {
- urls.add(new File(path).toURI().toURL());
- }
- return urls.toArray(new URL[urls.size()]);
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * @return closure executor class full name.
- * @see Class#getName()
- */
- public String mainClass() {
- return map.get("closure.executor.name");
- }
-
- /**
- * @return address string, eg: "localhost:54321"
- */
- public String consoleAddress() {
- return map.get("console.address");
- }
-
- /**
- * @return true if you want gc all useless classes loaded by last.
- * @see System#gc()
- */
- public boolean gcAtBeginning() {
- // having value means turn on this option
- return map.containsKey("gc.at.beginning");
- }
-
- public boolean debug() {
- return map.containsKey("debug");
- }
-}
View
43 agent/src/test/scala/com/github/zhongl/housemd/AgentSpec.scala
@@ -1,43 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd
-
-import org.scalatest.FunSpec
-import instrument.Instrumentation
-import java.util.concurrent.{TimeUnit, CountDownLatch}
-
-class AgentSpec extends FunSpec {
- describe("Agent") {
- it("should start closure executor") {
- val arguments = "a.jar com.github.zhongl.housemd.MockExecutor 54321"
-
- Agent.agentmain(arguments, null)
-
- Flag.latch.await(1L, TimeUnit.SECONDS)
- }
- }
-}
-
-object Flag {
- val latch = new CountDownLatch(1)
-}
-
-class MockExecutor(port: Int, inst: Instrumentation) extends Runnable {
- def run() {
- Flag.latch.countDown()
- }
-}
View
48 agent/src/test/scala/com/github/zhongl/housemd/OptionsSpec.scala
@@ -1,48 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd
-
-import org.scalatest.FunSpec
-import org.scalatest.matchers.ShouldMatchers
-import java.io.File
-
-class OptionsSpec extends FunSpec with ShouldMatchers {
-
- val options = Options.parse(
- """class.loader.urls=a.jar:b.jar
- closure.executor.name=com.github.zhongl.housemd.Executor
- console.address=localhost:54321"""
- )
-
- def url(s: String) = new File(s).toURI.toURL
-
- describe("Options") {
- it("should get class loader urls") {
- options.classLoaderUrls() should {
- contain(url("a.jar")) and contain(url("b.jar")) and have size (2)
- }
- }
-
- it("should get closure executor name") {
- options.mainClass() should be("com.github.zhongl.housemd.Executor")
- }
-
- it("should get console address") {
- options.consoleAddress() should be("localhost:54321")
- }
- }
-}
View
36 cmdl/src/main/scala/com/github/zhongl/command/Application.scala
@@ -1,36 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-/**
-* @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
-*/
-trait Application {self: Command =>
-
- private val printHelp = flag("-h" :: "--help" :: Nil, "show help infomation of this command.")
-
- def main(arguments: Array[String]) {
- try {
- parse(arguments)
- if (printHelp()) println(help) else run()
- } catch {
- case UnknownOptionException(option) => println("Unknown option: " + option)
- case MissingParameterException(parameter) => println("Missing parameter: " + parameter)
- case ConvertingException(id, value, explain) => println("Invalid " + id + " value: " + value + explain)
- }
- }
-}
View
145 cmdl/src/main/scala/com/github/zhongl/command/Command.scala
@@ -1,145 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-import collection.mutable.{ListBuffer, Map}
-import annotation.tailrec
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-abstract class Command(val name: String, val description: String, val out: PrintOut) extends Runnable {
-
- private val options = ListBuffer.empty[Option[_]]
- private val parameters = ListBuffer.empty[Parameter[_]]
- private val values = Map.empty[String, String]
- private val CR = System.getProperty("line.separator")
-
- implicit private val enhanceBoolean = (b: Boolean) => new {def ?(t: => String, f: => String = "") = if (b) t else f}
-
- def help = "Usage: " + name +
- !options.isEmpty ? (" [OPTIONS]") +
- !parameters.isEmpty ? parameters.map(_.repr).mkString(" ", " ", "") +
- "\n\t" + description +
- !options.isEmpty ? ("\nOptions:\n" + options.mkString("\n")) +
- !parameters.isEmpty ? ("\nParameters:\n" + parameters.mkString("\n"))
-
- def parse(arguments: Array[String]) {
-
- @tailrec
- def read(list: List[String])(implicit index: Int = 0) {
- list match {
- case head :: tail if (head.matches("-[a-zA-Z-]+")) => read(addOption(head, tail))
- case head :: tail => read(addParameter(index, list))(index + 1)
- case Nil => // end recusive
- }
- }
-
- read(arguments.toList)
- }
-
- protected final def info(s: Any) { println("INFO: " + s) }
-
- protected final def warn(s: Any) { println("WARN: " + s) }
-
- protected final def error(s: Any) { println("ERROR: " + s) }
-
- protected final def print(a: Any) { out.print(a.toString) }
-
- protected final def println() { print(CR) }
-
- protected final def println(a: Any) { print(a.toString + CR) }
-
- protected final def flag(names: List[String], description: String) =
- option[Boolean](names, description, false)(manifest[Boolean], Converters.string2Boolean)
-
- protected final def option[T](names: List[String], description: String, defaultValue: T)
- (implicit m: Manifest[T], convert: String => T) = {
-
- checkIllegalOption(names)
- checkDuplicatedOption(names)
- options += Option[T](names, description, defaultValue)
- () => eval(names(0), Some(defaultValue))
- }
-
- protected final def parameter[T](name: String, description: String, defaultValue: scala.Option[T] = None)
- (implicit m: Manifest[T], convert: String => T) = {
- checkDuplicatedParameter(name)
- parameters += Parameter[T](name, description, defaultValue.isDefined)
- () => eval(name, defaultValue)
- }
-
- private def checkIllegalOption(names: List[String]) {
- if (names.isEmpty) throw new IllegalArgumentException("At least one name should be given to option.")
- names find (!_.startsWith("-")) match {
- case Some(n) => throw new IllegalArgumentException(n + " should starts with '-'.")
- case None => // ignore
- }
- }
-
- private def checkDuplicatedParameter(s: String) {
- if (parameters.find(_.name == name).isDefined) throw new IllegalStateException(s + " have already been used")
- }
-
- private def checkDuplicatedOption[T](names: scala.List[String]) {
- options.find(_.names.intersect(names).size > 0) match {
- case Some(option) => throw new IllegalStateException(names + " have already been used in " + option.names)
- case None => // ignore
- }
- }
-
- private def addOption(name: String, rest: List[String]) = options find (_.names.contains(name)) match {
- case Some(option) if option.isFlag => values(option.names(0)) = "true"; rest
- case Some(option) => values(option.names(0)) = rest.head; rest.tail
- case None => throw new UnknownOptionException(name)
- }
-
- private def addParameter(index: Int, arguments: List[String]) = parameters(index) match {
- case p if p.isVarLength => values(p.name) = arguments.mkString(" "); Nil
- case p => values(p.name) = arguments.head; arguments.tail
- }
-
- private def eval[T](name: String, defaultValue: scala.Option[T])
- (implicit convert: String => T) = values get name match {
- case None => defaultValue.getOrElse {throw MissingParameterException(name)}
- case Some(value) => try {convert(value)} catch {
- case t: Throwable => throw ConvertingException(name, value, t.getMessage)
- }
- }
-
-
- case class Option[T: Manifest](names: List[String], description: String, defaultValue: T) {
- override def toString = {
- val isNotFlag = !isFlag
-
- "\t" + names.mkString(", ") + isNotFlag ? ("=[" + manifest[T].erasure.getSimpleName.toUpperCase + "]") +
- "\n\t\t" + description +
- isNotFlag ? ("\n\t\tdefault: " + defaultValue)
- }
-
- def isFlag = manifest[T].erasure == classOf[Boolean]
- }
-
- case class Parameter[T: Manifest](name: String, description: String, optional: Boolean) {
- override def toString = "\t" + name + "\n\t\t" + description
-
- def repr = { val s = isVarLength ?(name + "...", name); optional ?("[" + s + "]", s) }
-
- def isVarLength = manifest[T].erasure.isArray
- }
-
-}
View
30 cmdl/src/main/scala/com/github/zhongl/command/Converters.scala
@@ -1,30 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-import java.util.regex.Pattern
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-
-object Converters {
- implicit val string2Int = (_: String).toInt
- implicit val string2Boolean = (_: String).toBoolean
- implicit val string2Array = (_: String).split("\\s+")
- implicit val string2Pattern = Pattern.compile(_: String)
-}
View
23 cmdl/src/main/scala/com/github/zhongl/command/ConvertingException.scala
@@ -1,23 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-
-case class ConvertingException(name: String, value: String, explain: String) extends Exception
View
23 cmdl/src/main/scala/com/github/zhongl/command/MissingParameterException.scala
@@ -1,23 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-
-case class MissingParameterException(name: String) extends Exception
View
38 cmdl/src/main/scala/com/github/zhongl/command/PrintOut.scala
@@ -1,38 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-import java.io.OutputStream
-import jline.console.ConsoleReader
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-
-object PrintOut {
- def apply(out: OutputStream) = new PrintOut {
- def print(a: Any) { out.write(a.toString.getBytes); out.flush() }
- }
-
- def apply(cr: ConsoleReader) = new PrintOut {
- def print(a: Any) { cr.print(a.toString); cr.flush() }
- }
-}
-
-trait PrintOut {
- def print(a: Any)
-}
View
104 cmdl/src/main/scala/com/github/zhongl/command/Shell.scala
@@ -1,104 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-import jline.console.ConsoleReader
-import annotation.tailrec
-import java.util.List
-import jline.console.completer.{NullCompleter, Completer}
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-abstract class Shell(
- name: String,
- description: String,
- reader: ConsoleReader = new ConsoleReader(System.in, System.out))
- extends Command(name, description, PrintOut(reader)) with Suite {
-
- final def main(arguments: Array[String]) { interact() }
-
- override final def run() {}
-
- protected def prompt: String = name + "> "
-
- override protected def decorate(list: String) = "\n" + list + "\n"
-
- private def interact() {
- reader.setPrompt(prompt)
- reader.addCompleter(DefaultCompleter)
-
- @tailrec
- def parse(line: String) {
- if (line == null) return
- val array = line.trim.split("\\s+")
- try {
- run(array.head, array.tail) { name => println("Unknown command: " + name) }
- } catch {
- case e: QuitException => return
- }
- parse(reader.readLine())
- }
-
- parse(reader.readLine())
- }
-
- object Quit extends Command("quit", "terminate the process.", PrintOut(reader)) {
- def run() { throw new QuitException }
- }
-
- class QuitException extends Exception
-
- trait CommandCompleter extends Completer {
-
- import collection.JavaConversions._
-
- private val RE0 = """\s+""".r
- private val RE1 = """\s*(\w+)""".r
- private val RE2 = """\s*(\w+)(.+)""".r
-
- def complete(buffer: String, cursor: Int, candidates: List[CharSequence]) = buffer match {
- case null | RE0() => candidates.addAll(commandNames); cursor
- case RE1(p) => candidates.addAll(commandNamesStartsWith(p)); cursor - p.length
- case RE2(n, p) => argumentComplete(n, p, cursor, candidates)
- }
-
- protected def argumentComplete(name: String, prefix: String, cursor: Int, candidates: List[CharSequence]): Int
-
- private def commandNamesStartsWith(prefix: String): List[_ <: CharSequence] =
- commands.collect { case cl if cl.name.startsWith(prefix) => cl.name }.sorted
-
- private def commandNames: List[_ <: CharSequence] = commands.map(_.name).sorted
- }
-
- object HelpCompleter extends CommandCompleter {
- protected def argumentComplete(name: String, prefix: String, cursor: Int, candidates: List[CharSequence]) = -1
- }
-
- object DefaultCompleter extends CommandCompleter {
-
- protected def argumentComplete(name: String, prefix: String, cursor: Int, candidates: List[CharSequence]) =
- completerOfCommand(name).complete(prefix, cursor, candidates)
-
- private def completerOfCommand(name: String): Completer = commands find {_.name == name} match {
- case Some(c) if c.isInstanceOf[Completer] => c.asInstanceOf[Completer]
- case Some(c) if c == helpCommand => HelpCompleter
- case _ => NullCompleter.INSTANCE
- }
- }
-
-}
View
60 cmdl/src/main/scala/com/github/zhongl/command/Suite.scala
@@ -1,60 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-trait Suite {self: Command =>
-
- protected lazy val helpCommand = new Command("help", "display this infomation.", self.out) {
-
- private val command = parameter[String]("command", "sub command name.", Some("*"))
-
- private lazy val length = (name.length :: commands.map(_.name.length)).max
- private lazy val pattern = "%1$-" + length + "s\t%2$s\n"
-
- def list = commands.foldLeft[String]("") { (a, c) => a + pattern.format(c.name, c.description) }
-
- def helpOf(name: String) = commands find (_.name == name) match {
- case Some(c) => c.help + "\n"
- case None => throw new IllegalArgumentException("Unknown command: " + name)
- }
-
- def run() {
- try {
- print(command() match {
- case "*" => decorate(list)
- case cmd => helpOf(cmd)
- })
- } catch {case e: IllegalArgumentException => println(e.getMessage) }
- }
- }
-
- def run(command: String, arguments: Array[String])(handleUnknown: String => Unit) {
- commands find {_.name == command} match {
- case Some(c) => c.parse(arguments); c.run()
- case None => handleUnknown(command)
- }
- }
-
- protected def commands: List[Command]
-
- protected def decorate(list: String): String
-
-}
View
38 cmdl/src/main/scala/com/github/zhongl/command/SuiteAppcation.scala
@@ -1,38 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-import Converters._
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-abstract class SuiteAppcation(name: String, description: String, out: PrintOut)
- extends Command(name, description, out) with Suite with Application {
-
- private val command = parameter[String]("command", "sub command name.")
- private val arguments = parameter[Array[String]]("arguments", "sub command arguments.", Some(Array()))
-
- override def run() {
- run(command(), arguments()) { name => println("Unknown command: " + name) }
- }
-
- override def help = decorate(helpCommand.list)
-
- override protected def decorate(list: String) = super.help + "\nCommands:\n" + list
-
-}
View
23 cmdl/src/main/scala/com/github/zhongl/command/UnknownOptionException.scala
@@ -1,23 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-
-case class UnknownOptionException(name: String) extends Exception
View
63 cmdl/src/test/scala/com/github/zhongl/command/ApplicationSpec.scala
@@ -1,63 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-import org.scalatest.FunSpec
-import org.scalatest.matchers.ShouldMatchers
-import java.io.{OutputStream, ByteArrayOutputStream}
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-
-class ApplicationSpec extends FunSpec with ShouldMatchers {
-
- class Base(out: OutputStream) extends Command("App", "desc", PrintOut(out)) with Application {
-
- val param = parameter[String]("param", "parameter")(manifest[String], { value: String =>
- if (value.contains("@")) value else throw new IllegalArgumentException(", it should contains @")
- })
-
- def run() {}
- }
-
- val help = """Usage: App [OPTIONS] param
- | desc
- |Options:
- | -h, --help
- | show help infomation of this command.
- |Parameters:
- | param
- | parameter""".stripMargin.replaceAll(" ", "\t") + "\n"
-
- describe("Application") {
-
- it("should print help by short option") {
- val bout = new ByteArrayOutputStream()
- val app = new Base(bout)
- app main (Array("-h"))
- bout.toString should be(help)
- }
-
- it("should print help by long option") {
- val bout = new ByteArrayOutputStream()
- val app = new Base(bout)
- app main (Array("--help"))
- bout.toString should be(help)
- }
- }
-}
View
180 cmdl/src/test/scala/com/github/zhongl/command/CommandSpec.scala
@@ -1,180 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-import org.scalatest.FunSpec
-import org.scalatest.matchers.ShouldMatchers
-import java.io.File
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-
-class CommandSpec extends FunSpec with ShouldMatchers {
-
- import Converters._
-
- abstract class Base extends Command("app name","some description", PrintOut(System.out)) {
-
- def run() {}
-
- def main(arguments: Array[String]) {
- parse(arguments)
- }
- }
-
- describe("Command") {
-
- it("should parse parameters") {
- val command = new Base {
- val param1 = parameter[Int]("param1", "param1 description")
- val param2 = parameter[String]("param2", "param2 description")
- }
-
- command main ("123 allen".split("\\s+"))
- command param1() should be(123)
- command param2() should be("allen")
- }
-
- it("should support var length paramters") {
- val command = new Base {
- val param1 = parameter[Int]("param1", "param1 description")
- val param2 = parameter[Array[String]]("param2", "param2 description")
- }
-
- command main ("123 allen john".split("\\s+"))
- command param1() should be(123)
- command param2() should be(Array("allen", "john"))
- }
-
- it("should support optional parameter") {
- val command = new Base {
- val param = parameter[String]("param", "desc", Some(""))
- }
-
- command main (Array())
- command param() should be("")
- }
-
- ignore("should support POSIX-style short options") {
- val command = new Base {
- val flag1 = flag("-f" :: Nil, "enable flag1")
- val flag2 = flag("-F" :: Nil, "enable flag2")
- }
-
- command main ("-fF".split("\\s+"))
- command flag1() should be(true)
- command flag2() should be(true)
- }
-
- it("should support GNU-style long option") {
- val command = new Base {
- val flag0 = flag("--flag" :: Nil, "enable flag")
- }
-
- command main ("--flag".split("\\s+"))
- command flag0() should be(true)
- }
-
- it("should support single-value option") {
- val command = new Base {
- val singleValue = option[String]("--single-value" :: Nil, "set single value", "default")
- }
-
- command main ("--single-value v".split("\\s+"))
- command singleValue() should be("v")
- }
-
- it("should get help info") {
- val command = new Base {
- val flag0 = flag("-f" :: "--flag" :: Nil, "enable flag")
- val singleValue = option[String]("--single-value" :: Nil, "set single value", "v")
- val param1 = parameter[String]("param1", "set param1")
- val param2 = parameter[String]("param2", "set param2")
- }
-
- command.help should be(
- """Usage: app name [OPTIONS] param1 param2
- | some description
- |Options:
- | -f, --flag
- | enable flag
- | --single-value=[STRING]
- | set single value
- | default: v
- |Parameters:
- | param1
- | set param1
- | param2
- | set param2""".stripMargin.replaceAll(" ", "\t"))
- }
-
- it("should get help without options and parameters") {
- val command = new Base {}
-
- command.help should be(
- """Usage: app name
- | some description""".stripMargin.replaceAll(" ", "\t"))
- }
-
- it("should get help indicate var-length optional parameter") {
- val command = new Base {
- val param = parameter[Array[String]]("param", "var-length optional param", Some(Array()))
- }
- command.help should be(
- """Usage: app name [param...]
- | some description
- |Parameters:
- | param
- | var-length optional param""".stripMargin.replaceAll(" ", "\t"))
-
- }
-
- it("should complain unknown option") {
- val command = new Base {}
-
- val exception = evaluating {command main ("-u".split("\\s+"))} should produce[UnknownOptionException]
- exception.name should be("-u")
- }
-
- it("should complain missing parameter") {
- val command = new Base {
- val param = parameter[String]("param", "set param")
- }
- command main (Array())
- val exception = evaluating {command param()} should produce[MissingParameterException]
- exception.name should be("param")
- }
-
- it("should complain converting error") {
- val command = new Base {
- implicit val toFile = {
- value: String =>
- val file = new File(value)
- if (file.exists()) file else throw new IllegalArgumentException(", it should be an existed file")
- }
- val file = option[File]("--file" :: Nil, "set a file", new File("default"))
- }
- command main ("--file nonexist".split("\\s+"))
- val exception = evaluating {command file()} should produce[ConvertingException]
- exception.name should be("--file")
- exception.value should be("nonexist")
- exception.explain should be(", it should be an existed file")
- }
- }
-
-}
View
97 cmdl/src/test/scala/com/github/zhongl/command/ShellSpec.scala
@@ -1,97 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-import org.scalatest.FunSpec
-import org.scalatest.matchers.ShouldMatchers
-import java.io.{OutputStream, ByteArrayInputStream, PrintStream, ByteArrayOutputStream}
-import jline.console.ConsoleReader
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-class ShellSpec extends FunSpec with ShouldMatchers {
-
- class AShell(line: String, out: OutputStream) extends Shell(
- name = "shell",
- description = "a shell example",
- reader = new ConsoleReader(new ByteArrayInputStream(line.getBytes), new PrintStream(out))) {
- protected def commands = helpCommand :: Quit :: Nil
- }
-
- private val backspace = "\u001B[K"
-
- private def moveCursor(i: Int) = "\u001B[" + i + "G"
-
- describe("Shell") {
-
- it("should get help") {
- val bout = new ByteArrayOutputStream()
- val shell = new AShell("help\n", bout)
- shell main (Array())
- bout.toString should be(
- """shell> help
- |
- |help display this infomation.
- |quit terminate the process.
- |
- |shell> """.stripMargin)
- }
-
- it("should complete help command") {
- val bout = new ByteArrayOutputStream()
- val shell = new AShell("h\t", bout)
- shell main (Array())
- bout.toString should be("shell> h" + moveCursor(8) + backspace + "help")
- }
-
- it("should complete help command argument") {
- val bout = new ByteArrayOutputStream()
- val shell = new AShell("help q\t", bout)
- shell main (Array())
- bout.toString should be("shell> help q" + moveCursor(13) + backspace + "quit")
- }
-
- it("should complete nothing") {
- val bout = new ByteArrayOutputStream()
- val shell = new AShell("help help a\t", bout)
- shell main (Array())
- bout.toString should be("shell> help help a")
- }
-
- it("should complain unknown command name") {
- val bout = new ByteArrayOutputStream()
- val shell = new AShell("unknow\n", bout)
- shell main (Array())
- bout.toString should be(
- """shell> unknow
- |Unknown command: unknow
- |shell> """.stripMargin)
- }
-
- it("should complain unknown command name in help") {
- val bout = new ByteArrayOutputStream()
- val shell = new AShell("help unknow\n", bout)
- shell main (Array())
- bout.toString should be(
- """shell> help unknow
- |Unknown command: unknow
- |shell> """.stripMargin)
- }
- }
-
-}
View
48 cmdl/src/test/scala/com/github/zhongl/command/SuiteSpec.scala
@@ -1,48 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.command
-
-import org.scalatest.FunSpec
-import org.scalatest.matchers.ShouldMatchers
-import java.io.{OutputStream, ByteArrayOutputStream}
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-class SuiteSpec extends FunSpec with ShouldMatchers {
-
- class ACommand(out: PrintOut) extends Command("cmd", "example.", out) {
- def run() {}
- }
-
- class ASuiteAppcation(os: OutputStream)
- extends SuiteAppcation(name = "acs", description = "A command suite", out = PrintOut(os))
- with Application {
- override protected lazy val commands = helpCommand :: new ACommand(out) :: Nil
- }
-
- describe("Suite Application") {
-
- it("should get help") {
- val bout = new ByteArrayOutputStream()
- val acs = new ASuiteAppcation(bout)
- acs main ("help cmd".split("\\s+"))
- bout.toString should be("Usage: cmd\n\texample.\n")
- }
- }
-
-}
View
119 console/src/main/scala/com/github/zhongl/housemd/cli/Commands.scala
@@ -1,119 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.cli
-
-import java.lang.reflect.Method
-import collection.JavaConversions._
-import com.github.zhongl.housemd.logging.Loggable
-import com.github.zhongl.housemd.Reflections._
-import jline.console.completer.Completer
-import java.util.{SortedSet, List}
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-abstract class Commands(commandObjects: AnyRef*) extends Loggable with Completer {
-
- protected val name2Command = {
- val map = scala.collection.mutable.Map.empty[String, Command]
- commandObjects.toList ::: Quit :: Help :: Nil foreach { instance =>
- commandMethodOf(instance) match {
- case None => warn("Skip invalid command {}", instance)
- case Some(method) =>
- val name = instance.getClass.getAnnotation(classOf[annotation.Command]).name()
- map += (name -> new Command(name, method, instance))
- }
- }
- map.toMap
- }
-
- protected val commandNames = new java.util.TreeSet[String](name2Command.keySet)
-
- def execute(name: String, arguments: String*) {
- name2Command get name match {
- case None => warn("Unknown command {}", name)
- case Some(command) => command.apply(arguments)
- }
- }
-
- def commands: SortedSet[String] = commandNames
-
- def command(name: String): Option[Command] = name2Command get name
-
- private[this] def commandMethodOf(instance: AnyRef) = instance.getClass.getMethods find {_.getName == "apply"}
-
- class Command(name: String, method: Method, instance: AnyRef) extends (Seq[String] => Unit) with Completer {
- private lazy val completer = {
- if (instance.isInstanceOf[Completer]) instance.asInstanceOf[Completer]
- else new Completer {
- def complete(buffer: String, cursor: Int, candidates: List[CharSequence]) = -1
- }
- }
-
- def apply(argStrings: Seq[String]) {
- try invoke(parse(argStrings)) catch {
- case e: IllegalArgumentException => warn(e.getMessage); Help.apply(name) //; throw e
- case e: Throwable => warn(e.getMessage) //; throw e
- }
- }
-
- def complete(buffer: String, cursor: Int, candidates: List[CharSequence]) =
- completer.complete(buffer, cursor, candidates)
-
-
- private[this] def invoke(arguments: Seq[AnyRef]) {
- method.invoke(instance, arguments: _*)
- }
-
- private[this] def parse(argStrings: Seq[String]): Seq[AnyRef] = {
- val classes = method.getParameterTypes
- if (argStrings.size != classes.size) throw new IllegalArgumentException("Miss match argument")
- classes zip argStrings map { t => convert(t._1, t._2) }
- }
-
- }
-
- @command(name = "help", description = "show help infomation of one command or all commands")
- object Help extends FirstArgumentCompleter {
-
- def apply(@argument(name = "command", description = "command name") command: String = "") {
- command match {
- case "" => list()
- case _ => usage(command)
- }
- }
-
- protected def allCandidates = commands
-
- private[this] def list() {
- // TODO
- }
-
- private[this] def usage(command: String) {
- // TODO
- }
-
- }
-
- @command(name = "quit", description = "quit the console")
- object Quit {
- def apply() {}
- }
-
-}
-
-
View
55 console/src/main/scala/com/github/zhongl/housemd/cli/Completers.scala
@@ -1,55 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.cli
-
-import collection.JavaConversions._
-import jline.console.completer.Completer
-import java.util.SortedSet
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-
-trait CommandCompleter extends Completer {self: Commands =>
- private val RE0 = """\s+""".r
- private val RE1 = """\s*(\w+)""".r
- private val RE2 = """\s*(\w+)(.+)""".r
-
- override def complete(buffer: String, cursor: Int, candidates: java.util.List[CharSequence]): Int = buffer match {
- case null | RE0() => candidates.addAll(commands); 0
- case RE1(part) => commands.tailSet(part) filter {_.startsWith(part)} foreach {candidates.add}; 0
- case RE2(name, part) => command(name) match {
- case None => warn("Invalid command {}", name); -1
- case Some(command) => command.complete(part, cursor, candidates)
- }
- }
-}
-
-trait FirstArgumentCompleter extends Completer {
- protected def allCandidates:SortedSet[String]
-
- override def complete(buffer: String, cursor: Int, candidates: java.util.List[CharSequence]) = {
- val trimmed = buffer.trim
- trimmed match {
- case "" => candidates.addAll(allCandidates); cursor
- case _ =>
- allCandidates.tailSet(trimmed) filter {_.startsWith(trimmed)} foreach {candidates.add}
- if (candidates.isEmpty) -1 else cursor - trimmed.size
- }
- }
-
-}
View
63 console/src/main/scala/com/github/zhongl/housemd/cli/Console.scala
@@ -1,63 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.cli
-
-import java.io.InputStream
-import java.io.OutputStream
-import jline.console.ConsoleReader
-import instrument.Instrumentation
-import scala.annotation.tailrec
-import management.ManagementFactory
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-class Console(in: InputStream, out: OutputStream, instrumentation: Instrumentation) {
-
- var commands: Commands = _
-
- def run() {
- val reader = new ConsoleReader(in, out)
-
- reader.setPrompt(ManagementFactory.getRuntimeMXBean.getName + ">")
-
- reader.addCompleter(commands)
-
- @tailrec
- def parse(line: String) {
- line match {
- case null =>
- case _ => execute(line); parse(reader.readLine())
- }
- }
-
- parse(reader.readLine())
- }
-
- private[this] def execute(line: String) {
- line split ("\\s+") match {
- case Array() =>
- case Array(command) => commands.execute(command)
- case Array(command, arguments@_*) => commands.execute(command, arguments: _*)
- }
- }
-
-
-}
-
-
-
View
28 console/src/main/scala/com/github/zhongl/housemd/cli/Output.scala
@@ -1,28 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.cli
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-trait Output {
- def print(text: String)
-
- def println(line: String)
-
- def printf(pattern: String, objs: AnyRef*)
-}
View
30 console/src/main/scala/com/github/zhongl/housemd/cli/VirtualMachine.scala
@@ -1,30 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.cli
-
-import com.github.zhongl.housemd.Advice
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-trait VirtualMachine {
- def allLoadedClasses: Array[Class[_]]
-
- def probe(advice: Advice)
-
- def reset()
-}
View
29 console/src/main/scala/com/github/zhongl/housemd/cli/annotation/Argument.java
@@ -1,29 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.cli.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Argument {
- String name();
- String description();
-}
View
30 console/src/main/scala/com/github/zhongl/housemd/cli/annotation/Command.java
@@ -1,30 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.cli.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Command {
- String name();
-
- String description();
-}
View
29 console/src/main/scala/com/github/zhongl/housemd/cli/annotation/Option.java
@@ -1,29 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.cli.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Option {
- String[] name();
- String description();
-}
View
30 console/src/main/scala/com/github/zhongl/housemd/cli/package.scala
@@ -1,30 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd
-
-import annotation.target.field
-import cli.annotation.{Option, Command, Argument}
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-
-package object cli {
- type command = Command
- type option = Option@field
- type argument = Argument@field
-}
View
106 console/src/main/scala/com/github/zhongl/housemd/closures/Closure.scala
@@ -1,106 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.closures
-
-import management.ManagementFactory
-import instrument.Instrumentation
-import com.github.zhongl.housemd.{Reflections, Utils, cli}
-import Reflections._
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-trait Closure {
- override def toString = "Closure: " + nativeToStringOf(this)
-
- def apply(instrumentation: Instrumentation)(output: String => Unit)
-}
-
-class Summary extends Closure {
- def apply(instrumentation: Instrumentation)(output: String => Unit) {
- val runtime = ManagementFactory.getRuntimeMXBean
- output("name : " + runtime.getName)
- }
-}
-
-trait ListMapByPattern extends Closure {
-
- def apply(instrumentation: Instrumentation)(output: String => Unit) {
- for ((k, v) <- map) {
- if (pattern == null ||
- k.toLowerCase.contains(pattern.toLowerCase)) output(k + " = " + v)
- }
- }
-
- protected def pattern: String
-
- protected def map: Map[String, String]
-}
-
-import cli._
-
-class Enviroment(
- @argument(name = "pattern", description = "enviroment key pattern")
- protected val pattern: String = null) extends ListMapByPattern {
- protected def map = sys.env
-}
-
-class Properites(
- @argument(name = "pattern", description = "properties key pattern")
- protected val pattern: String = null)
- extends ListMapByPattern {
- protected def map = sys.props.toMap
-}
-
-class LoadedClasses(
- @argument(name = "regex", description = "regex for matching loaded classes")
- regex: String = ".+",
- @option(name = Array("-h", "--loader-hierarchies"), description = "show loader hierarchies of loaded classes")
- loaderHierarchies: Boolean = false)
- extends Closure {
-
- private[this] val tab = "\t"
-
- def apply(instrumentation: Instrumentation)(output: String => Unit) {
- implicit val o = output
- instrumentation.getAllLoadedClasses filter {_.getName.matches(regex)} foreach {
- c =>
- output(c.getName + originOf(c))
- if (loaderHierarchies) layout(c.getClassLoader)
- }
- }
-
- private[this] def layout(cl: ClassLoader, lastIndents: String = "- ")(implicit output: String => Unit) {
- cl match {
- case null => Unit
- case _ =>
- val indents = tab + lastIndents
- output(indents + nativeToStringOf(cl))
- layout(cl.getParent, indents)
- }
- }
-
- private[this] def originOf(c: Class[_]): String = " -> " + Utils.sourceOf(c)
-}
-
-//abstract class Trace(regex: String) extends Closure {
-// def apply() {
-//
-//
-// }
-//}
-
View
49 console/src/main/scala/com/github/zhongl/housemd/closures/ClosureExecutor.scala
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.closures
-
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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.
- */
-
-import instrument.Instrumentation
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-object ClosureExecutor extends App {
- val klass = Class.forName("com.github.zhongl.housemd.Summary").asInstanceOf[Class[Closure]]
- val method = klass.getMethod("apply", classOf[Instrumentation], classOf[String => Unit])
- val instance = klass.newInstance()
- val arguments = Seq(null, {x: String => println(x) }).asInstanceOf[Seq[AnyRef]]
- method invoke(instance, arguments: _*)
-
-}
-
-class a extends StaticAnnotation
View
65 console/src/main/scala/com/github/zhongl/housemd/closures/Loaded.scala
@@ -1,65 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.closures
-
-import java.util.SortedSet
-import com.github.zhongl.housemd.{Reflections, Utils, cli}
-import Reflections._
-import cli._
-
-@command(name = "loaded", description = "output loaded classes information")
-class Loaded(output: Output, vm: VirtualMachine) extends FirstArgumentCompleter {
-
- private[this] val tab = "\t"
-
- def apply(
- @argument(name = "name", description = "specical class name, eg: String@java.lang")
- name: String /*,
- @option(name = Array("-h", "--inClassLoader-hierarchies"), description = "show inClassLoader hierarchies of loaded classes")
- loaderHierarchies: Boolean = false*/) {
-
- implicit val o = output
- vm.allLoadedClasses filter {classNameOf(_).equals(name)} foreach {
- c =>
- output.println(c.getName + originOf(c))
- // if (loaderHierarchies) layout(c.getClassLoader)
- }
- }
-
- protected def allCandidates = sortedSet(vm.allLoadedClasses.map { c => classNameOf(c) })
-
- private[this] def layout(cl: ClassLoader, lastIndents: String = "- ")(implicit output: String => Unit) {
- cl match {
- case null => Unit
- case _ =>
- val indents = tab + lastIndents
- output(indents + nativeToStringOf(cl))
- layout(cl.getParent, indents)
- }
- }
-
- private[this] def originOf(c: Class[_]): String = " -> " + Utils.sourceOf(c)
-
- private[this] def classNameOf(c: Class[_]): String = c.getSimpleName + "@" + c.getPackage.getName
-
- private def sortedSet[T](list: Array[T]): SortedSet[T] = {
- import collection.JavaConversions.asJavaCollection
- new java.util.TreeSet[T](list.toIterable)
- }
-}
-
-
View
26 console/src/main/scala/com/github/zhongl/housemd/logging/Level.scala
@@ -1,26 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.logging
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-
-object Level extends Enumeration {
- type Level = Value
- val Debug, Info, Warn, Error = Value
-}
View
50 console/src/main/scala/com/github/zhongl/housemd/logging/Loggable.scala
@@ -1,50 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.logging
-
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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.
- */
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-
-trait Loggable {
-
- protected def debug(pattern: String, anyRefs: AnyRef*)
-
- protected def info(pattern: String, anyRefs: AnyRef*)
-
- protected def warn(pattern: String, anyRefs: AnyRef*)
-
- protected def error(pattern: String, anyRefs: AnyRef*)
-
-}
-
View
170 console/src/test/scala/com/github/zhongl/housemd/cli/CommandsSpec.scala
@@ -1,170 +0,0 @@
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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 com.github.zhongl.housemd.cli
-
-/*
- * Copyright 2012 zhongl
- *
- * Licensed 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.
- */
-
-import org.scalatest.FunSpec
-import org.scalatest.matchers.ShouldMatchers
-import com.github.zhongl.housemd.logging.{AssertLog, Level}
-import java.util.ArrayList
-
-/**
- * @author <a href="mailto:zhong.lunfu@gmail.com">zhongl<a>
- */
-
-class CommandsSpec extends FunSpec with ShouldMatchers {
-
- abstract class Mock {
- var called = false
-
- def shouldCalled() {
- assert(called === true)
- }
- }
-
- @command(name = "mock0", description = "mock a command")
- class Mock0 extends Mock {
-
- def apply() {
- called = true
- }
-
- }
-
- @command(name = "mock1", description = "mock a command")
- class Mock1 extends Mock {
- def apply(
- @argument(name = "boolean", description = "desc") b: Boolean,
- @argument(name = "int", description = "desc") i: Int,
- @argument(name = "long", description = "desc") l: Long,
- @argument(name = "double", description = "desc") d: Double,
- @argument(name = "string", description = "desc") s: String) {
- called = true
- assert(b === true)
- assert(i === 1)
- assert(l === 1000L)
- assert(d === 0.5D)
- assert(s === "s")
- }
- }
-
- @command(name = "mock1", description = "mock a command")
- class Mock2 extends Mock {
- def apply(
- @option(name = Array("-b", "--boolean"), description = "flag") flag: Boolean = false,
- @argument(name = "arg", description = "desc") arg: String) {
- called = true
- assert(arg === "arg")
- }
- }
-
- describe("Commands") {
- it("should execute command without argument and get exception") {
- val mock = new Mock0
- val commands = new Commands(mock) with AssertLog with NoneCompleter
- commands.execute("mock0")
- mock.shouldCalled()
- }
-
- it("should execute command with argument and get exception") {
- val mock = new Mock1
- val commands = new Commands(mock) with AssertLog with NoneCompleter
- commands.execute("mock1", "true", "1", "1000", "0.5", "s")
- mock.shouldCalled()
- commands.shouldNotLogged()
- }
-
- it("should complain by unknown command name") {
- val commands = new Commands() with AssertLog with NoneCompleter
- commands.execute("unknown")
- commands.shouldLogged(Level.Warn, "Unknown command {}", "unknown")
- }
-
- it("should complain by illegal argument") {
- pending
- }
-
- it("should complain by runtime exception of command") {
- pending
- }
-
- it("should complete all command names") {
- val commands = new Commands() with AssertLog with CommandCompleter
- val candidates = new ArrayList[CharSequence]()
- val cursor = commands.complete(" ", 2, candidates)
- candidates.get(0) should be("help")
- candidates.get(1) should be("quit")
- candidates.size() should be(2)
- cursor should be(0)
- }
-
- it("should complete help") {
- val commands = new Commands() with AssertLog with CommandCompleter
- val candidates = new ArrayList[CharSequence]()
- val cursor = commands.complete("he", 2, candidates)
- candidates.get(0) should be("help")
- candidates.size() should be(1)
- cursor should be(0)
- }
-
- it("should complete help all arguments") {
- val commands = new Commands() with AssertLog with CommandCompleter
- val candidates = new ArrayList[CharSequence]()
- val cursor = commands.complete("help ", 5, candidates)
- candidates.get(0) should be("help")
- candidates.get(1) should be("quit")
- candidates.size() should be(2)
-
- cursor should be(5)
- }
-
- it("should complete help argument quit") {
- val commands = new Commands() with AssertLog with CommandCompleter
- val candidates = new ArrayList[CharSequence]()
- val cursor = commands.complete("help qu", 7, candidates)
- candidates.get(0) should be("quit")
- candidates.size() should be(1)
- cursor should be(5)
- }
-
- it("should complete nothing for quit") {
- val commands = new Commands() with AssertLog with CommandCompleter
- val candidates = new ArrayList[CharSequence]()
- val cursor = commands.complete("quit ", 5, candidates)
- candidates.size() should be(0)
- cursor should be(-1)
- }