diff --git a/docs/Developer-Guide.md b/docs/Developer-Guide.md index d7c44ab..1794e04 100644 --- a/docs/Developer-Guide.md +++ b/docs/Developer-Guide.md @@ -152,7 +152,7 @@ Command | `parse(String userInput)`: Analyses the given `userInput` to determine ## `Storage` Class `Storage` is a simple class that has one public method which takes in a list of lines and saves them to a -local file in a default folder. This default folder is defined in this class. +local file in the a specified output folder. This output folder is specified in the constructor. The current implementation saves collated data in Markdown files. These files are human-readable and editable, and utilises syntax from [Github Flavored Markdown](https://help.github.com/articles/github-flavored-markdown/). @@ -187,7 +187,7 @@ lines of code of all code snippets and is used to calculate the overall proporti ## `SourceFile` Class This class represents source files that contain at least one author tag. Each `SourceFile` object is constructed with the file's path relative to the user's specified folder and the file's language. -The base folder is specified through the `collate from ` command. +The base folder is specified through the `collate from ` command. # GUI Component diff --git a/docs/User-Guide.md b/docs/User-Guide.md index ffece44..bbb3adf 100644 --- a/docs/User-Guide.md +++ b/docs/User-Guide.md @@ -14,6 +14,7 @@ Now that you know what Collate is [about](../README.md), you can follow this gui - [Viewing the summary](#viewing-the-summary) - [Exiting](#exiting) - [Using the Text UI](#using-the-text-ui) + - [Using the Batch mode](#using-the-batch-mode) - [Cheatsheet](#cheatsheet) @@ -37,11 +38,13 @@ Now that you know what Collate is [about](../README.md), you can follow this gui ![gui collate all subfolders](images/user-guide/gui-collate-all-subfolders.gif) 5. **Ask Collate to collate your code**. As shown in the above animation, you can type - `collate from ` to collate all files within `` including subfolders. + `collate from ` to collate all files within `` + including subfolders. -6. **View reports**: The reports can be found in a folder called `collated`. +6. **View reports**: The reports can be found in the same folder as the jar file. You'll find one `.md` for each author, containing the code written by that author. - [Here](https://github.com/collate/collate/blob/master/collated-example/Sebastian.md) is an example. + [Here](https://github.com/collate/collate/blob/master/collated-example/Sebastian.md) is an example.
+ To specify a different output folder, user the command `collate from to ` 7. **Try more commands**: * `view ` - See author's individual statistics e.g. `view Sebastian` @@ -71,14 +74,14 @@ enter his/her author tags. To collate files in a folder and all its sub folders, use this command. -`collate from ` +`collate from to ` (the `to ` part is optional) > Tip: If your folder includes whitespaces, you will need to surround the folder with double inverted commas. Examples: -* `collate from src` +* `collate from src to collated` * `collate from .` -* `collate from C:/myProject/component1/src` +* `collate from C:/myProject/component1/src to collated/src` * `collate from "C:/source files"` ![gui collate all subfolders](images/user-guide/gui-collate-all-subfolders.gif) @@ -87,7 +90,7 @@ Examples: If you would like to collate files only from the specified folder, and not files from sub folders, you can add the `only` option. -`collate from only` or `collate only from ` +`collate from only` or `collate only from ` > Tip: option order of the `collate` command is flexible. You need not worry about the position of these options, just remember to start each command with the `collate` keyword. @@ -100,15 +103,15 @@ Examples: Collate scans the folder you specified for all types of file. What if you want to collate only `java` files? Well, you can use the `include` option. -`collate from include java` +`collate from include java` You can include multiple filetypes by separating them with commas. -`collate from include java, css, fxml` +`collate from include java, css, fxml` Examples: -* `collate from C:/src java` -* `collate from C:/src java,md,css,txt` +* `collate from C:/src include java` +* `collate from C:/src to ./collated include java,md,css,txt` ## Viewing an author's statistics Viewing an author's contribution statistics can be done by entering the following command. @@ -150,13 +153,20 @@ Here are some examples: ![tui summary view](images/user-guide/tui-summary.gif) +## Using the batch mode + +Collate Text UI can be run in 'batch mode' (i.e. non-interactive CLI) to execute a command in one shot. +Here's an example.
+`java -jar Collate-TUI.jar collate from src to collated` + # Cheatsheet Command | Description --------| ------------ -`collate from ` | Collate all files within `` including subfolders -`collate from only` | Collate files in `` only -`collate from include , ` | Collate `` and `` files in `` and its subfolders -`collate from only include ` | Collate `` files in `` only -`view ` | See author's individual statistics -`summary` | See default statistics summary table -`exit` | Exit Collate \ No newline at end of file +`collate from ` | Collates all files within `` including subfolders and puts the collated files in the same folder +`collate from to ` | Collates all files within `` including subfolders and puts the collated files in the `` +`collate from only` | Collates files in `` only +`collate from include , ` | Collates `` and `` files in `` and its subfolders +`collate from only include ` | Collates `` files in `` only +`view ` | Shows author's individual statistics +`summary` | Shows default statistics summary table +`exit` | Exits Collate \ No newline at end of file diff --git a/src/main/java/backend/Command.java b/src/main/java/backend/Command.java index 26b73b1..ac8e9fb 100644 --- a/src/main/java/backend/Command.java +++ b/src/main/java/backend/Command.java @@ -16,7 +16,8 @@ public enum Type { } private Type type; - private String directory; + private String readDirectory; + private String saveDirectory; private boolean scanCurrentDirOnly; private ArrayList fileTypes; @@ -37,12 +38,20 @@ public Type getCommandType() { // "Collate" command methods // ================================================================ - public String getDirectory() { - return directory; + public String getReadDirectory() { + return readDirectory; } - public void setDirectory(String directory) { - this.directory = directory; + public String getSaveDirectory() { + return saveDirectory; + } + + public void setReadDirectory(String directory) { + this.readDirectory = directory; + } + + public void setSaveDirectory(String directory) { + this.saveDirectory = directory; } public boolean willScanCurrentDirOnly() { diff --git a/src/main/java/backend/CommandParser.java b/src/main/java/backend/CommandParser.java index 3af0e9e..c982858 100644 --- a/src/main/java/backend/CommandParser.java +++ b/src/main/java/backend/CommandParser.java @@ -29,10 +29,11 @@ public class CommandParser { private static final String USER_COMMAND_SUMMARY = "summary"; private static final String USER_COMMAND_EXIT = "exit"; - private static final String[] KEYWORDS = {"from", "only", "include"}; - private static final String KEYWORD_DIRECTORY = KEYWORDS[0]; - private static final String KEYWORD_SCAN_CURRENT_DIR_ONLY = KEYWORDS[1]; - private static final String KEYWORD_INCLUDE = KEYWORDS[2]; + private static final String[] KEYWORDS = {"from", "to", "only", "include"}; + private static final String KEYWORD_FROM_DIRECTORY = KEYWORDS[0]; + private static final String KEYWORD_TO_DIRECTORY = KEYWORDS[1]; + private static final String KEYWORD_SCAN_CURRENT_DIR_ONLY = KEYWORDS[2]; + private static final String KEYWORD_INCLUDE = KEYWORDS[3]; public CommandParser() { } @@ -88,12 +89,14 @@ private ArrayList getUserArguments(ArrayList parameters) { // ================================================================ private Command initCollateCommand(ArrayList arguments) { - File directory = new File(findDirectory(arguments)); + File fromDirectory = new File(findDirectory(arguments, KEYWORD_FROM_DIRECTORY)); + File toDirectory = new File(findDirectory(arguments, KEYWORD_TO_DIRECTORY)); ArrayList fileTypes = findIncludedFileTypes(arguments); - if (isValidCollateCommand(arguments, directory, fileTypes)) { + if (isValidCollateCommand(arguments, fromDirectory, fileTypes)) { Command command = new Command(Command.Type.COLLATE); - command.setDirectory(directory.getAbsolutePath()); + command.setReadDirectory(fromDirectory.getAbsolutePath()); + command.setSaveDirectory(toDirectory.getAbsolutePath()); command.setScanCurrentDirOnly(hasScanCurrentDirOnlyKeyword(arguments)); command.setFileTypes(fileTypes); return command; @@ -102,9 +105,9 @@ private Command initCollateCommand(ArrayList arguments) { } } - private String findDirectory(ArrayList arguments) { - if (arguments.contains(KEYWORD_DIRECTORY)) { - int directoryIndex = arguments.indexOf(KEYWORD_DIRECTORY) + 1; + private String findDirectory(ArrayList arguments, String directoryIdentifier) { + if (arguments.contains(directoryIdentifier)) { + int directoryIndex = arguments.indexOf(directoryIdentifier) + 1; try { return getFullDirectory(arguments, directoryIndex); diff --git a/src/main/java/backend/Logic.java b/src/main/java/backend/Logic.java index 3f6220d..12bb4e3 100644 --- a/src/main/java/backend/Logic.java +++ b/src/main/java/backend/Logic.java @@ -23,7 +23,7 @@ public class Logic { private CommandParser commandParser; private Storage storage; private HashMap authors; - private File rootDirectory; + private File readDirectory; private Author targetAuthor; private static final String AUTHOR_TAG = "@@author"; @@ -75,12 +75,12 @@ public Command.Type executeCommand(String userInput) { private void handleCollate(Command command) { resetVariables(); - rootDirectory = new File(command.getDirectory()); - storage = new Storage(rootDirectory); + readDirectory = new File(command.getReadDirectory()); + storage = new Storage(command.getSaveDirectory()); boolean willScanCurrentDirOnly = command.willScanCurrentDirOnly(); ArrayList fileTypes = command.getFileTypes(); - traverseDirectory(rootDirectory, willScanCurrentDirOnly, fileTypes); + traverseDirectory(readDirectory, willScanCurrentDirOnly, fileTypes); saveCollatedFiles(); } @@ -201,11 +201,11 @@ private Author getAuthorByName(String authorName) { private String generateRelativePath(String filePath) { File newFile = new File(filePath); - if (newFile.equals(rootDirectory)) { + if (newFile.equals(readDirectory)) { return newFile.getName(); } else { return newFile.getAbsolutePath() - .replace(rootDirectory.getAbsolutePath(), + .replace(readDirectory.getAbsolutePath(), STRING_EMPTY); } } diff --git a/src/main/java/backend/Storage.java b/src/main/java/backend/Storage.java index 2f992bc..d2a26a0 100644 --- a/src/main/java/backend/Storage.java +++ b/src/main/java/backend/Storage.java @@ -14,7 +14,7 @@ public class Storage { public static final String DEFAULT_SAVE_DIRECTORY = "collated"; - private static final String SAVE_DIRECTORY_FORMAT = "%s" + File.separator + "collated"; + private static final String SAVE_DIRECTORY_FORMAT = "%s"; private static final String COLLATED_FILE_PATH_FORMAT = "%s" + File.separator + "%s.md"; private static final String ERROR_FILE_NOT_FOUND = "File was not found: %s"; @@ -30,15 +30,22 @@ public Storage(File directory) { } public Storage() { - saveFolder = DEFAULT_SAVE_DIRECTORY; - createSaveDirectory(DEFAULT_SAVE_DIRECTORY); + this(DEFAULT_SAVE_DIRECTORY); + } + + public Storage(String saveDirectory) { + saveFolder = saveDirectory; + createSaveDirectory(saveFolder); } private void createSaveDirectory(String directory) { File dir = new File(directory); if (!dir.exists()) { - dir.mkdir(); + boolean isDirectoryCreated = dir.mkdirs(); + if (!isDirectoryCreated) { + throw new RuntimeException("Could not create directory " + dir); + } } } diff --git a/src/main/java/tui/CollateTui.java b/src/main/java/tui/CollateTui.java index 03734ee..8556f6e 100644 --- a/src/main/java/tui/CollateTui.java +++ b/src/main/java/tui/CollateTui.java @@ -4,6 +4,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Scanner; +import java.util.StringJoiner; import main.java.backend.Logic; import main.java.data.Author; @@ -72,6 +73,29 @@ public class CollateTui { * @param args */ public static void main(String[] args) { + if (args.length == 0) { + runInteractiveMode(); + } else { + runBatchMode(args); + } + } + + private static void runBatchMode(String[] args) { + Logic logic = new Logic(); + String command = stitchArgs(args); + System.out.println("Executing command " + command); + logic.executeCommand(command); + } + + private static String stitchArgs(String args[]) { + StringJoiner joiner = new StringJoiner(" "); + for (String s: args) { + joiner.add(s); + } + return joiner.toString(); + } + + private static void runInteractiveMode() { Scanner input = new Scanner(System.in); PrintStream output = System.out; Logic logic = new Logic(); diff --git a/src/test/TestCommandParserAndCommand.java b/src/test/TestCommandParserAndCommand.java index ab80496..070a776 100644 --- a/src/test/TestCommandParserAndCommand.java +++ b/src/test/TestCommandParserAndCommand.java @@ -36,7 +36,7 @@ public void testCollateCommand() { // Normal collate command = commandParser.parse("collate from \"" + FULL_TEST_RES_DIR + "\""); assertEquals(Command.Type.COLLATE, command.getCommandType()); - assertEquals(FULL_TEST_RES_DIR, command.getDirectory()); + assertEquals(FULL_TEST_RES_DIR, command.getReadDirectory()); assertFalse(command.willScanCurrentDirOnly()); assertEquals(0, command.getFileTypes().size()); @@ -44,7 +44,7 @@ public void testCollateCommand() { command = commandParser.parse("collate from \"" + FULL_TEST_RES_DIR + "\""); assertEquals(Command.Type.COLLATE, command.getCommandType()); - assertEquals(FULL_TEST_RES_DIR, command.getDirectory()); + assertEquals(FULL_TEST_RES_DIR, command.getReadDirectory()); assertFalse(command.willScanCurrentDirOnly()); assertEquals(0, command.getFileTypes().size()); @@ -53,7 +53,7 @@ public void testCollateCommand() { File.separator + "subfolder with spaces\""); assertEquals(Command.Type.COLLATE, command.getCommandType()); assertEquals(FULL_TEST_RES_DIR + File.separator + "subfolder with spaces", - command.getDirectory()); + command.getReadDirectory()); assertFalse(command.willScanCurrentDirOnly()); assertEquals(0, command.getFileTypes().size()); @@ -61,7 +61,7 @@ public void testCollateCommand() { command = commandParser.parse("collate from \"" + FULL_TEST_RES_DIR + "\" only"); assertEquals(Command.Type.COLLATE, command.getCommandType()); - assertEquals(FULL_TEST_RES_DIR, command.getDirectory()); + assertEquals(FULL_TEST_RES_DIR, command.getReadDirectory()); assertTrue(command.willScanCurrentDirOnly()); assertEquals(0, command.getFileTypes().size()); @@ -70,7 +70,7 @@ public void testCollateCommand() { command = commandParser.parse("collate from \"" + FULL_TEST_RES_DIR + "\" include java, css"); assertEquals(Command.Type.COLLATE, command.getCommandType()); - assertEquals(FULL_TEST_RES_DIR, command.getDirectory()); + assertEquals(FULL_TEST_RES_DIR, command.getReadDirectory()); assertFalse(command.willScanCurrentDirOnly()); assertEquals(2, command.getFileTypes().size()); assertEquals("java", command.getFileTypes().get(0)); @@ -81,7 +81,7 @@ public void testCollateCommand() { command = commandParser.parse("collate include css, FXML from \"" + FULL_TEST_RES_DIR + "\""); assertEquals(Command.Type.COLLATE, command.getCommandType()); - assertEquals(FULL_TEST_RES_DIR, command.getDirectory()); + assertEquals(FULL_TEST_RES_DIR, command.getReadDirectory()); assertFalse(command.willScanCurrentDirOnly()); assertEquals(2, command.getFileTypes().size()); assertEquals("css", command.getFileTypes().get(0)); @@ -94,7 +94,7 @@ public void testCollateCommand() { "subfolder with spaces\" only"); assertEquals(Command.Type.COLLATE, command.getCommandType()); assertEquals(FULL_TEST_RES_DIR + File.separator + "subfolder with spaces", - command.getDirectory()); + command.getReadDirectory()); assertTrue(command.willScanCurrentDirOnly()); assertEquals(1, command.getFileTypes().size()); }