[from now] 2014/06/16 23:56:28

diff --git a/build.gradle b/build.gradle
index d7c291e..c7c71c4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -26,7 +26,7 @@ apply plugin: 'idea'

 version = '0.4'
-mainClassName = 'gaiden.GaidenMain'
+mainClassName = 'gaiden.kai.GaidenMain'

 sourceCompatibility = 1.7
 targetCompatibility = 1.7
@@ -42,7 +42,11 @@ dependencies {
     compile 'commons-io:commons-io:2.4'
     compile 'commons-cli:commons-cli:1.2'
     compile 'org.apache.commons:commons-lang3:3.1'
-    compile 'org.springframework:spring-context:4.0.5.RELEASE'
+    compile('org.springframework:spring-context:4.0.5.RELEASE') {
+        exclude(group: 'commons-logging', module: 'commons-logging')
+    }
+    compile 'ch.qos.logback:logback-classic:1.1.2'
+    compile 'org.slf4j:jcl-over-slf4j:1.7.7'

     testCompile 'org.spockframework:spock-core:0.7-groovy-2.0'

@@ -92,13 +96,13 @@ codenarc {

 processResources {
     filter ReplaceTokens, tokens: [
-        revision: revision,
-        version: version,
-        buildDate: new Date().format("yyyy-MM-dd HH:mm:ss.SSSZ"),
-        username: System.properties["user.name"],
+        revision   : revision,
+        version    : version,
+        buildDate  : new Date().format("yyyy-MM-dd HH:mm:ss.SSSZ"),
+        username   : System.properties["user.name"],
         javaVersion: System.properties["java.version"],
-        osName: System.properties["os.name"],
-        osVersion: System.properties["os.version"]
+        osName     : System.properties["os.name"],
+        osVersion  : System.properties["os.version"]
     ]
 }

diff --git a/src/main/groovy/gaiden/command/Build.groovy b/src/main/groovy/gaiden/command/Build.groovy
index 1cd1ff9..242189c 100644
--- a/src/main/groovy/gaiden/command/Build.groovy
+++ b/src/main/groovy/gaiden/command/Build.groovy
@@ -35,7 +35,6 @@
     /**
      * Executes building.
      */
-    @Override
     void execute(List args = []) {
         def documentSource = new SourceCollector().collect()
         def context = new BuildContext(documentSource: documentSource)
diff --git a/src/main/groovy/gaiden/command/Clean.groovy b/src/main/groovy/gaiden/command/Clean.groovy
index 83cdfd8..c3a4a7a 100644
--- a/src/main/groovy/gaiden/command/Clean.groovy
+++ b/src/main/groovy/gaiden/command/Clean.groovy
@@ -37,7 +37,6 @@
     /**
      * Executes cleaning.
      */
-    @Override
     void execute(List args = []) {
         new AntBuilder().delete(dir: targetDirectory)
     }
diff --git a/src/main/groovy/gaiden/command/CreateProject.groovy b/src/main/groovy/gaiden/command/CreateProject.groovy
index 3a5b759..1c22a73 100644
--- a/src/main/groovy/gaiden/command/CreateProject.groovy
+++ b/src/main/groovy/gaiden/command/CreateProject.groovy
@@ -39,7 +39,6 @@
     /**
      * Executes creating project.
      */
-    @Override
     void execute(List args = []) {
         if (args.empty) {
             throw new GaidenException("command.create.project.name.required.error")
diff --git a/src/main/groovy/gaiden/command/Version.groovy b/src/main/groovy/gaiden/command/Version.groovy
index 10eb2a3..8e9ba71 100644
--- a/src/main/groovy/gaiden/command/Version.groovy
+++ b/src/main/groovy/gaiden/command/Version.groovy
@@ -31,7 +31,6 @@
     /**
      * Displays a version of Gaiden.
      */
-    @Override
     void execute(List args = []) {
         def properties = new Properties()
         getClass().getResourceAsStream("/build-receipt.properties").withStream { InputStream stream ->
diff --git a/src/main/groovy/gaiden/exception/GaidenException.groovy b/src/main/groovy/gaiden/exception/GaidenException.groovy
index 093a1bf..844bb85 100644
--- a/src/main/groovy/gaiden/exception/GaidenException.groovy
+++ b/src/main/groovy/gaiden/exception/GaidenException.groovy
@@ -50,5 +50,4 @@
     String getMessage() {
         return "ERROR: " + Holders.getMessage(key, arguments)
     }
-
 }
diff --git a/src/main/groovy/gaiden/kai/CommandResolver.groovy b/src/main/groovy/gaiden/kai/CommandResolver.groovy
index b05f2ce..92c6490 100644
--- a/src/main/groovy/gaiden/kai/CommandResolver.groovy
+++ b/src/main/groovy/gaiden/kai/CommandResolver.groovy
@@ -1,6 +1,7 @@
 package gaiden.kai

 import gaiden.kai.command.GaidenCommnad
+import gaiden.kai.command.UnknownCommand
 import groovy.transform.CompileStatic
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.stereotype.Component
@@ -14,18 +15,6 @@

     GaidenCommnad resolve(String commandName) {
         def command = commnads.find { it.name == commandName }
-        command ?: UNKNOWN_COMMAND
-    }
-
-    private static final GaidenCommnad UNKNOWN_COMMAND = new GaidenCommnad() {
-        @Override
-        void execute() {
-            // TODO
-        }
-
-        @Override
-        String getName() {
-            return null
-        }
+        command ?: new UnknownCommand()
     }
 }
diff --git a/src/main/groovy/gaiden/kai/GaidenApplication.groovy b/src/main/groovy/gaiden/kai/GaidenApplication.groovy
new file mode 100644
index 0000000..1fb63f6
--- /dev/null
+++ b/src/main/groovy/gaiden/kai/GaidenApplication.groovy
@@ -0,0 +1,18 @@
+package gaiden.kai
+
+import groovy.transform.CompileStatic
+import org.springframework.context.ApplicationContext
+import org.springframework.context.annotation.AnnotationConfigApplicationContext
+
+@CompileStatic
+class GaidenApplication {
+
+    ApplicationContext applicationContext
+
+    GaidenApplication() {
+        def applicationContext = new AnnotationConfigApplicationContext()
+        applicationContext.scan(getClass().package.name)
+        applicationContext.refresh()
+        this.applicationContext = applicationContext
+    }
+}
diff --git a/src/main/groovy/gaiden/kai/GaidenApplicationContext.groovy b/src/main/groovy/gaiden/kai/GaidenApplicationContext.groovy
deleted file mode 100644
index 8c00fd1..0000000
--- a/src/main/groovy/gaiden/kai/GaidenApplicationContext.groovy
+++ /dev/null
@@ -1,11 +0,0 @@
-package gaiden.kai
-
-import org.springframework.context.annotation.AnnotationConfigApplicationContext
-
-class GaidenApplicationContext extends AnnotationConfigApplicationContext {
-
-    GaidenApplicationContext() {
-        scan(getClass().package.name)
-        refresh()
-    }
-}
diff --git a/src/main/groovy/gaiden/kai/GaidenConfig.groovy b/src/main/groovy/gaiden/kai/GaidenConfig.groovy
index aa7b5b0..67de3e2 100644
--- a/src/main/groovy/gaiden/kai/GaidenConfig.groovy
+++ b/src/main/groovy/gaiden/kai/GaidenConfig.groovy
@@ -3,15 +3,35 @@
 import groovy.transform.CompileStatic
 import org.springframework.stereotype.Component

+import javax.annotation.PostConstruct
+import java.nio.file.Files
 import java.nio.file.Path
+import java.nio.file.Paths

 @Component
 @CompileStatic
 class GaidenConfig {

-    Path pagesDirectory
+    private static final Path CONFIG_PATH = Paths.get("GaidenConfig.groovy")

-    Path outputDirectory
+    Path pagesDirectory = Paths.get("pages")
+
+    Path outputDirectory = Paths.get("build")

     String inputEncoding = "UTF-8"
+
+    @PostConstruct
+    void loadConfigFile() {
+        if (Files.notExists(CONFIG_PATH)) {
+            return
+        }
+
+        def configObject = new ConfigSlurper().parse(CONFIG_PATH.toUri().toURL())
+        configObject.each { Map.Entry entry ->
+            def key = entry.key as String
+            if (this.hasProperty(key)) {
+                this.setProperty(key, entry.value)
+            }
+        }
+    }
 }
diff --git a/src/main/groovy/gaiden/kai/GaidenMain.groovy b/src/main/groovy/gaiden/kai/GaidenMain.groovy
index 2e7d440..f794320 100644
--- a/src/main/groovy/gaiden/kai/GaidenMain.groovy
+++ b/src/main/groovy/gaiden/kai/GaidenMain.groovy
@@ -1,14 +1,42 @@
 package gaiden.kai

+import gaiden.exception.GaidenException
+
 class GaidenMain {

     static void main(String... args) {
-        def gaidenContext = new GaidenApplicationContext()
+        try {
+            new GaidenMain().run(args)
+        } catch (GaidenException e) {
+            System.err.println(e.message)
+            System.exit(1)
+        }
+    }

-        def commandName = args.first()
+    void run(String... args) {
+        def gaidenContext = new GaidenApplication()

-        def commandResolver = gaidenContext.getBean(CommandResolver)
+        def options = getOptions(args)
+        def commandName = getCommandName(args, options)
+        def commandResolver = gaidenContext.applicationContext.getBean(CommandResolver)
         def command = commandResolver.resolve(commandName)
-        command.execute()
+        command.execute(options.arguments())
+    }
+
+    private String getCommandName(String[] args, OptionAccessor options) {
+        if (options.v) {
+            return "version"
+        } else if (args) {
+            return args.first()
+        }
+        null
+    }
+
+    private OptionAccessor getOptions(String[] args) {
+        def cliBuilder = new CliBuilder()
+        cliBuilder.with {
+            v longOpt: 'version', 'show version'
+        }
+        cliBuilder.parse(args)
     }
 }
diff --git a/src/main/groovy/gaiden/kai/command/BuildCommand.groovy b/src/main/groovy/gaiden/kai/command/BuildCommand.groovy
index 5d334e8..c183c3f 100644
--- a/src/main/groovy/gaiden/kai/command/BuildCommand.groovy
+++ b/src/main/groovy/gaiden/kai/command/BuildCommand.groovy
@@ -18,8 +18,7 @@
     @Autowired
     DocumentWriter documentWriter

-    @Override
-    void execute() {
+    void execute(List<String> options) {
         def documentSource = sourceCollector.collect()
         documentWriter.write(documentSource)
     }
diff --git a/src/main/groovy/gaiden/kai/command/GaidenCommnad.groovy b/src/main/groovy/gaiden/kai/command/GaidenCommnad.groovy
index 059a8a7..4562a82 100644
--- a/src/main/groovy/gaiden/kai/command/GaidenCommnad.groovy
+++ b/src/main/groovy/gaiden/kai/command/GaidenCommnad.groovy
@@ -4,7 +4,7 @@

 @CompileStatic
 interface GaidenCommnad {
-    void execute()
+    void execute(List<String> options)

     String getName()
 }
diff --git a/src/main/groovy/gaiden/kai/command/UnknownCommand.groovy b/src/main/groovy/gaiden/kai/command/UnknownCommand.groovy
new file mode 100644
index 0000000..85f7e66
--- /dev/null
+++ b/src/main/groovy/gaiden/kai/command/UnknownCommand.groovy
@@ -0,0 +1,23 @@
+package gaiden.kai.command
+
+import groovy.transform.CompileStatic
+import groovy.util.logging.Slf4j
+
+@Slf4j
+@CompileStatic
+class UnknownCommand implements GaidenCommnad {
+
+    final String name = "unknown"
+
+    void execute(List<String> options) {
+        log.error '''\
+Usage: gaiden [-v|--version] <command>
+
+    commands:
+            build                          Build pages from source pages
+            clean                          Clean the build directory
+            create-project <project name>  Create the project directory\
+'''
+        System.exit(1)
+    }
+}
diff --git a/src/main/groovy/gaiden/kai/exception/GaidenException.groovy b/src/main/groovy/gaiden/kai/exception/GaidenException.groovy
new file mode 100644
index 0000000..47747da
--- /dev/null
+++ b/src/main/groovy/gaiden/kai/exception/GaidenException.groovy
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 the original author or authors
+ *
+ * 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 gaiden.kai.exception
+
+import groovy.transform.InheritConstructors
+
+@InheritConstructors
+class GaidenException extends RuntimeException {
+}
diff --git a/src/main/groovy/gaiden/markdown/GaidenToHtmlSerializer.groovy b/src/main/groovy/gaiden/markdown/GaidenToHtmlSerializer.groovy
index 98748a5..1721c8e 100644
--- a/src/main/groovy/gaiden/markdown/GaidenToHtmlSerializer.groovy
+++ b/src/main/groovy/gaiden/markdown/GaidenToHtmlSerializer.groovy
@@ -41,7 +41,6 @@
         this.printer = printer
     }

-    @Override
     protected void printImageTag(SuperNode imageNode, String url) {
         def rendering = imageRenderer.render(url, printChildrenToString(imageNode))
         printer
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644
index 0000000..9d0892d
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,15 @@
+<configuration>
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <logger name="org.springframework" level="OFF"/>
+
+    <root level="info">
+        <appender-ref ref="STDOUT"/>
+    </root>
+
+</configuration>
\ No newline at end of file
diff --git a/src/test/groovy/gaiden/GaidenMainSpec.groovy b/src/test/groovy/gaiden/GaidenMainSpec.groovy
index 50ee1be..439e23d 100644
--- a/src/test/groovy/gaiden/GaidenMainSpec.groovy
+++ b/src/test/groovy/gaiden/GaidenMainSpec.groovy
@@ -19,7 +19,7 @@
 import gaiden.command.CommandFactory
 import gaiden.command.GaidenCommand
 import gaiden.exception.GaidenException
-import gaiden.exception.IllegalOperationException
+import gaiden.kai.exception.IllegalOperationException
 import gaiden.message.MessageSource
 import spock.lang.Specification

diff --git a/src/test/groovy/gaiden/kai/command/CommandSpec.groovy b/src/test/groovy/gaiden/kai/command/CommandSpec.groovy
index 3541c8e..896986e 100644
--- a/src/test/groovy/gaiden/kai/command/CommandSpec.groovy
+++ b/src/test/groovy/gaiden/kai/command/CommandSpec.groovy
@@ -1,19 +1,19 @@
 package gaiden.kai.command

-import gaiden.kai.GaidenApplicationContext
+import gaiden.kai.GaidenApplication
 import gaiden.kai.GaidenConfig
 import gaiden.kai.GaidenSpec

 abstract class CommandSpec extends GaidenSpec {

-    GaidenApplicationContext context = new GaidenApplicationContext()
+    GaidenApplication application = new GaidenApplication()
     GaidenCommnad command

     def setup() {
         def commandClass = getClass().getAnnotation(TestFor).value()
-        command = context.getBean(commandClass)
+        command = application.applicationContext.getBean(commandClass)

-        gaidenConfig = context.getBean(GaidenConfig)
+        gaidenConfig = application.applicationContext.getBean(GaidenConfig)
         gaidenConfig.pagesDirectory = pagesDirectory
         gaidenConfig.outputDirectory = outputDirectory
     }
[from now] 2014/06/17 00:00:42

diff --git a/src/main/groovy/gaiden/kai/exception/GaidenException.groovy b/src/main/groovy/gaiden/kai/exception/GaidenException.groovy
index 47747da..05ca89a 100644
--- a/src/main/groovy/gaiden/kai/exception/GaidenException.groovy
+++ b/src/main/groovy/gaiden/kai/exception/GaidenException.groovy
@@ -16,8 +16,10 @@

 package gaiden.kai.exception

+import groovy.transform.CompileStatic
 import groovy.transform.InheritConstructors

+@CompileStatic
 @InheritConstructors
 class GaidenException extends RuntimeException {
 }