diff --git a/README.md b/README.md
index 6cef48003..0681f00d1 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# JBake
-[![Build Status](https://travis-ci.org/jonbullock/JBake.png?branch=master)](https://travis-ci.org/jonbullock/JBake)
+![Build Status](https://travis-ci.org/mismatch/JBake.png?branch=master)
by **[Jonathan Bullock](http://jonathanbullock.com/)**
diff --git a/pom.xml b/pom.xml
index e33f77484..be941e2ee 100644
--- a/pom.xml
+++ b/pom.xml
@@ -112,6 +112,11 @@
commons-configuration
1.9
+
+ args4j
+ args4j
+ 2.0.23
+
org.freemarker
freemarker
diff --git a/src/main/java/org/jbake/app/FileUtil.java b/src/main/java/org/jbake/app/FileUtil.java
index 2067c1ee6..c15514a65 100644
--- a/src/main/java/org/jbake/app/FileUtil.java
+++ b/src/main/java/org/jbake/app/FileUtil.java
@@ -27,4 +27,8 @@ public boolean accept(File pathname) {
}
};
}
+
+ public static boolean isExistingFolder(File f) {
+ return null != f && f.exists() && f.isDirectory();
+ }
}
diff --git a/src/main/java/org/jbake/app/Oven.java b/src/main/java/org/jbake/app/Oven.java
index 4b0b66003..adaadc32a 100644
--- a/src/main/java/org/jbake/app/Oven.java
+++ b/src/main/java/org/jbake/app/Oven.java
@@ -36,18 +36,49 @@ public class Oven {
*
* @param source The source folder
* @param destination The destination folder
- * @throws ConfigurationException
+ * @throws Exception
*/
- public Oven(File source, File destination) throws ConfigurationException {
+ public Oven(File source, File destination) throws Exception {
this.source = source;
this.destination = destination;
+
+ ensureSource();
+
+ loadConfig();
+
+ ensureDestination();
+ }
+
+ private void loadConfig() throws ConfigurationException {
this.config = new CompositeConfiguration();
- File customConfig = new File(source.getPath()+File.separator+"custom.properties");
+ File customConfig = new File(source, "custom.properties");
if (customConfig.exists()) {
config.addConfiguration(new PropertiesConfiguration(customConfig));
}
config.addConfiguration(new PropertiesConfiguration("default.properties"));
- }
+ }
+
+ private void ensureSource() throws Exception {
+ if (!FileUtil.isExistingFolder(source)) {
+ throw new Exception("Source folder MUST exist!");
+ }
+ if (!source.canRead()) {
+ throw new Exception("Source folder is not readable! Please, check");
+ }
+ }
+
+
+ private void ensureDestination() throws Exception {
+ if (null == destination) {
+ destination = new File(config.getString("destination.folder"));
+ }
+ if (!destination.exists()) {
+ destination.mkdirs();
+ }
+ if (!destination.canWrite()) {
+ throw new Exception("Destination folder is not writable! Please, check");
+ }
+ }
/**
* Checks source path contains required sub-folders (i.e. templates) and setups up variables for them.
@@ -55,20 +86,26 @@ public Oven(File source, File destination) throws ConfigurationException {
* @throws Exception If template or contents folder don't exist
*/
public void setupPaths() throws Exception {
- templatesPath = new File(source.getPath() + File.separator + config.getString("template.folder"));
- if (!templatesPath.exists()) {
- throw new Exception("Error: Required template folder cannot be found!");
- }
- contentsPath = new File(source.getPath() + File.separator + config.getString("content.folder"));
- if (!contentsPath.exists()) {
- throw new Exception("Error: Required content folder cannot be found!");
- }
- assetsPath = new File(source.getPath() + File.separator + config.getString("asset.folder"));
+ templatesPath = setupRequiredFolderFromConfig("template.folder");
+ contentsPath = setupRequiredFolderFromConfig("content.folder");
+ assetsPath = setupPathFromConfig("asset.folder");
if (!assetsPath.exists()) {
System.out.println("Warning: No asset folder was found!");
}
}
+ private File setupPathFromConfig(String key) {
+ return new File(source, config.getString(key));
+ }
+
+ private File setupRequiredFolderFromConfig(String key) throws Exception {
+ File path = setupPathFromConfig(key);
+ if (!FileUtil.isExistingFolder(path)) {
+ throw new Exception("Error: Required folder cannot be found! Config key is " + key);
+ }
+ return path;
+ }
+
/**
* All the good stuff happens in here...
*
diff --git a/src/main/java/org/jbake/launcher/LaunchOptions.java b/src/main/java/org/jbake/launcher/LaunchOptions.java
new file mode 100644
index 000000000..3e1040d8c
--- /dev/null
+++ b/src/main/java/org/jbake/launcher/LaunchOptions.java
@@ -0,0 +1,32 @@
+package org.jbake.launcher;
+
+import java.io.File;
+
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+class LaunchOptions {
+ @Argument(index = 0, usage = "source of your blog posts (with templates and assets)", metaVar = "source_folder")
+ private File source = new File(".");
+
+ @Argument(index = 1, usage = "destination folder for baked artifacts", metaVar = "destination_folder")
+ private File destination = null;
+
+ @Option(name = "-h", aliases = {"--help"}, usage="prints this message")
+ private boolean isHelpNeeded;
+
+
+ LaunchOptions() {}
+
+ File getSource() {
+ return source;
+ }
+
+ File getDestination() {
+ return destination;
+ }
+
+ boolean isHelpNeeded() {
+ return isHelpNeeded;
+ }
+}
diff --git a/src/main/java/org/jbake/launcher/Main.java b/src/main/java/org/jbake/launcher/Main.java
index 91c9a2dff..f159d4abc 100644
--- a/src/main/java/org/jbake/launcher/Main.java
+++ b/src/main/java/org/jbake/launcher/Main.java
@@ -1,6 +1,10 @@
package org.jbake.launcher;
import java.io.File;
+import java.io.StringWriter;
+
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
import org.jbake.app.Oven;
@@ -11,9 +15,9 @@
*
*/
public class Main {
-
public static final String VERSION = "v2.0";
- private static final String USAGE = "Usage: java -jar jbake.jar