From 56b693a0edd6ad8303da12b1997a6b0fd0e74ff7 Mon Sep 17 00:00:00 2001 From: sikai00 Date: Sun, 5 Mar 2023 12:46:51 +0800 Subject: [PATCH 01/25] Add DES skeleton code --- .../java/reposense/wizard/BasicWizard.java | 8 + .../java/reposense/wizard/InputBuilder.java | 357 ++++++++++++++++++ src/main/java/reposense/wizard/Prompt.java | 43 +++ .../java/reposense/wizard/SincePrompt.java | 17 + src/main/java/reposense/wizard/Wizard.java | 20 + .../java/reposense/wizard/WizardRunner.java | 54 +++ .../reposense/wizard/WizardRunnerTest.java | 23 ++ 7 files changed, 522 insertions(+) create mode 100644 src/main/java/reposense/wizard/BasicWizard.java create mode 100644 src/main/java/reposense/wizard/InputBuilder.java create mode 100644 src/main/java/reposense/wizard/Prompt.java create mode 100644 src/main/java/reposense/wizard/SincePrompt.java create mode 100644 src/main/java/reposense/wizard/Wizard.java create mode 100644 src/main/java/reposense/wizard/WizardRunner.java create mode 100644 src/test/java/reposense/wizard/WizardRunnerTest.java diff --git a/src/main/java/reposense/wizard/BasicWizard.java b/src/main/java/reposense/wizard/BasicWizard.java new file mode 100644 index 0000000000..5d5ded26f1 --- /dev/null +++ b/src/main/java/reposense/wizard/BasicWizard.java @@ -0,0 +1,8 @@ +package reposense.wizard; + +public class BasicWizard extends Wizard { + private static final Prompt[] INITIAL_PROMPTS = new Prompt[] {new SincePrompt()}; + public BasicWizard() { + super(INITIAL_PROMPTS); + } +} diff --git a/src/main/java/reposense/wizard/InputBuilder.java b/src/main/java/reposense/wizard/InputBuilder.java new file mode 100644 index 0000000000..6b3b2ce4df --- /dev/null +++ b/src/main/java/reposense/wizard/InputBuilder.java @@ -0,0 +1,357 @@ +package reposense.wizard; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.StringTokenizer; + +import org.apache.tools.ant.BuildException; + +import reposense.parser.ArgsParser; + +/** + * A utility class to help with building command line input. + * Example usage:
+ * {@code String input = new InputBuilder().addSinceDate("27/01/2017").build();} + */ +public class InputBuilder { + private static final String WHITESPACE = " "; + + private StringBuilder input; + private boolean shallowCloning; + + public InputBuilder() { + init(); + } + + /** + * Initialize variables to default values. + * Used by {@link InputBuilder#InputBuilder() constructor} and {@link InputBuilder#reset() reset} method. + */ + private void init() { + input = new StringBuilder(); + shallowCloning = false; + } + + /** + * Returns the {@code input} generated from this {@link InputBuilder}. + */ + public String build() { + return input.toString(); + } + + /** + * Add a help flag to the input. + * This method should only be called once in one build. + */ + public InputBuilder addHelp() { + input.append(ArgsParser.HELP_FLAGS[0] + WHITESPACE); + return this; + } + + /** + * Adds the config flag with the {@code path} as argument to the input. + * This method should only be called once in one build. + * + * @param path The config folder path. + */ + public InputBuilder addConfig(Path path) { + input.append(ArgsParser.CONFIG_FLAGS[0] + WHITESPACE + addQuotationMarksToPath(path) + WHITESPACE); + return this; + } + + /** + * Adds the repo flag with the {@code paths} as arguments to the input. + * This method should only be called once in one build. + * + * @param paths The repo paths. + */ + public InputBuilder addRepos(String... paths) { + input.append(ArgsParser.REPO_FLAGS[0] + WHITESPACE); + for (String path : paths) { + input.append(addQuotationMarksToPath(path) + WHITESPACE); + } + return this; + } + + /** + * Adds the view flag with the {@code path} as argument to the input. + * This method should only be called once in one build. + * + * @param path The view folder path. + */ + public InputBuilder addView(Path path) { + input.append(ArgsParser.VIEW_FLAGS[0] + WHITESPACE + addQuotationMarksToPath(path) + WHITESPACE); + return this; + } + + /** + * Adds the view flag only to the input. + * This method should only be called once in one build. + */ + public InputBuilder addView() { + input.append(ArgsParser.VIEW_FLAGS[0] + WHITESPACE); + return this; + } + + /** + * Adds the output flag with the {@code path} as argument to the input. + * This method should only be called once in one build. + * + * @param path The output folder path (type {@link Path}). + */ + public InputBuilder addOutput(Path path) { + input.append(ArgsParser.OUTPUT_FLAGS[0] + WHITESPACE + addQuotationMarksToPath(path) + WHITESPACE); + return this; + } + + /** + * Adds the output flag with the {@code path} as argument to the input. + * This method should only be called once in one build. + * + * @param path The output folder path (type {@link String}). + */ + public InputBuilder addOutput(String path) { + return addOutput(Paths.get(path)); + } + + /** + * Adds the since flag with the {@code date} as argument to the input. + * This method should only be called once in one build. + * + * @param date The since date. + */ + public InputBuilder addSinceDate(String date) { + input.append(ArgsParser.SINCE_FLAGS[0] + WHITESPACE + date + WHITESPACE); + return this; + } + + /** + * Adds the until flag with the {@code date} as argument to the input. + * This method should only be called once in one build. + * + * @param date The until date. + */ + public InputBuilder addUntilDate(String date) { + input.append(ArgsParser.UNTIL_FLAGS[0] + WHITESPACE + date + WHITESPACE); + return this; + } + + /** + * Adds the period flag with the {@code period} as argument to the input. + * This method should only be called once in one build. + * + * @param period The period. + */ + public InputBuilder addPeriod(String period) { + input.append(ArgsParser.PERIOD_FLAGS[0] + WHITESPACE + period + WHITESPACE); + return this; + } + + /** + * Adds the format flag with the {@code formats} as argument to the input. + * This method should only be called once in one build. + * + * @param formats The formats that need to be evaluated. + */ + public InputBuilder addFormats(String formats) { + input.append(ArgsParser.FORMAT_FLAGS[0] + WHITESPACE + formats + WHITESPACE); + return this; + } + + /** + * Adds the ignoreStandaloneConfig flag to the input. + * This method should only be called once in one build. + */ + public InputBuilder addIgnoreStandaloneConfig() { + input.append(ArgsParser.IGNORE_CONFIG_FLAGS[0] + WHITESPACE); + return this; + } + + /** + * Adds the ignoreFilesizeLimit flag to the input. + * This method should only be called once in one build. + */ + public InputBuilder addIgnoreFilesizeLimit() { + input.append(ArgsParser.IGNORE_SIZELIMIT_FLAGS[0] + WHITESPACE); + return this; + } + + /** + * Adds the timezone flag with the {@code zoneId} as argument to the input. + * This method should only be called once in one build. + */ + public InputBuilder addTimezone(String zoneId) { + input.append(ArgsParser.TIMEZONE_FLAGS[0] + WHITESPACE + zoneId + WHITESPACE); + return this; + } + + /** + * Adds the cloning threads flag with the {@code threads} as argument to the input. + * This method should only be called once in one build. + * + * @param threads The number of threads for cloning. + */ + public InputBuilder addNumCloningThreads(int threads) { + input.append(ArgsParser.CLONING_THREADS_FLAG[0] + WHITESPACE + threads + WHITESPACE); + return this; + } + + /** + * Adds the analysis threads flag with the {@code threads} as argument to the input. + * This method should only be called once in one build. + * + * @param threads The number of threads for analysis. + */ + public InputBuilder addNumAnalysisThreads(int threads) { + input.append(ArgsParser.ANALYSIS_THREADS_FLAG[0] + WHITESPACE + threads + WHITESPACE); + return this; + } + + /** + * Adds the flag to enable shallow cloning. + * This method should only be called once in one build. + */ + public InputBuilder addShallowCloning() { + input.append(ArgsParser.SHALLOW_CLONING_FLAGS[0] + WHITESPACE); + shallowCloning = true; + return this; + } + + /** + * Adds the flag to enable find previous authors. + * This method should only be called once in one build. + */ + public InputBuilder addFindPreviousAuthors() { + input.append(ArgsParser.FIND_PREVIOUS_AUTHORS_FLAGS[0] + WHITESPACE); + return this; + } + + /** + * Adds the flag to enable test mode. + * This method should only be called once in one build. + */ + public InputBuilder addTestMode() { + input.append(ArgsParser.TEST_MODE_FLAG[0] + WHITESPACE); + return this; + } + + /** + * Adds the flag to include modified date in lines. + * This method should only be called once in one build. + */ + public InputBuilder addLastModifiedDateFlags() { + input.append(ArgsParser.LAST_MODIFIED_DATE_FLAGS[0] + WHITESPACE); + return this; + } + + /** + * Adds the flag to enable fresh cloning. + * This method should only be called once in one build. + */ + public InputBuilder addFreshCloning() { + input.append(ArgsParser.FRESH_CLONING_FLAG[0] + WHITESPACE); + return this; + } + + /** + * Adds {@code content} to the input. + */ + public InputBuilder add(String content) { + input.append(content + WHITESPACE); + return this; + } + + /** + * Adds {@code num} of white spaces to the input. + * + * @param num The number of white spaces to add. + */ + public InputBuilder addWhiteSpace(int num) { + for (int i = 0; i < num; i++) { + input.append(WHITESPACE); + } + return this; + } + + /** + * Clears all input and flags given. + */ + public InputBuilder reset() { + init(); + return this; + } + + private static String addQuotationMarksToPath(String path) { + return '"' + path + '"'; + } + + private static String addQuotationMarksToPath(Path path) { + return addQuotationMarksToPath(path.toString()); + } + + public boolean isShallowCloning() { + return shallowCloning; + } + + public static String[] translateCommandline(String toProcess) { + if (toProcess == null || toProcess.isEmpty()) { + //no command? no string + return new String[0]; + } + // parse with a simple finite state machine + + final int normal = 0; + final int inQuote = 1; + final int inDoubleQuote = 2; + int state = normal; + final StringTokenizer tok = new StringTokenizer(toProcess, "\"' ", true); + final ArrayList result = new ArrayList<>(); + final StringBuilder current = new StringBuilder(); + boolean lastTokenHasBeenQuoted = false; + + while (tok.hasMoreTokens()) { + String nextTok = tok.nextToken(); + switch (state) { + case inQuote: + if ("'".equals(nextTok)) { + lastTokenHasBeenQuoted = true; + state = normal; + } else { + current.append(nextTok); + } + break; + case inDoubleQuote: + if ("\"".equals(nextTok)) { + lastTokenHasBeenQuoted = true; + state = normal; + } else { + current.append(nextTok); + } + break; + default: + if ("'".equals(nextTok)) { + state = inQuote; + } else if ("\"".equals(nextTok)) { + state = inDoubleQuote; + } else if (" ".equals(nextTok)) { + if (lastTokenHasBeenQuoted || current.length() > 0) { + result.add(current.toString()); + current.setLength(0); + } + } else { + current.append(nextTok); + } + lastTokenHasBeenQuoted = false; + break; + } + } + if (lastTokenHasBeenQuoted || current.length() > 0) { + result.add(current.toString()); + } + if (state == inQuote || state == inDoubleQuote) { + throw new BuildException("unbalanced quotes in " + toProcess); + } + return result.toArray(new String[0]); + } +} diff --git a/src/main/java/reposense/wizard/Prompt.java b/src/main/java/reposense/wizard/Prompt.java new file mode 100644 index 0000000000..ec4b17f442 --- /dev/null +++ b/src/main/java/reposense/wizard/Prompt.java @@ -0,0 +1,43 @@ +package reposense.wizard; + +import java.util.Scanner; + +/** + * Represents an abstract prompt. + */ +public abstract class Prompt { + private final String question; + private final String description; + private String response; + + public Prompt(String question, String description) { + this.question = question; + this.description = description; + } + + public void promptAndGetInput(Scanner sc) { + System.out.println(this); + response = getInput(sc); + } + + private String getInput(Scanner sc) { + return sc.nextLine(); + } + + public String getResponse() { + return response; + } + + public abstract InputBuilder addToInput(InputBuilder inputBuilder); + + // each prompt may have additional effects depending on the prompt. + // when we run a prompt, the prompt will ask for input. + // for example, repos prompt will launch a vim window. + // a prompt may also create other prompts () (for example a open vim prompt) + public abstract Prompt[] run(); + + @Override + public String toString() { + return String.format("%s (%s): ", question, description); + } +} diff --git a/src/main/java/reposense/wizard/SincePrompt.java b/src/main/java/reposense/wizard/SincePrompt.java new file mode 100644 index 0000000000..1880407c79 --- /dev/null +++ b/src/main/java/reposense/wizard/SincePrompt.java @@ -0,0 +1,17 @@ +package reposense.wizard; + +public class SincePrompt extends Prompt { + public SincePrompt() { + super("Enter the start date for the period to be analyzed", "DD/MM/YYYY"); + } + + @Override + public InputBuilder addToInput(InputBuilder inputBuilder) { + return inputBuilder.addSinceDate(getResponse()); + } + + @Override + public Prompt[] run() { + return new Prompt[] {}; + } +} diff --git a/src/main/java/reposense/wizard/Wizard.java b/src/main/java/reposense/wizard/Wizard.java new file mode 100644 index 0000000000..04344f0b3d --- /dev/null +++ b/src/main/java/reposense/wizard/Wizard.java @@ -0,0 +1,20 @@ +package reposense.wizard; + +/** + * This class implements an abstract wizard. + * A concrete implementation of a wizard contains + * prompts specific to that wizard. + */ +public abstract class Wizard { + // contains the basic skeleton of the wizard. + + private final Prompt[] initialPrompts; + + public Wizard(Prompt[] initialPrompts) { + this.initialPrompts = initialPrompts; + } + + public Prompt[] getInitialPrompts() { + return initialPrompts; + }; +} diff --git a/src/main/java/reposense/wizard/WizardRunner.java b/src/main/java/reposense/wizard/WizardRunner.java new file mode 100644 index 0000000000..73b4fa6a5a --- /dev/null +++ b/src/main/java/reposense/wizard/WizardRunner.java @@ -0,0 +1,54 @@ +package reposense.wizard; + +import static reposense.wizard.InputBuilder.translateCommandline; + +import java.util.ArrayDeque; +import java.util.Queue; +import java.util.Scanner; + +import reposense.RepoSense; + +/** + * This class implements a wizard runner in the form + * of a discrete event simulator. + * It maintains a queue of prompts and run through + * the prompts until the queue is empty. + */ +public class WizardRunner { + private final Queue prompts; + private InputBuilder inputBuilder; + + public WizardRunner(Wizard wizard) { + prompts = new ArrayDeque<>(); + for (Prompt p : wizard.getInitialPrompts()) { + prompts.add(p); + } + inputBuilder = new InputBuilder(); + } + + /** + * Run the wizard until no more prompts is in the queue. + * If the wizard returns one or more prompts, add them + * to the queue, and repeat. + */ + public void buildInput(Scanner sc) { + Prompt prompt = prompts.poll(); + while (prompt != null) { + prompt.promptAndGetInput(sc); + inputBuilder = prompt.addToInput(inputBuilder); + Prompt[] newPrompts = prompt.run(); + for (Prompt p : newPrompts) { + prompts.add(p); + } + prompt = prompts.poll(); + } + } + + public String getBuiltInput() { + return inputBuilder.build(); + } + + public void run() { + RepoSense.main(translateCommandline(getBuiltInput())); + } +} diff --git a/src/test/java/reposense/wizard/WizardRunnerTest.java b/src/test/java/reposense/wizard/WizardRunnerTest.java new file mode 100644 index 0000000000..bca2b0e703 --- /dev/null +++ b/src/test/java/reposense/wizard/WizardRunnerTest.java @@ -0,0 +1,23 @@ +package reposense.wizard; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Scanner; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class WizardRunnerTest { + @Test + public void buildInput_sinceOnly_success() { + WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); + String initialString = "30/09/2022\n"; + InputStream targetStream = new ByteArrayInputStream(initialString.getBytes()); + Scanner sc = new Scanner(targetStream); + wizardRunner.buildInput(sc); + + String expectedInput = new InputBuilder().addSinceDate("30/09/2022").build(); + assertEquals(expectedInput, wizardRunner.getBuiltInput()); + } +} From 306d157b507dac87798503df5c57575abc2d68d8 Mon Sep 17 00:00:00 2001 From: sikai00 Date: Sun, 5 Mar 2023 13:17:07 +0800 Subject: [PATCH 02/25] Add docs --- src/main/java/reposense/wizard/BasicWizard.java | 3 +++ src/main/java/reposense/wizard/InputBuilder.java | 8 ++++++++ src/main/java/reposense/wizard/Prompt.java | 5 +++++ src/main/java/reposense/wizard/SincePrompt.java | 3 +++ 4 files changed, 19 insertions(+) diff --git a/src/main/java/reposense/wizard/BasicWizard.java b/src/main/java/reposense/wizard/BasicWizard.java index 5d5ded26f1..4e53aa3090 100644 --- a/src/main/java/reposense/wizard/BasicWizard.java +++ b/src/main/java/reposense/wizard/BasicWizard.java @@ -1,5 +1,8 @@ package reposense.wizard; +/** + * Represents a basic wizard run. + */ public class BasicWizard extends Wizard { private static final Prompt[] INITIAL_PROMPTS = new Prompt[] {new SincePrompt()}; public BasicWizard() { diff --git a/src/main/java/reposense/wizard/InputBuilder.java b/src/main/java/reposense/wizard/InputBuilder.java index 6b3b2ce4df..f44e69b226 100644 --- a/src/main/java/reposense/wizard/InputBuilder.java +++ b/src/main/java/reposense/wizard/InputBuilder.java @@ -294,6 +294,14 @@ public boolean isShallowCloning() { return shallowCloning; } + /** + * Crack a command line. + * + * @param toProcess the command line to process. + * @return the command line broken into strings. + * @throws BuildException if there are unbalanced quotes. + * An empty or null toProcess parameter results in a zero sized array. + */ public static String[] translateCommandline(String toProcess) { if (toProcess == null || toProcess.isEmpty()) { //no command? no string diff --git a/src/main/java/reposense/wizard/Prompt.java b/src/main/java/reposense/wizard/Prompt.java index ec4b17f442..b09450ac70 100644 --- a/src/main/java/reposense/wizard/Prompt.java +++ b/src/main/java/reposense/wizard/Prompt.java @@ -15,6 +15,11 @@ public Prompt(String question, String description) { this.description = description; } + /** + * Prompts the user for an input and stores it in response. + * + * @param sc Scanner that takes in the input + */ public void promptAndGetInput(Scanner sc) { System.out.println(this); response = getInput(sc); diff --git a/src/main/java/reposense/wizard/SincePrompt.java b/src/main/java/reposense/wizard/SincePrompt.java index 1880407c79..fd52c201e4 100644 --- a/src/main/java/reposense/wizard/SincePrompt.java +++ b/src/main/java/reposense/wizard/SincePrompt.java @@ -1,5 +1,8 @@ package reposense.wizard; +/** + * Represents a Prompt to get the sinceDate flag. + */ public class SincePrompt extends Prompt { public SincePrompt() { super("Enter the start date for the period to be analyzed", "DD/MM/YYYY"); From a26facc55cb1f6fdd0d7e31774ce1974924c2d9b Mon Sep 17 00:00:00 2001 From: sikai00 Date: Sun, 5 Mar 2023 13:20:44 +0800 Subject: [PATCH 03/25] Fix import groups in test --- src/test/java/reposense/wizard/WizardRunnerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/reposense/wizard/WizardRunnerTest.java b/src/test/java/reposense/wizard/WizardRunnerTest.java index bca2b0e703..5309bf010b 100644 --- a/src/test/java/reposense/wizard/WizardRunnerTest.java +++ b/src/test/java/reposense/wizard/WizardRunnerTest.java @@ -1,13 +1,13 @@ package reposense.wizard; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.Scanner; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; - public class WizardRunnerTest { @Test public void buildInput_sinceOnly_success() { From 534ed26f865d4e664b699502b955e418ea9528fc Mon Sep 17 00:00:00 2001 From: sikai00 Date: Mon, 6 Mar 2023 13:16:31 +0800 Subject: [PATCH 04/25] Fix prompt adding ordering --- src/main/java/reposense/wizard/WizardRunner.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/reposense/wizard/WizardRunner.java b/src/main/java/reposense/wizard/WizardRunner.java index 73b4fa6a5a..885fb697ff 100644 --- a/src/main/java/reposense/wizard/WizardRunner.java +++ b/src/main/java/reposense/wizard/WizardRunner.java @@ -3,7 +3,7 @@ import static reposense.wizard.InputBuilder.translateCommandline; import java.util.ArrayDeque; -import java.util.Queue; +import java.util.Deque; import java.util.Scanner; import reposense.RepoSense; @@ -15,7 +15,7 @@ * the prompts until the queue is empty. */ public class WizardRunner { - private final Queue prompts; + private final Deque prompts; private InputBuilder inputBuilder; public WizardRunner(Wizard wizard) { @@ -37,8 +37,8 @@ public void buildInput(Scanner sc) { prompt.promptAndGetInput(sc); inputBuilder = prompt.addToInput(inputBuilder); Prompt[] newPrompts = prompt.run(); - for (Prompt p : newPrompts) { - prompts.add(p); + for (int i = newPrompts.length - 1; i >= 0; i--) { + prompts.addFirst(newPrompts[i]); } prompt = prompts.poll(); } From bcf29ca5d2e905c85996a88310ad69e28fd4468f Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Sat, 11 Mar 2023 03:18:12 +0800 Subject: [PATCH 05/25] Add wizard cli flag to ArgsParser --- src/main/java/reposense/RepoSense.java | 18 +++++------ .../reposense/model/WizardCliArguments.java | 7 ++++ .../java/reposense/parser/ArgsParser.java | 19 +++++++---- .../java/reposense/wizard/OptionalPrompt.java | 32 +++++++++++++++++++ .../java/reposense/wizard/ViewPrompt.java | 20 ++++++++++++ 5 files changed, 81 insertions(+), 15 deletions(-) create mode 100644 src/main/java/reposense/model/WizardCliArguments.java create mode 100644 src/main/java/reposense/wizard/OptionalPrompt.java create mode 100644 src/main/java/reposense/wizard/ViewPrompt.java diff --git a/src/main/java/reposense/RepoSense.java b/src/main/java/reposense/RepoSense.java index 62c476dec7..6fc6557f87 100644 --- a/src/main/java/reposense/RepoSense.java +++ b/src/main/java/reposense/RepoSense.java @@ -7,6 +7,7 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; +import java.util.Scanner; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.Logger; @@ -14,15 +15,7 @@ import net.sourceforge.argparse4j.helper.HelpScreenException; import reposense.git.GitConfig; import reposense.git.GitVersion; -import reposense.model.AuthorConfiguration; -import reposense.model.CliArguments; -import reposense.model.ConfigCliArguments; -import reposense.model.GroupConfiguration; -import reposense.model.LocationsCliArguments; -import reposense.model.RepoConfiguration; -import reposense.model.RepoLocation; -import reposense.model.ReportConfiguration; -import reposense.model.ViewCliArguments; +import reposense.model.*; import reposense.parser.ArgsParser; import reposense.parser.AuthorConfigCsvParser; import reposense.parser.GroupConfigCsvParser; @@ -36,6 +29,8 @@ import reposense.system.ReportServer; import reposense.util.FileUtil; import reposense.util.TimeUtil; +import reposense.wizard.BasicWizard; +import reposense.wizard.WizardRunner; /** * The main RepoSense class. @@ -68,6 +63,11 @@ public static void main(String[] args) { reportConfig = ((ConfigCliArguments) cliArguments).getReportConfiguration(); } else if (cliArguments instanceof LocationsCliArguments) { configs = getRepoConfigurations((LocationsCliArguments) cliArguments); + } else if (cliArguments instanceof WizardCliArguments) { + WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); + wizardRunner.buildInput(new Scanner(System.in)); + wizardRunner.run(); + return; } else { throw new AssertionError("CliArguments's subclass type is unhandled."); } diff --git a/src/main/java/reposense/model/WizardCliArguments.java b/src/main/java/reposense/model/WizardCliArguments.java new file mode 100644 index 0000000000..39e2d78e64 --- /dev/null +++ b/src/main/java/reposense/model/WizardCliArguments.java @@ -0,0 +1,7 @@ +package reposense.model; + +/** + * Represents command line arguments user supplied when running the program with mandatory field -init. + */ +public class WizardCliArguments extends CliArguments { +} diff --git a/src/main/java/reposense/parser/ArgsParser.java b/src/main/java/reposense/parser/ArgsParser.java index b39f048522..97a1601ae1 100644 --- a/src/main/java/reposense/parser/ArgsParser.java +++ b/src/main/java/reposense/parser/ArgsParser.java @@ -25,12 +25,7 @@ import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup; import net.sourceforge.argparse4j.inf.Namespace; import reposense.RepoSense; -import reposense.model.CliArguments; -import reposense.model.ConfigCliArguments; -import reposense.model.FileType; -import reposense.model.LocationsCliArguments; -import reposense.model.ReportConfiguration; -import reposense.model.ViewCliArguments; +import reposense.model.*; import reposense.system.LogsManager; import reposense.util.TimeUtil; @@ -65,6 +60,8 @@ public class ArgsParser { public static final String[] CLONING_THREADS_FLAG = new String[] {"--cloning-threads"}; public static final String[] ANALYSIS_THREADS_FLAG = new String[] {"--analysis-threads"}; + public static final String[] CLI_WIZARD_FLAGS = new String[] {"--init"}; + public static final String[] TEST_MODE_FLAG = new String[] {"--test-mode"}; public static final String[] FRESH_CLONING_FLAG = new String[] {"--fresh-cloning"}; @@ -239,6 +236,11 @@ private static ArgumentParser getArgumentParser() { .setDefault(DEFAULT_NUM_ANALYSIS_THREADS) .help(FeatureControl.SUPPRESS); + parser.addArgument(CLI_WIZARD_FLAGS) + .dest(CLI_WIZARD_FLAGS[0]) + .action(Arguments.storeTrue()) + .help("Launches the RepoSense Command line wizard to walk through the basic setup."); + // Testing flags argumentGroup.addArgument(TEST_MODE_FLAG) .dest(TEST_MODE_FLAG[0]) @@ -283,6 +285,11 @@ public static CliArguments parse(String[] args) throws HelpScreenException, Pars boolean shouldIncludeLastModifiedDate = results.get(LAST_MODIFIED_DATE_FLAGS[0]); boolean shouldPerformShallowCloning = results.get(SHALLOW_CLONING_FLAGS[0]); boolean shouldFindPreviousAuthors = results.get(FIND_PREVIOUS_AUTHORS_FLAGS[0]); + boolean isWizardCli = results.get(CLI_WIZARD_FLAGS[0]); + + if (isWizardCli) { + return new WizardCliArguments(); + } // Report config is ignored if --repos is provided if (locations == null) { diff --git a/src/main/java/reposense/wizard/OptionalPrompt.java b/src/main/java/reposense/wizard/OptionalPrompt.java new file mode 100644 index 0000000000..bfafefadd0 --- /dev/null +++ b/src/main/java/reposense/wizard/OptionalPrompt.java @@ -0,0 +1,32 @@ +package reposense.wizard; + +/** + * Represents a Prompt to get the view flag. + */ + + +public class OptionalPrompt extends Prompt { + private final Prompt prompt; + private final static String YES_FLAG = "Y"; + private final static String NO_FLAG = "N"; + private final static String DESCRIPTION = YES_FLAG + "/" + NO_FLAG; + + public OptionalPrompt(String question, Prompt prompt) { + super(question, DESCRIPTION); + this.prompt = prompt; + } + + @Override + public InputBuilder addToInput(InputBuilder inputBuilder) { + return inputBuilder; + } + + @Override + public Prompt[] run() { + if (getResponse().compareToIgnoreCase(YES_FLAG) == 0) { + + } + + return new Prompt[] {}; + } +} diff --git a/src/main/java/reposense/wizard/ViewPrompt.java b/src/main/java/reposense/wizard/ViewPrompt.java new file mode 100644 index 0000000000..fd52c201e4 --- /dev/null +++ b/src/main/java/reposense/wizard/ViewPrompt.java @@ -0,0 +1,20 @@ +package reposense.wizard; + +/** + * Represents a Prompt to get the sinceDate flag. + */ +public class SincePrompt extends Prompt { + public SincePrompt() { + super("Enter the start date for the period to be analyzed", "DD/MM/YYYY"); + } + + @Override + public InputBuilder addToInput(InputBuilder inputBuilder) { + return inputBuilder.addSinceDate(getResponse()); + } + + @Override + public Prompt[] run() { + return new Prompt[] {}; + } +} From 96c24c684263c61380388030aa3bfd12ad48a817 Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Sat, 11 Mar 2023 03:19:12 +0800 Subject: [PATCH 06/25] Add view prompt and optional prompt --- src/main/java/reposense/wizard/BasicWizard.java | 5 ++++- .../java/reposense/wizard/OptionalPrompt.java | 13 ++++++++----- src/main/java/reposense/wizard/Prompt.java | 14 +++++++++++++- src/main/java/reposense/wizard/ViewPrompt.java | 17 ++++++++++++----- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/main/java/reposense/wizard/BasicWizard.java b/src/main/java/reposense/wizard/BasicWizard.java index 4e53aa3090..cae832594c 100644 --- a/src/main/java/reposense/wizard/BasicWizard.java +++ b/src/main/java/reposense/wizard/BasicWizard.java @@ -4,7 +4,10 @@ * Represents a basic wizard run. */ public class BasicWizard extends Wizard { - private static final Prompt[] INITIAL_PROMPTS = new Prompt[] {new SincePrompt()}; + private static final Prompt[] INITIAL_PROMPTS = new Prompt[] { + new SincePrompt(), + new OptionalPrompt(ViewPrompt.OPTIONAL_PROMPT, new ViewPrompt()) + }; public BasicWizard() { super(INITIAL_PROMPTS); } diff --git a/src/main/java/reposense/wizard/OptionalPrompt.java b/src/main/java/reposense/wizard/OptionalPrompt.java index bfafefadd0..5806ba4fa8 100644 --- a/src/main/java/reposense/wizard/OptionalPrompt.java +++ b/src/main/java/reposense/wizard/OptionalPrompt.java @@ -1,15 +1,13 @@ package reposense.wizard; /** - * Represents a Prompt to get the view flag. + * Represents an optional prompt that only calls the provided prompt if requested by the user. */ - - public class OptionalPrompt extends Prompt { private final Prompt prompt; private final static String YES_FLAG = "Y"; private final static String NO_FLAG = "N"; - private final static String DESCRIPTION = YES_FLAG + "/" + NO_FLAG; + private final static String DESCRIPTION = String.format("%s/%s", YES_FLAG, NO_FLAG); public OptionalPrompt(String question, Prompt prompt) { super(question, DESCRIPTION); @@ -24,9 +22,14 @@ public InputBuilder addToInput(InputBuilder inputBuilder) { @Override public Prompt[] run() { if (getResponse().compareToIgnoreCase(YES_FLAG) == 0) { + return new Prompt[] {this.prompt}; + } + if (getResponse().compareToIgnoreCase(NO_FLAG) == 0) { + return new Prompt[] {}; } - return new Prompt[] {}; + // Repeat OptionalPrompt until a valid flag is provided + return new Prompt[] {new OptionalPrompt(this.getQuestion(), this.prompt)}; } } diff --git a/src/main/java/reposense/wizard/Prompt.java b/src/main/java/reposense/wizard/Prompt.java index b09450ac70..748424a510 100644 --- a/src/main/java/reposense/wizard/Prompt.java +++ b/src/main/java/reposense/wizard/Prompt.java @@ -15,6 +15,11 @@ public Prompt(String question, String description) { this.description = description; } + public Prompt(String question) { + this.question = question; + this.description = ""; + } + /** * Prompts the user for an input and stores it in response. * @@ -30,7 +35,11 @@ private String getInput(Scanner sc) { } public String getResponse() { - return response; + return response.trim(); + } + + public String getQuestion() { + return question; } public abstract InputBuilder addToInput(InputBuilder inputBuilder); @@ -43,6 +52,9 @@ public String getResponse() { @Override public String toString() { + if (description.isEmpty()) { + return String.format("%s: ", question); + } return String.format("%s (%s): ", question, description); } } diff --git a/src/main/java/reposense/wizard/ViewPrompt.java b/src/main/java/reposense/wizard/ViewPrompt.java index fd52c201e4..bb7d234869 100644 --- a/src/main/java/reposense/wizard/ViewPrompt.java +++ b/src/main/java/reposense/wizard/ViewPrompt.java @@ -1,16 +1,23 @@ package reposense.wizard; /** - * Represents a Prompt to get the sinceDate flag. + * Represents a Prompt to get the view flag. */ -public class SincePrompt extends Prompt { - public SincePrompt() { - super("Enter the start date for the period to be analyzed", "DD/MM/YYYY"); +import java.nio.file.Paths; + +public class ViewPrompt extends Prompt { + public static final String OPTIONAL_PROMPT = "Do you want to start a server to display the report?"; + + public ViewPrompt() { + super("Enter directory of report to display in server. If not specified, default directory will be used."); } @Override public InputBuilder addToInput(InputBuilder inputBuilder) { - return inputBuilder.addSinceDate(getResponse()); + if (getResponse().isEmpty()) { + return inputBuilder.addView(); + } + return inputBuilder.addView(Paths.get(getResponse())); } @Override From 9b39e501251f7308f332780b14e724b5be1d31b9 Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Sat, 11 Mar 2023 04:13:16 +0800 Subject: [PATCH 07/25] Add repo prompt and update since prompt to be optinal --- .../java/reposense/wizard/BasicWizard.java | 5 +++-- .../java/reposense/wizard/InputBuilder.java | 7 ++----- .../java/reposense/wizard/RepoPrompt.java | 19 +++++++++++++++++++ .../java/reposense/wizard/SincePrompt.java | 3 +++ .../java/reposense/wizard/ViewPrompt.java | 2 +- 5 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 src/main/java/reposense/wizard/RepoPrompt.java diff --git a/src/main/java/reposense/wizard/BasicWizard.java b/src/main/java/reposense/wizard/BasicWizard.java index cae832594c..b0254c1899 100644 --- a/src/main/java/reposense/wizard/BasicWizard.java +++ b/src/main/java/reposense/wizard/BasicWizard.java @@ -5,8 +5,9 @@ */ public class BasicWizard extends Wizard { private static final Prompt[] INITIAL_PROMPTS = new Prompt[] { - new SincePrompt(), - new OptionalPrompt(ViewPrompt.OPTIONAL_PROMPT, new ViewPrompt()) + new OptionalPrompt(SincePrompt.OPTIONAL_PROMPT, new SincePrompt()), + new OptionalPrompt(ViewPrompt.OPTIONAL_PROMPT, new ViewPrompt()), + new RepoPrompt() }; public BasicWizard() { super(INITIAL_PROMPTS); diff --git a/src/main/java/reposense/wizard/InputBuilder.java b/src/main/java/reposense/wizard/InputBuilder.java index f44e69b226..0c6edb2609 100644 --- a/src/main/java/reposense/wizard/InputBuilder.java +++ b/src/main/java/reposense/wizard/InputBuilder.java @@ -66,11 +66,8 @@ public InputBuilder addConfig(Path path) { * * @param paths The repo paths. */ - public InputBuilder addRepos(String... paths) { - input.append(ArgsParser.REPO_FLAGS[0] + WHITESPACE); - for (String path : paths) { - input.append(addQuotationMarksToPath(path) + WHITESPACE); - } + public InputBuilder addRepos(String paths) { + input.append(ArgsParser.REPO_FLAGS[0] + WHITESPACE + paths); return this; } diff --git a/src/main/java/reposense/wizard/RepoPrompt.java b/src/main/java/reposense/wizard/RepoPrompt.java new file mode 100644 index 0000000000..4e821ddcf9 --- /dev/null +++ b/src/main/java/reposense/wizard/RepoPrompt.java @@ -0,0 +1,19 @@ +package reposense.wizard; +/** + * Represents a Prompt to get the repo flag. + */ +public class RepoPrompt extends Prompt { + public RepoPrompt() { + super("Enter a list of URLs or the disk location of the git repositories to analyze, separated by spaces"); + } + + @Override + public InputBuilder addToInput(InputBuilder inputBuilder) { + return inputBuilder.addRepos(getResponse()); + } + + @Override + public Prompt[] run() { + return new Prompt[] {}; + } +} diff --git a/src/main/java/reposense/wizard/SincePrompt.java b/src/main/java/reposense/wizard/SincePrompt.java index fd52c201e4..2af78a1162 100644 --- a/src/main/java/reposense/wizard/SincePrompt.java +++ b/src/main/java/reposense/wizard/SincePrompt.java @@ -4,6 +4,9 @@ * Represents a Prompt to get the sinceDate flag. */ public class SincePrompt extends Prompt { + public static final String OPTIONAL_PROMPT = "Do you want to specify the start date for the period to be" + + " analyzed? The default is one month before the current date"; + public SincePrompt() { super("Enter the start date for the period to be analyzed", "DD/MM/YYYY"); } diff --git a/src/main/java/reposense/wizard/ViewPrompt.java b/src/main/java/reposense/wizard/ViewPrompt.java index bb7d234869..af2054e610 100644 --- a/src/main/java/reposense/wizard/ViewPrompt.java +++ b/src/main/java/reposense/wizard/ViewPrompt.java @@ -9,7 +9,7 @@ public class ViewPrompt extends Prompt { public static final String OPTIONAL_PROMPT = "Do you want to start a server to display the report?"; public ViewPrompt() { - super("Enter directory of report to display in server. If not specified, default directory will be used."); + super("Enter directory of report to display in server. If not specified, default directory will be used"); } @Override From d30c0e8781feb263ca69282a00956febf6aba5bf Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Sat, 11 Mar 2023 04:13:56 +0800 Subject: [PATCH 08/25] Fix java.util.NoSuchElementException when running wizard via gradle --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 2c4a73705e..b6a5d2c680 100644 --- a/build.gradle +++ b/build.gradle @@ -88,6 +88,7 @@ run { tasks.compileJava.mustRunAfter(zipReport) args System.getProperty('args', '').split() systemProperty "version", getRepoSenseVersion() + standardInput = System.in } checkstyle { From a713677e964ce49e93d4ed204e157a1384594fd1 Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Sat, 11 Mar 2023 04:37:23 +0800 Subject: [PATCH 09/25] Fix import wildcard --- src/main/java/reposense/RepoSense.java | 11 ++++++++++- src/main/java/reposense/parser/ArgsParser.java | 8 +++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/reposense/RepoSense.java b/src/main/java/reposense/RepoSense.java index 6fc6557f87..3178bf4df2 100644 --- a/src/main/java/reposense/RepoSense.java +++ b/src/main/java/reposense/RepoSense.java @@ -15,7 +15,16 @@ import net.sourceforge.argparse4j.helper.HelpScreenException; import reposense.git.GitConfig; import reposense.git.GitVersion; -import reposense.model.*; +import reposense.model.AuthorConfiguration; +import reposense.model.CliArguments; +import reposense.model.ConfigCliArguments; +import reposense.model.GroupConfiguration; +import reposense.model.LocationsCliArguments; +import reposense.model.RepoConfiguration; +import reposense.model.RepoLocation; +import reposense.model.ReportConfiguration; +import reposense.model.ViewCliArguments; +import reposense.model.WizardCliArguments; import reposense.parser.ArgsParser; import reposense.parser.AuthorConfigCsvParser; import reposense.parser.GroupConfigCsvParser; diff --git a/src/main/java/reposense/parser/ArgsParser.java b/src/main/java/reposense/parser/ArgsParser.java index 97a1601ae1..f0a288dc94 100644 --- a/src/main/java/reposense/parser/ArgsParser.java +++ b/src/main/java/reposense/parser/ArgsParser.java @@ -25,7 +25,13 @@ import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup; import net.sourceforge.argparse4j.inf.Namespace; import reposense.RepoSense; -import reposense.model.*; +import reposense.model.CliArguments; +import reposense.model.ConfigCliArguments; +import reposense.model.FileType; +import reposense.model.LocationsCliArguments; +import reposense.model.ReportConfiguration; +import reposense.model.ViewCliArguments; +import reposense.model.WizardCliArguments; import reposense.system.LogsManager; import reposense.util.TimeUtil; From 9a62d2468c316d3155c25602e8e2b398f5c0a637 Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Sun, 12 Mar 2023 17:36:15 +0800 Subject: [PATCH 10/25] Refactor optinal prompt and Update prompt field names --- .../java/reposense/wizard/BasicWizard.java | 4 ++-- .../java/reposense/wizard/OptionalPrompt.java | 21 +++++++++--------- .../reposense/wizard/OptionalSincePrompt.java | 18 +++++++++++++++ .../reposense/wizard/OptionalViewPrompt.java | 17 ++++++++++++++ src/main/java/reposense/wizard/Prompt.java | 22 ++++++++----------- .../java/reposense/wizard/RepoPrompt.java | 6 ++++- .../java/reposense/wizard/SincePrompt.java | 6 ++--- .../java/reposense/wizard/ViewPrompt.java | 5 +++-- 8 files changed, 68 insertions(+), 31 deletions(-) create mode 100644 src/main/java/reposense/wizard/OptionalSincePrompt.java create mode 100644 src/main/java/reposense/wizard/OptionalViewPrompt.java diff --git a/src/main/java/reposense/wizard/BasicWizard.java b/src/main/java/reposense/wizard/BasicWizard.java index b0254c1899..a8cd7d3e5f 100644 --- a/src/main/java/reposense/wizard/BasicWizard.java +++ b/src/main/java/reposense/wizard/BasicWizard.java @@ -5,8 +5,8 @@ */ public class BasicWizard extends Wizard { private static final Prompt[] INITIAL_PROMPTS = new Prompt[] { - new OptionalPrompt(SincePrompt.OPTIONAL_PROMPT, new SincePrompt()), - new OptionalPrompt(ViewPrompt.OPTIONAL_PROMPT, new ViewPrompt()), + new OptionalSincePrompt(), + new OptionalViewPrompt(), new RepoPrompt() }; public BasicWizard() { diff --git a/src/main/java/reposense/wizard/OptionalPrompt.java b/src/main/java/reposense/wizard/OptionalPrompt.java index 5806ba4fa8..07b6c52ff8 100644 --- a/src/main/java/reposense/wizard/OptionalPrompt.java +++ b/src/main/java/reposense/wizard/OptionalPrompt.java @@ -3,33 +3,34 @@ /** * Represents an optional prompt that only calls the provided prompt if requested by the user. */ -public class OptionalPrompt extends Prompt { - private final Prompt prompt; +public abstract class OptionalPrompt extends Prompt { private final static String YES_FLAG = "Y"; private final static String NO_FLAG = "N"; - private final static String DESCRIPTION = String.format("%s/%s", YES_FLAG, NO_FLAG); + private final static String FORMAT = String.format("%s/%s", YES_FLAG, NO_FLAG); - public OptionalPrompt(String question, Prompt prompt) { - super(question, DESCRIPTION); - this.prompt = prompt; + public OptionalPrompt(String description) { + super(description, FORMAT); } + // optionally run array of Prompts if YES_FLAG is provided as input + public abstract Prompt[] optionallyRun(); + @Override public InputBuilder addToInput(InputBuilder inputBuilder) { - return inputBuilder; + return inputBuilder.addRepos(getResponse()); } @Override public Prompt[] run() { if (getResponse().compareToIgnoreCase(YES_FLAG) == 0) { - return new Prompt[] {this.prompt}; + return optionallyRun(); } if (getResponse().compareToIgnoreCase(NO_FLAG) == 0) { return new Prompt[] {}; } - // Repeat OptionalPrompt until a valid flag is provided - return new Prompt[] {new OptionalPrompt(this.getQuestion(), this.prompt)}; + // Repeat OptionalPrompt until a valid input is provided + return new Prompt[] {this}; } } diff --git a/src/main/java/reposense/wizard/OptionalSincePrompt.java b/src/main/java/reposense/wizard/OptionalSincePrompt.java new file mode 100644 index 0000000000..a7a269f6ec --- /dev/null +++ b/src/main/java/reposense/wizard/OptionalSincePrompt.java @@ -0,0 +1,18 @@ +package reposense.wizard; + +/** + * Represents an Optional Prompt to get the sinceDate flag. + */ +public class OptionalSincePrompt extends OptionalPrompt { + private static final String DESCRIPTION = "Do you want to specify the start date for the period to be analyzed? " + + "The default is one month before the current date"; + + public OptionalSincePrompt() { + super(DESCRIPTION); + } + + @Override + public Prompt[] optionallyRun() { + return new Prompt[]{new SincePrompt()}; + } +} \ No newline at end of file diff --git a/src/main/java/reposense/wizard/OptionalViewPrompt.java b/src/main/java/reposense/wizard/OptionalViewPrompt.java new file mode 100644 index 0000000000..3172a71eb1 --- /dev/null +++ b/src/main/java/reposense/wizard/OptionalViewPrompt.java @@ -0,0 +1,17 @@ +package reposense.wizard; + +/** + * Represents an Optional Prompt to get the view flag. + */ +public class OptionalViewPrompt extends OptionalPrompt { + private static final String DESCRIPTION = "Do you want to start a server to display the report?"; + + public OptionalViewPrompt() { + super(DESCRIPTION); + } + + @Override + public Prompt[] optionallyRun() { + return new Prompt[]{new ViewPrompt()}; + } +} diff --git a/src/main/java/reposense/wizard/Prompt.java b/src/main/java/reposense/wizard/Prompt.java index 748424a510..278cb7825e 100644 --- a/src/main/java/reposense/wizard/Prompt.java +++ b/src/main/java/reposense/wizard/Prompt.java @@ -6,18 +6,18 @@ * Represents an abstract prompt. */ public abstract class Prompt { - private final String question; private final String description; + private final String format; private String response; - public Prompt(String question, String description) { - this.question = question; + public Prompt(String description, String format) { this.description = description; + this.format = format; } - public Prompt(String question) { - this.question = question; - this.description = ""; + public Prompt(String description) { + this.description = description; + this.format = ""; } /** @@ -38,10 +38,6 @@ public String getResponse() { return response.trim(); } - public String getQuestion() { - return question; - } - public abstract InputBuilder addToInput(InputBuilder inputBuilder); // each prompt may have additional effects depending on the prompt. @@ -52,9 +48,9 @@ public String getQuestion() { @Override public String toString() { - if (description.isEmpty()) { - return String.format("%s: ", question); + if (format.isEmpty()) { + return String.format("%s: ", description); } - return String.format("%s (%s): ", question, description); + return String.format("%s (%s): ", description, format); } } diff --git a/src/main/java/reposense/wizard/RepoPrompt.java b/src/main/java/reposense/wizard/RepoPrompt.java index 4e821ddcf9..128a6e44dd 100644 --- a/src/main/java/reposense/wizard/RepoPrompt.java +++ b/src/main/java/reposense/wizard/RepoPrompt.java @@ -1,10 +1,14 @@ package reposense.wizard; + /** * Represents a Prompt to get the repo flag. */ public class RepoPrompt extends Prompt { + private static final String DESCRIPTION = "Enter a list of URLs or the disk location of the git repositories " + + "to analyze, separated by spaces"; + public RepoPrompt() { - super("Enter a list of URLs or the disk location of the git repositories to analyze, separated by spaces"); + super(DESCRIPTION); } @Override diff --git a/src/main/java/reposense/wizard/SincePrompt.java b/src/main/java/reposense/wizard/SincePrompt.java index 2af78a1162..bbffa101b2 100644 --- a/src/main/java/reposense/wizard/SincePrompt.java +++ b/src/main/java/reposense/wizard/SincePrompt.java @@ -4,11 +4,11 @@ * Represents a Prompt to get the sinceDate flag. */ public class SincePrompt extends Prompt { - public static final String OPTIONAL_PROMPT = "Do you want to specify the start date for the period to be" + - " analyzed? The default is one month before the current date"; + private static final String DESCRIPTION = "Enter the start date for the period to be analyzed"; + private static final String FORMAT = "DD/MM/YYYY"; public SincePrompt() { - super("Enter the start date for the period to be analyzed", "DD/MM/YYYY"); + super(DESCRIPTION, FORMAT); } @Override diff --git a/src/main/java/reposense/wizard/ViewPrompt.java b/src/main/java/reposense/wizard/ViewPrompt.java index af2054e610..03723996fd 100644 --- a/src/main/java/reposense/wizard/ViewPrompt.java +++ b/src/main/java/reposense/wizard/ViewPrompt.java @@ -6,10 +6,11 @@ import java.nio.file.Paths; public class ViewPrompt extends Prompt { - public static final String OPTIONAL_PROMPT = "Do you want to start a server to display the report?"; + public static final String DESCRIPTION = "Enter directory of report to display in server. " + + "If not specified, default directory will be used"; public ViewPrompt() { - super("Enter directory of report to display in server. If not specified, default directory will be used"); + super(DESCRIPTION); } @Override From 181a62cefb6fa990e7de55d6073b10df1ddfdaf3 Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Sun, 12 Mar 2023 17:41:08 +0800 Subject: [PATCH 11/25] Update optional prompt --- src/main/java/reposense/wizard/OptionalPrompt.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/reposense/wizard/OptionalPrompt.java b/src/main/java/reposense/wizard/OptionalPrompt.java index 07b6c52ff8..d60bc6390f 100644 --- a/src/main/java/reposense/wizard/OptionalPrompt.java +++ b/src/main/java/reposense/wizard/OptionalPrompt.java @@ -17,7 +17,7 @@ public OptionalPrompt(String description) { @Override public InputBuilder addToInput(InputBuilder inputBuilder) { - return inputBuilder.addRepos(getResponse()); + return inputBuilder; } @Override From 15577ae5974f87bbe8a71e5d7530d8588216027c Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Sun, 12 Mar 2023 19:00:10 +0800 Subject: [PATCH 12/25] Fix checkstyle error --- src/main/java/reposense/wizard/OptionalPrompt.java | 6 +++--- src/main/java/reposense/wizard/OptionalSincePrompt.java | 6 +++--- src/main/java/reposense/wizard/RepoPrompt.java | 4 ++-- src/main/java/reposense/wizard/ViewPrompt.java | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/reposense/wizard/OptionalPrompt.java b/src/main/java/reposense/wizard/OptionalPrompt.java index d60bc6390f..1f2d6fc47f 100644 --- a/src/main/java/reposense/wizard/OptionalPrompt.java +++ b/src/main/java/reposense/wizard/OptionalPrompt.java @@ -4,9 +4,9 @@ * Represents an optional prompt that only calls the provided prompt if requested by the user. */ public abstract class OptionalPrompt extends Prompt { - private final static String YES_FLAG = "Y"; - private final static String NO_FLAG = "N"; - private final static String FORMAT = String.format("%s/%s", YES_FLAG, NO_FLAG); + private static final String YES_FLAG = "Y"; + private static final String NO_FLAG = "N"; + private static final String FORMAT = String.format("%s/%s", YES_FLAG, NO_FLAG); public OptionalPrompt(String description) { super(description, FORMAT); diff --git a/src/main/java/reposense/wizard/OptionalSincePrompt.java b/src/main/java/reposense/wizard/OptionalSincePrompt.java index a7a269f6ec..059c653567 100644 --- a/src/main/java/reposense/wizard/OptionalSincePrompt.java +++ b/src/main/java/reposense/wizard/OptionalSincePrompt.java @@ -4,8 +4,8 @@ * Represents an Optional Prompt to get the sinceDate flag. */ public class OptionalSincePrompt extends OptionalPrompt { - private static final String DESCRIPTION = "Do you want to specify the start date for the period to be analyzed? " + - "The default is one month before the current date"; + private static final String DESCRIPTION = "Do you want to specify the start date for the period to be analyzed? " + + "The default is one month before the current date"; public OptionalSincePrompt() { super(DESCRIPTION); @@ -15,4 +15,4 @@ public OptionalSincePrompt() { public Prompt[] optionallyRun() { return new Prompt[]{new SincePrompt()}; } -} \ No newline at end of file +} diff --git a/src/main/java/reposense/wizard/RepoPrompt.java b/src/main/java/reposense/wizard/RepoPrompt.java index 128a6e44dd..97a6b7d98f 100644 --- a/src/main/java/reposense/wizard/RepoPrompt.java +++ b/src/main/java/reposense/wizard/RepoPrompt.java @@ -4,8 +4,8 @@ * Represents a Prompt to get the repo flag. */ public class RepoPrompt extends Prompt { - private static final String DESCRIPTION = "Enter a list of URLs or the disk location of the git repositories " + - "to analyze, separated by spaces"; + private static final String DESCRIPTION = "Enter a list of URLs or the disk location of the git repositories " + + "to analyze, separated by spaces"; public RepoPrompt() { super(DESCRIPTION); diff --git a/src/main/java/reposense/wizard/ViewPrompt.java b/src/main/java/reposense/wizard/ViewPrompt.java index 03723996fd..bc8f92d9ab 100644 --- a/src/main/java/reposense/wizard/ViewPrompt.java +++ b/src/main/java/reposense/wizard/ViewPrompt.java @@ -1,13 +1,13 @@ package reposense.wizard; +import java.nio.file.Paths; + /** * Represents a Prompt to get the view flag. */ -import java.nio.file.Paths; - public class ViewPrompt extends Prompt { - public static final String DESCRIPTION = "Enter directory of report to display in server. " + - "If not specified, default directory will be used"; + public static final String DESCRIPTION = "Enter directory of report to display in server. " + + "If not specified, default directory will be used"; public ViewPrompt() { super(DESCRIPTION); From e83fbf01030ef9cac86fd6a28ca60c2c5913aac6 Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Sun, 12 Mar 2023 21:27:37 +0800 Subject: [PATCH 13/25] Update WizardRunnerTest --- .../reposense/util/WizardInputBuilder.java | 32 +++++++ .../reposense/wizard/WizardRunnerTest.java | 86 ++++++++++++++++++- 2 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 src/test/java/reposense/util/WizardInputBuilder.java diff --git a/src/test/java/reposense/util/WizardInputBuilder.java b/src/test/java/reposense/util/WizardInputBuilder.java new file mode 100644 index 0000000000..695052a957 --- /dev/null +++ b/src/test/java/reposense/util/WizardInputBuilder.java @@ -0,0 +1,32 @@ +package reposense.util; +/** + * A utility class to help with building command line input for Wizard CLI. + * Example usage:
+ * {@code String input = new WizardInputBuilder().append("22/02/2022").build();} + */ +public class WizardInputBuilder { + private static final String NEW_LINE = "\n"; + private StringBuilder input; + + public WizardInputBuilder() { + this.input = new StringBuilder(); + } + + /** + * Adds command entered by the user to the input. + * + * @param command The command by the user + */ + public WizardInputBuilder append(String command) { + input.append(command).append(NEW_LINE); + return this; + } + + /** + * Returns the {@code input} generated from this {@link WizardInputBuilder}. + */ + public String build() { + return input.toString(); + } + +} diff --git a/src/test/java/reposense/wizard/WizardRunnerTest.java b/src/test/java/reposense/wizard/WizardRunnerTest.java index 5309bf010b..5b9bc060d3 100644 --- a/src/test/java/reposense/wizard/WizardRunnerTest.java +++ b/src/test/java/reposense/wizard/WizardRunnerTest.java @@ -4,20 +4,98 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.nio.file.Paths; import java.util.Scanner; import org.junit.jupiter.api.Test; +import reposense.util.WizardInputBuilder; + public class WizardRunnerTest { + private static final String YES_FLAG = "Y"; + private static final String NO_FLAG = "N"; + private static final String SINCE_DATE = "30/09/2022"; + private static final String REPORT_PATH = "C:\\User\\RepoSense"; + private static final String REPO_LINK = "https://github.com/reposense/RepoSense.git"; + + @Test + public void buildInput_repoOnly_success() { + WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); + String input = new WizardInputBuilder() + .append(NO_FLAG) + .append(NO_FLAG) + .append(REPO_LINK) + .build(); + InputStream targetStream = new ByteArrayInputStream(input.getBytes()); + Scanner sc = new Scanner(targetStream); + wizardRunner.buildInput(sc); + + String expectedInput = new InputBuilder().addRepos(REPO_LINK).build(); + assertEquals(expectedInput, wizardRunner.getBuiltInput()); + } + + @Test + public void buildInput_sinceDateAndRepo_success() { + WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); + // Yes only for sinceDate flag + String input = new WizardInputBuilder() + .append(YES_FLAG) + .append(SINCE_DATE) + .append(NO_FLAG) + .append(REPO_LINK) + .build(); + InputStream targetStream = new ByteArrayInputStream(input.getBytes()); + Scanner sc = new Scanner(targetStream); + wizardRunner.buildInput(sc); + + String expectedInput = new InputBuilder() + .addSinceDate(SINCE_DATE) + .addRepos(REPO_LINK) + .build(); + assertEquals(expectedInput, wizardRunner.getBuiltInput()); + } + + @Test + public void buildInput_viewAndRepo_success() { + WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); + // Yes only for view flag + String input = new WizardInputBuilder() + .append(NO_FLAG) + .append(YES_FLAG) + .append(REPORT_PATH) + .append(REPO_LINK) + .build(); + InputStream targetStream = new ByteArrayInputStream(input.getBytes()); + Scanner sc = new Scanner(targetStream); + wizardRunner.buildInput(sc); + + String expectedInput = new InputBuilder() + .addView(Paths.get(REPORT_PATH)) + .addRepos(REPO_LINK) + .build(); + assertEquals(expectedInput, wizardRunner.getBuiltInput()); + } + @Test - public void buildInput_sinceOnly_success() { + public void buildInput_allFlags_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); - String initialString = "30/09/2022\n"; - InputStream targetStream = new ByteArrayInputStream(initialString.getBytes()); + // Yes for all flags + String input = new WizardInputBuilder() + .append(YES_FLAG) + .append(SINCE_DATE) + .append(YES_FLAG) + .append(REPORT_PATH) + .append(REPO_LINK) + .build(); + InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); wizardRunner.buildInput(sc); - String expectedInput = new InputBuilder().addSinceDate("30/09/2022").build(); + String expectedInput = new InputBuilder() + .addSinceDate(SINCE_DATE) + .addView(Paths.get(REPORT_PATH)) + .addRepos(REPO_LINK) + .build(); assertEquals(expectedInput, wizardRunner.getBuiltInput()); } } From ac8fd12919173c1c79d27852f1d6ccf6650eb02d Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Sun, 12 Mar 2023 21:48:45 +0800 Subject: [PATCH 14/25] Update wizard input builder --- .../java/reposense/wizard/OptionalPrompt.java | 4 +-- .../reposense/util/WizardInputBuilder.java | 21 +++++++++++- .../reposense/wizard/WizardRunnerTest.java | 34 +++++++++---------- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/main/java/reposense/wizard/OptionalPrompt.java b/src/main/java/reposense/wizard/OptionalPrompt.java index 1f2d6fc47f..5840fc1e95 100644 --- a/src/main/java/reposense/wizard/OptionalPrompt.java +++ b/src/main/java/reposense/wizard/OptionalPrompt.java @@ -4,8 +4,8 @@ * Represents an optional prompt that only calls the provided prompt if requested by the user. */ public abstract class OptionalPrompt extends Prompt { - private static final String YES_FLAG = "Y"; - private static final String NO_FLAG = "N"; + public static final String YES_FLAG = "Y"; + public static final String NO_FLAG = "N"; private static final String FORMAT = String.format("%s/%s", YES_FLAG, NO_FLAG); public OptionalPrompt(String description) { diff --git a/src/test/java/reposense/util/WizardInputBuilder.java b/src/test/java/reposense/util/WizardInputBuilder.java index 695052a957..d513597654 100644 --- a/src/test/java/reposense/util/WizardInputBuilder.java +++ b/src/test/java/reposense/util/WizardInputBuilder.java @@ -1,4 +1,7 @@ package reposense.util; + +import reposense.wizard.OptionalPrompt; + /** * A utility class to help with building command line input for Wizard CLI. * Example usage:
@@ -17,11 +20,27 @@ public WizardInputBuilder() { * * @param command The command by the user */ - public WizardInputBuilder append(String command) { + public WizardInputBuilder add(String command) { input.append(command).append(NEW_LINE); return this; } + /** + * Adds Yes Flag entered by the user to the input. + */ + public WizardInputBuilder addYesFlag() { + input.append(OptionalPrompt.YES_FLAG).append(NEW_LINE); + return this; + } + + /** + * Adds No Flag entered by the user to the input. + */ + public WizardInputBuilder addNoFlag() { + input.append(OptionalPrompt.NO_FLAG).append(NEW_LINE); + return this; + } + /** * Returns the {@code input} generated from this {@link WizardInputBuilder}. */ diff --git a/src/test/java/reposense/wizard/WizardRunnerTest.java b/src/test/java/reposense/wizard/WizardRunnerTest.java index 5b9bc060d3..08761e548f 100644 --- a/src/test/java/reposense/wizard/WizardRunnerTest.java +++ b/src/test/java/reposense/wizard/WizardRunnerTest.java @@ -12,8 +12,6 @@ import reposense.util.WizardInputBuilder; public class WizardRunnerTest { - private static final String YES_FLAG = "Y"; - private static final String NO_FLAG = "N"; private static final String SINCE_DATE = "30/09/2022"; private static final String REPORT_PATH = "C:\\User\\RepoSense"; private static final String REPO_LINK = "https://github.com/reposense/RepoSense.git"; @@ -22,9 +20,9 @@ public class WizardRunnerTest { public void buildInput_repoOnly_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); String input = new WizardInputBuilder() - .append(NO_FLAG) - .append(NO_FLAG) - .append(REPO_LINK) + .addNoFlag() + .addNoFlag() + .add(REPO_LINK) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); @@ -39,10 +37,10 @@ public void buildInput_sinceDateAndRepo_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); // Yes only for sinceDate flag String input = new WizardInputBuilder() - .append(YES_FLAG) - .append(SINCE_DATE) - .append(NO_FLAG) - .append(REPO_LINK) + .addYesFlag() + .add(SINCE_DATE) + .addNoFlag() + .add(REPO_LINK) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); @@ -60,10 +58,10 @@ public void buildInput_viewAndRepo_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); // Yes only for view flag String input = new WizardInputBuilder() - .append(NO_FLAG) - .append(YES_FLAG) - .append(REPORT_PATH) - .append(REPO_LINK) + .addNoFlag() + .addYesFlag() + .add(REPORT_PATH) + .add(REPO_LINK) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); @@ -81,11 +79,11 @@ public void buildInput_allFlags_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); // Yes for all flags String input = new WizardInputBuilder() - .append(YES_FLAG) - .append(SINCE_DATE) - .append(YES_FLAG) - .append(REPORT_PATH) - .append(REPO_LINK) + .addYesFlag() + .add(SINCE_DATE) + .addYesFlag() + .add(REPORT_PATH) + .add(REPO_LINK) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); From 8b1b7b42c451ac3f76367f80277b0c6d99e655c1 Mon Sep 17 00:00:00 2001 From: sikai00 Date: Wed, 15 Mar 2023 18:37:25 +0800 Subject: [PATCH 15/25] Add UntilPrompt --- .../java/reposense/wizard/BasicWizard.java | 1 + .../reposense/wizard/OptionalUntilPrompt.java | 18 +++++++ .../java/reposense/wizard/UntilPrompt.java | 23 +++++++++ .../reposense/wizard/WizardRunnerTest.java | 51 +++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 src/main/java/reposense/wizard/OptionalUntilPrompt.java create mode 100644 src/main/java/reposense/wizard/UntilPrompt.java diff --git a/src/main/java/reposense/wizard/BasicWizard.java b/src/main/java/reposense/wizard/BasicWizard.java index a8cd7d3e5f..fd93529be2 100644 --- a/src/main/java/reposense/wizard/BasicWizard.java +++ b/src/main/java/reposense/wizard/BasicWizard.java @@ -6,6 +6,7 @@ public class BasicWizard extends Wizard { private static final Prompt[] INITIAL_PROMPTS = new Prompt[] { new OptionalSincePrompt(), + new OptionalUntilPrompt(), new OptionalViewPrompt(), new RepoPrompt() }; diff --git a/src/main/java/reposense/wizard/OptionalUntilPrompt.java b/src/main/java/reposense/wizard/OptionalUntilPrompt.java new file mode 100644 index 0000000000..4c3c298411 --- /dev/null +++ b/src/main/java/reposense/wizard/OptionalUntilPrompt.java @@ -0,0 +1,18 @@ +package reposense.wizard; + +/** + * Represents an Optional Prompt to get the untilDate flag. + */ +public class OptionalUntilPrompt extends OptionalPrompt { + private static final String DESCRIPTION = "Do you want to specify the end date for the period to be analyzed? " + + "The default is today"; + + public OptionalUntilPrompt() { + super(DESCRIPTION); + } + + @Override + public Prompt[] optionallyRun() { + return new Prompt[]{new UntilPrompt()}; + } +} diff --git a/src/main/java/reposense/wizard/UntilPrompt.java b/src/main/java/reposense/wizard/UntilPrompt.java new file mode 100644 index 0000000000..8dcad68117 --- /dev/null +++ b/src/main/java/reposense/wizard/UntilPrompt.java @@ -0,0 +1,23 @@ +package reposense.wizard; + +/** + * Represents a Prompt to get the untilDate flag. + */ +public class UntilPrompt extends Prompt { + private static final String DESCRIPTION = "Enter the end date for the period to be analyzed"; + private static final String FORMAT = "DD/MM/YYYY"; + + public UntilPrompt() { + super(DESCRIPTION, FORMAT); + } + + @Override + public InputBuilder addToInput(InputBuilder inputBuilder) { + return inputBuilder.addUntilDate(getResponse()); + } + + @Override + public Prompt[] run() { + return new Prompt[] {}; + } +} diff --git a/src/test/java/reposense/wizard/WizardRunnerTest.java b/src/test/java/reposense/wizard/WizardRunnerTest.java index 08761e548f..eab4968935 100644 --- a/src/test/java/reposense/wizard/WizardRunnerTest.java +++ b/src/test/java/reposense/wizard/WizardRunnerTest.java @@ -13,6 +13,7 @@ public class WizardRunnerTest { private static final String SINCE_DATE = "30/09/2022"; + private static final String UNTIL_DATE = "15/03/2023"; private static final String REPORT_PATH = "C:\\User\\RepoSense"; private static final String REPO_LINK = "https://github.com/reposense/RepoSense.git"; @@ -20,6 +21,7 @@ public class WizardRunnerTest { public void buildInput_repoOnly_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); String input = new WizardInputBuilder() + .addNoFlag() .addNoFlag() .addNoFlag() .add(REPO_LINK) @@ -40,6 +42,50 @@ public void buildInput_sinceDateAndRepo_success() { .addYesFlag() .add(SINCE_DATE) .addNoFlag() + .addNoFlag() + .add(REPO_LINK) + .build(); + InputStream targetStream = new ByteArrayInputStream(input.getBytes()); + Scanner sc = new Scanner(targetStream); + wizardRunner.buildInput(sc); + + String expectedInput = new InputBuilder() + .addSinceDate(SINCE_DATE) + .addRepos(REPO_LINK) + .build(); + assertEquals(expectedInput, wizardRunner.getBuiltInput()); + } + + @Test + public void buildInput_untilDateAndRepo_success() { + WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); + String input = new WizardInputBuilder() + .addNoFlag() + .addYesFlag() + .add(UNTIL_DATE) + .addNoFlag() + .add(REPO_LINK) + .build(); + InputStream targetStream = new ByteArrayInputStream(input.getBytes()); + Scanner sc = new Scanner(targetStream); + wizardRunner.buildInput(sc); + + String expectedInput = new InputBuilder() + .addUntilDate(UNTIL_DATE) + .addRepos(REPO_LINK) + .build(); + assertEquals(expectedInput, wizardRunner.getBuiltInput()); + } + + @Test + public void buildInput_sinceDateAndUntilDateAndRepo_success() { + WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); + String input = new WizardInputBuilder() + .addYesFlag() + .add(SINCE_DATE) + .addYesFlag() + .add(UNTIL_DATE) + .addNoFlag() .add(REPO_LINK) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); @@ -48,6 +94,7 @@ public void buildInput_sinceDateAndRepo_success() { String expectedInput = new InputBuilder() .addSinceDate(SINCE_DATE) + .addUntilDate(UNTIL_DATE) .addRepos(REPO_LINK) .build(); assertEquals(expectedInput, wizardRunner.getBuiltInput()); @@ -58,6 +105,7 @@ public void buildInput_viewAndRepo_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); // Yes only for view flag String input = new WizardInputBuilder() + .addNoFlag() .addNoFlag() .addYesFlag() .add(REPORT_PATH) @@ -82,6 +130,8 @@ public void buildInput_allFlags_success() { .addYesFlag() .add(SINCE_DATE) .addYesFlag() + .add(UNTIL_DATE) + .addYesFlag() .add(REPORT_PATH) .add(REPO_LINK) .build(); @@ -91,6 +141,7 @@ public void buildInput_allFlags_success() { String expectedInput = new InputBuilder() .addSinceDate(SINCE_DATE) + .addUntilDate(UNTIL_DATE) .addView(Paths.get(REPORT_PATH)) .addRepos(REPO_LINK) .build(); From 9b47b339ae73d711dd52592c8ee6e1ee4cd0f274 Mon Sep 17 00:00:00 2001 From: sikai00 Date: Thu, 16 Mar 2023 00:11:41 +0800 Subject: [PATCH 16/25] Add documentaion for init --- docs/ug/cli.md | 13 +++++++++++++ docs/ug/generatingReports.md | 3 +++ 2 files changed, 16 insertions(+) diff --git a/docs/ug/cli.md b/docs/ug/cli.md index e5c3794c4d..e0ec3c370b 100644 --- a/docs/ug/cli.md +++ b/docs/ug/cli.md @@ -137,6 +137,19 @@ This flag overrides the `Ignore file size limit` field in the CSV config file. +### `--init` + +**`--init`**: Launches the RepoSense CLI set-up wizard. +* Example:`--init` + + + +* The wizard will run through the basic config flags in this order: `--since`, `--until`, `--view`, `--repos`. +* This flag overrides all other flags and thus should be used on its own. + + + + ### `--last-modified-date`, `-l` **`--last-modified-date`**: Specifies that the last modified date of each line of code should be added to `authorship.json`. diff --git a/docs/ug/generatingReports.md b/docs/ug/generatingReports.md index f4bb88f557..42f40c97f8 100644 --- a/docs/ug/generatingReports.md +++ b/docs/ug/generatingReports.md @@ -44,6 +44,9 @@ For other types of repositories, external links are disabled. **To learn how to generate a report using other settings**, head over to the [_**Customizing reports**_](customizingReports.html) section. +**Alternatively**, you may also use the RepoSense CLI set-up wizard, which will take you through a basic configuration of RepoSense through the following command: + * `java -jar RepoSense.jar --init` + ## Generating reports remotely From 8eb642ddbe3f9b75432e4bebbd75c182dea44327 Mon Sep 17 00:00:00 2001 From: sikai00 Date: Thu, 16 Mar 2023 00:24:18 +0800 Subject: [PATCH 17/25] Reorganise file structure --- src/main/java/reposense/wizard/BasicWizard.java | 6 ++++++ src/main/java/reposense/wizard/Wizard.java | 2 ++ src/main/java/reposense/wizard/WizardRunner.java | 1 + .../java/reposense/wizard/{ => prompts}/OptionalPrompt.java | 4 +++- .../reposense/wizard/{ => prompts}/OptionalSincePrompt.java | 2 +- .../reposense/wizard/{ => prompts}/OptionalUntilPrompt.java | 2 +- .../reposense/wizard/{ => prompts}/OptionalViewPrompt.java | 2 +- src/main/java/reposense/wizard/{ => prompts}/Prompt.java | 4 +++- .../java/reposense/wizard/{ => prompts}/RepoPrompt.java | 4 +++- .../java/reposense/wizard/{ => prompts}/SincePrompt.java | 4 +++- .../java/reposense/wizard/{ => prompts}/UntilPrompt.java | 4 +++- .../java/reposense/wizard/{ => prompts}/ViewPrompt.java | 4 +++- src/test/java/reposense/util/WizardInputBuilder.java | 2 +- 13 files changed, 31 insertions(+), 10 deletions(-) rename src/main/java/reposense/wizard/{ => prompts}/OptionalPrompt.java (93%) rename src/main/java/reposense/wizard/{ => prompts}/OptionalSincePrompt.java (93%) rename src/main/java/reposense/wizard/{ => prompts}/OptionalUntilPrompt.java (93%) rename src/main/java/reposense/wizard/{ => prompts}/OptionalViewPrompt.java (92%) rename src/main/java/reposense/wizard/{ => prompts}/Prompt.java (95%) rename src/main/java/reposense/wizard/{ => prompts}/RepoPrompt.java (88%) rename src/main/java/reposense/wizard/{ => prompts}/SincePrompt.java (88%) rename src/main/java/reposense/wizard/{ => prompts}/UntilPrompt.java (88%) rename src/main/java/reposense/wizard/{ => prompts}/ViewPrompt.java (90%) diff --git a/src/main/java/reposense/wizard/BasicWizard.java b/src/main/java/reposense/wizard/BasicWizard.java index fd93529be2..7aff683884 100644 --- a/src/main/java/reposense/wizard/BasicWizard.java +++ b/src/main/java/reposense/wizard/BasicWizard.java @@ -1,5 +1,11 @@ package reposense.wizard; +import reposense.wizard.prompts.OptionalSincePrompt; +import reposense.wizard.prompts.OptionalUntilPrompt; +import reposense.wizard.prompts.OptionalViewPrompt; +import reposense.wizard.prompts.Prompt; +import reposense.wizard.prompts.RepoPrompt; + /** * Represents a basic wizard run. */ diff --git a/src/main/java/reposense/wizard/Wizard.java b/src/main/java/reposense/wizard/Wizard.java index 04344f0b3d..3dc5bdde2f 100644 --- a/src/main/java/reposense/wizard/Wizard.java +++ b/src/main/java/reposense/wizard/Wizard.java @@ -1,5 +1,7 @@ package reposense.wizard; +import reposense.wizard.prompts.Prompt; + /** * This class implements an abstract wizard. * A concrete implementation of a wizard contains diff --git a/src/main/java/reposense/wizard/WizardRunner.java b/src/main/java/reposense/wizard/WizardRunner.java index 885fb697ff..a95c8b1c84 100644 --- a/src/main/java/reposense/wizard/WizardRunner.java +++ b/src/main/java/reposense/wizard/WizardRunner.java @@ -7,6 +7,7 @@ import java.util.Scanner; import reposense.RepoSense; +import reposense.wizard.prompts.Prompt; /** * This class implements a wizard runner in the form diff --git a/src/main/java/reposense/wizard/OptionalPrompt.java b/src/main/java/reposense/wizard/prompts/OptionalPrompt.java similarity index 93% rename from src/main/java/reposense/wizard/OptionalPrompt.java rename to src/main/java/reposense/wizard/prompts/OptionalPrompt.java index 5840fc1e95..cd6c1769af 100644 --- a/src/main/java/reposense/wizard/OptionalPrompt.java +++ b/src/main/java/reposense/wizard/prompts/OptionalPrompt.java @@ -1,4 +1,6 @@ -package reposense.wizard; +package reposense.wizard.prompts; + +import reposense.wizard.InputBuilder; /** * Represents an optional prompt that only calls the provided prompt if requested by the user. diff --git a/src/main/java/reposense/wizard/OptionalSincePrompt.java b/src/main/java/reposense/wizard/prompts/OptionalSincePrompt.java similarity index 93% rename from src/main/java/reposense/wizard/OptionalSincePrompt.java rename to src/main/java/reposense/wizard/prompts/OptionalSincePrompt.java index 059c653567..28227b8d4f 100644 --- a/src/main/java/reposense/wizard/OptionalSincePrompt.java +++ b/src/main/java/reposense/wizard/prompts/OptionalSincePrompt.java @@ -1,4 +1,4 @@ -package reposense.wizard; +package reposense.wizard.prompts; /** * Represents an Optional Prompt to get the sinceDate flag. diff --git a/src/main/java/reposense/wizard/OptionalUntilPrompt.java b/src/main/java/reposense/wizard/prompts/OptionalUntilPrompt.java similarity index 93% rename from src/main/java/reposense/wizard/OptionalUntilPrompt.java rename to src/main/java/reposense/wizard/prompts/OptionalUntilPrompt.java index 4c3c298411..a43cbaf7e5 100644 --- a/src/main/java/reposense/wizard/OptionalUntilPrompt.java +++ b/src/main/java/reposense/wizard/prompts/OptionalUntilPrompt.java @@ -1,4 +1,4 @@ -package reposense.wizard; +package reposense.wizard.prompts; /** * Represents an Optional Prompt to get the untilDate flag. diff --git a/src/main/java/reposense/wizard/OptionalViewPrompt.java b/src/main/java/reposense/wizard/prompts/OptionalViewPrompt.java similarity index 92% rename from src/main/java/reposense/wizard/OptionalViewPrompt.java rename to src/main/java/reposense/wizard/prompts/OptionalViewPrompt.java index 3172a71eb1..306bd539d8 100644 --- a/src/main/java/reposense/wizard/OptionalViewPrompt.java +++ b/src/main/java/reposense/wizard/prompts/OptionalViewPrompt.java @@ -1,4 +1,4 @@ -package reposense.wizard; +package reposense.wizard.prompts; /** * Represents an Optional Prompt to get the view flag. diff --git a/src/main/java/reposense/wizard/Prompt.java b/src/main/java/reposense/wizard/prompts/Prompt.java similarity index 95% rename from src/main/java/reposense/wizard/Prompt.java rename to src/main/java/reposense/wizard/prompts/Prompt.java index 278cb7825e..dc449df89a 100644 --- a/src/main/java/reposense/wizard/Prompt.java +++ b/src/main/java/reposense/wizard/prompts/Prompt.java @@ -1,7 +1,9 @@ -package reposense.wizard; +package reposense.wizard.prompts; import java.util.Scanner; +import reposense.wizard.InputBuilder; + /** * Represents an abstract prompt. */ diff --git a/src/main/java/reposense/wizard/RepoPrompt.java b/src/main/java/reposense/wizard/prompts/RepoPrompt.java similarity index 88% rename from src/main/java/reposense/wizard/RepoPrompt.java rename to src/main/java/reposense/wizard/prompts/RepoPrompt.java index 97a6b7d98f..8e130546e8 100644 --- a/src/main/java/reposense/wizard/RepoPrompt.java +++ b/src/main/java/reposense/wizard/prompts/RepoPrompt.java @@ -1,4 +1,6 @@ -package reposense.wizard; +package reposense.wizard.prompts; + +import reposense.wizard.InputBuilder; /** * Represents a Prompt to get the repo flag. diff --git a/src/main/java/reposense/wizard/SincePrompt.java b/src/main/java/reposense/wizard/prompts/SincePrompt.java similarity index 88% rename from src/main/java/reposense/wizard/SincePrompt.java rename to src/main/java/reposense/wizard/prompts/SincePrompt.java index bbffa101b2..7d149803a9 100644 --- a/src/main/java/reposense/wizard/SincePrompt.java +++ b/src/main/java/reposense/wizard/prompts/SincePrompt.java @@ -1,4 +1,6 @@ -package reposense.wizard; +package reposense.wizard.prompts; + +import reposense.wizard.InputBuilder; /** * Represents a Prompt to get the sinceDate flag. diff --git a/src/main/java/reposense/wizard/UntilPrompt.java b/src/main/java/reposense/wizard/prompts/UntilPrompt.java similarity index 88% rename from src/main/java/reposense/wizard/UntilPrompt.java rename to src/main/java/reposense/wizard/prompts/UntilPrompt.java index 8dcad68117..d0f9c28451 100644 --- a/src/main/java/reposense/wizard/UntilPrompt.java +++ b/src/main/java/reposense/wizard/prompts/UntilPrompt.java @@ -1,4 +1,6 @@ -package reposense.wizard; +package reposense.wizard.prompts; + +import reposense.wizard.InputBuilder; /** * Represents a Prompt to get the untilDate flag. diff --git a/src/main/java/reposense/wizard/ViewPrompt.java b/src/main/java/reposense/wizard/prompts/ViewPrompt.java similarity index 90% rename from src/main/java/reposense/wizard/ViewPrompt.java rename to src/main/java/reposense/wizard/prompts/ViewPrompt.java index bc8f92d9ab..50fe8afa93 100644 --- a/src/main/java/reposense/wizard/ViewPrompt.java +++ b/src/main/java/reposense/wizard/prompts/ViewPrompt.java @@ -1,7 +1,9 @@ -package reposense.wizard; +package reposense.wizard.prompts; import java.nio.file.Paths; +import reposense.wizard.InputBuilder; + /** * Represents a Prompt to get the view flag. */ diff --git a/src/test/java/reposense/util/WizardInputBuilder.java b/src/test/java/reposense/util/WizardInputBuilder.java index d513597654..3ebd6b1327 100644 --- a/src/test/java/reposense/util/WizardInputBuilder.java +++ b/src/test/java/reposense/util/WizardInputBuilder.java @@ -1,6 +1,6 @@ package reposense.util; -import reposense.wizard.OptionalPrompt; +import reposense.wizard.prompts.OptionalPrompt; /** * A utility class to help with building command line input for Wizard CLI. From e006376c55d0b642d01a72176673aa3078bfe3ec Mon Sep 17 00:00:00 2001 From: sikai00 Date: Thu, 16 Mar 2023 00:26:33 +0800 Subject: [PATCH 18/25] Rename prompts to prompt --- src/main/java/reposense/wizard/BasicWizard.java | 10 +++++----- src/main/java/reposense/wizard/Wizard.java | 2 +- src/main/java/reposense/wizard/WizardRunner.java | 2 +- .../wizard/{prompts => prompt}/OptionalPrompt.java | 2 +- .../{prompts => prompt}/OptionalSincePrompt.java | 2 +- .../{prompts => prompt}/OptionalUntilPrompt.java | 2 +- .../wizard/{prompts => prompt}/OptionalViewPrompt.java | 2 +- .../reposense/wizard/{prompts => prompt}/Prompt.java | 2 +- .../wizard/{prompts => prompt}/RepoPrompt.java | 2 +- .../wizard/{prompts => prompt}/SincePrompt.java | 2 +- .../wizard/{prompts => prompt}/UntilPrompt.java | 2 +- .../wizard/{prompts => prompt}/ViewPrompt.java | 2 +- src/test/java/reposense/util/WizardInputBuilder.java | 2 +- 13 files changed, 17 insertions(+), 17 deletions(-) rename src/main/java/reposense/wizard/{prompts => prompt}/OptionalPrompt.java (96%) rename src/main/java/reposense/wizard/{prompts => prompt}/OptionalSincePrompt.java (93%) rename src/main/java/reposense/wizard/{prompts => prompt}/OptionalUntilPrompt.java (93%) rename src/main/java/reposense/wizard/{prompts => prompt}/OptionalViewPrompt.java (92%) rename src/main/java/reposense/wizard/{prompts => prompt}/Prompt.java (97%) rename src/main/java/reposense/wizard/{prompts => prompt}/RepoPrompt.java (94%) rename src/main/java/reposense/wizard/{prompts => prompt}/SincePrompt.java (94%) rename src/main/java/reposense/wizard/{prompts => prompt}/UntilPrompt.java (94%) rename src/main/java/reposense/wizard/{prompts => prompt}/ViewPrompt.java (95%) diff --git a/src/main/java/reposense/wizard/BasicWizard.java b/src/main/java/reposense/wizard/BasicWizard.java index 7aff683884..b0e31f1358 100644 --- a/src/main/java/reposense/wizard/BasicWizard.java +++ b/src/main/java/reposense/wizard/BasicWizard.java @@ -1,10 +1,10 @@ package reposense.wizard; -import reposense.wizard.prompts.OptionalSincePrompt; -import reposense.wizard.prompts.OptionalUntilPrompt; -import reposense.wizard.prompts.OptionalViewPrompt; -import reposense.wizard.prompts.Prompt; -import reposense.wizard.prompts.RepoPrompt; +import reposense.wizard.prompt.OptionalSincePrompt; +import reposense.wizard.prompt.OptionalUntilPrompt; +import reposense.wizard.prompt.OptionalViewPrompt; +import reposense.wizard.prompt.Prompt; +import reposense.wizard.prompt.RepoPrompt; /** * Represents a basic wizard run. diff --git a/src/main/java/reposense/wizard/Wizard.java b/src/main/java/reposense/wizard/Wizard.java index 3dc5bdde2f..68fc97d0ea 100644 --- a/src/main/java/reposense/wizard/Wizard.java +++ b/src/main/java/reposense/wizard/Wizard.java @@ -1,6 +1,6 @@ package reposense.wizard; -import reposense.wizard.prompts.Prompt; +import reposense.wizard.prompt.Prompt; /** * This class implements an abstract wizard. diff --git a/src/main/java/reposense/wizard/WizardRunner.java b/src/main/java/reposense/wizard/WizardRunner.java index a95c8b1c84..42072bc1cb 100644 --- a/src/main/java/reposense/wizard/WizardRunner.java +++ b/src/main/java/reposense/wizard/WizardRunner.java @@ -7,7 +7,7 @@ import java.util.Scanner; import reposense.RepoSense; -import reposense.wizard.prompts.Prompt; +import reposense.wizard.prompt.Prompt; /** * This class implements a wizard runner in the form diff --git a/src/main/java/reposense/wizard/prompts/OptionalPrompt.java b/src/main/java/reposense/wizard/prompt/OptionalPrompt.java similarity index 96% rename from src/main/java/reposense/wizard/prompts/OptionalPrompt.java rename to src/main/java/reposense/wizard/prompt/OptionalPrompt.java index cd6c1769af..6ddb514b36 100644 --- a/src/main/java/reposense/wizard/prompts/OptionalPrompt.java +++ b/src/main/java/reposense/wizard/prompt/OptionalPrompt.java @@ -1,4 +1,4 @@ -package reposense.wizard.prompts; +package reposense.wizard.prompt; import reposense.wizard.InputBuilder; diff --git a/src/main/java/reposense/wizard/prompts/OptionalSincePrompt.java b/src/main/java/reposense/wizard/prompt/OptionalSincePrompt.java similarity index 93% rename from src/main/java/reposense/wizard/prompts/OptionalSincePrompt.java rename to src/main/java/reposense/wizard/prompt/OptionalSincePrompt.java index 28227b8d4f..47fcffd382 100644 --- a/src/main/java/reposense/wizard/prompts/OptionalSincePrompt.java +++ b/src/main/java/reposense/wizard/prompt/OptionalSincePrompt.java @@ -1,4 +1,4 @@ -package reposense.wizard.prompts; +package reposense.wizard.prompt; /** * Represents an Optional Prompt to get the sinceDate flag. diff --git a/src/main/java/reposense/wizard/prompts/OptionalUntilPrompt.java b/src/main/java/reposense/wizard/prompt/OptionalUntilPrompt.java similarity index 93% rename from src/main/java/reposense/wizard/prompts/OptionalUntilPrompt.java rename to src/main/java/reposense/wizard/prompt/OptionalUntilPrompt.java index a43cbaf7e5..bcf873e9d3 100644 --- a/src/main/java/reposense/wizard/prompts/OptionalUntilPrompt.java +++ b/src/main/java/reposense/wizard/prompt/OptionalUntilPrompt.java @@ -1,4 +1,4 @@ -package reposense.wizard.prompts; +package reposense.wizard.prompt; /** * Represents an Optional Prompt to get the untilDate flag. diff --git a/src/main/java/reposense/wizard/prompts/OptionalViewPrompt.java b/src/main/java/reposense/wizard/prompt/OptionalViewPrompt.java similarity index 92% rename from src/main/java/reposense/wizard/prompts/OptionalViewPrompt.java rename to src/main/java/reposense/wizard/prompt/OptionalViewPrompt.java index 306bd539d8..a75cc54cd5 100644 --- a/src/main/java/reposense/wizard/prompts/OptionalViewPrompt.java +++ b/src/main/java/reposense/wizard/prompt/OptionalViewPrompt.java @@ -1,4 +1,4 @@ -package reposense.wizard.prompts; +package reposense.wizard.prompt; /** * Represents an Optional Prompt to get the view flag. diff --git a/src/main/java/reposense/wizard/prompts/Prompt.java b/src/main/java/reposense/wizard/prompt/Prompt.java similarity index 97% rename from src/main/java/reposense/wizard/prompts/Prompt.java rename to src/main/java/reposense/wizard/prompt/Prompt.java index dc449df89a..d2290551da 100644 --- a/src/main/java/reposense/wizard/prompts/Prompt.java +++ b/src/main/java/reposense/wizard/prompt/Prompt.java @@ -1,4 +1,4 @@ -package reposense.wizard.prompts; +package reposense.wizard.prompt; import java.util.Scanner; diff --git a/src/main/java/reposense/wizard/prompts/RepoPrompt.java b/src/main/java/reposense/wizard/prompt/RepoPrompt.java similarity index 94% rename from src/main/java/reposense/wizard/prompts/RepoPrompt.java rename to src/main/java/reposense/wizard/prompt/RepoPrompt.java index 8e130546e8..be025c967f 100644 --- a/src/main/java/reposense/wizard/prompts/RepoPrompt.java +++ b/src/main/java/reposense/wizard/prompt/RepoPrompt.java @@ -1,4 +1,4 @@ -package reposense.wizard.prompts; +package reposense.wizard.prompt; import reposense.wizard.InputBuilder; diff --git a/src/main/java/reposense/wizard/prompts/SincePrompt.java b/src/main/java/reposense/wizard/prompt/SincePrompt.java similarity index 94% rename from src/main/java/reposense/wizard/prompts/SincePrompt.java rename to src/main/java/reposense/wizard/prompt/SincePrompt.java index 7d149803a9..768f811dd7 100644 --- a/src/main/java/reposense/wizard/prompts/SincePrompt.java +++ b/src/main/java/reposense/wizard/prompt/SincePrompt.java @@ -1,4 +1,4 @@ -package reposense.wizard.prompts; +package reposense.wizard.prompt; import reposense.wizard.InputBuilder; diff --git a/src/main/java/reposense/wizard/prompts/UntilPrompt.java b/src/main/java/reposense/wizard/prompt/UntilPrompt.java similarity index 94% rename from src/main/java/reposense/wizard/prompts/UntilPrompt.java rename to src/main/java/reposense/wizard/prompt/UntilPrompt.java index d0f9c28451..7f019e86cb 100644 --- a/src/main/java/reposense/wizard/prompts/UntilPrompt.java +++ b/src/main/java/reposense/wizard/prompt/UntilPrompt.java @@ -1,4 +1,4 @@ -package reposense.wizard.prompts; +package reposense.wizard.prompt; import reposense.wizard.InputBuilder; diff --git a/src/main/java/reposense/wizard/prompts/ViewPrompt.java b/src/main/java/reposense/wizard/prompt/ViewPrompt.java similarity index 95% rename from src/main/java/reposense/wizard/prompts/ViewPrompt.java rename to src/main/java/reposense/wizard/prompt/ViewPrompt.java index 50fe8afa93..4363205cde 100644 --- a/src/main/java/reposense/wizard/prompts/ViewPrompt.java +++ b/src/main/java/reposense/wizard/prompt/ViewPrompt.java @@ -1,4 +1,4 @@ -package reposense.wizard.prompts; +package reposense.wizard.prompt; import java.nio.file.Paths; diff --git a/src/test/java/reposense/util/WizardInputBuilder.java b/src/test/java/reposense/util/WizardInputBuilder.java index 3ebd6b1327..e8251d2745 100644 --- a/src/test/java/reposense/util/WizardInputBuilder.java +++ b/src/test/java/reposense/util/WizardInputBuilder.java @@ -1,6 +1,6 @@ package reposense.util; -import reposense.wizard.prompts.OptionalPrompt; +import reposense.wizard.prompt.OptionalPrompt; /** * A utility class to help with building command line input for Wizard CLI. From 4cadcca38e70a2b125c8280cb90fe05573c0e1df Mon Sep 17 00:00:00 2001 From: Marcus Tang <50147457+MarcusTXK@users.noreply.github.com> Date: Thu, 16 Mar 2023 01:08:57 +0800 Subject: [PATCH 19/25] Update cli.md --- docs/ug/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ug/cli.md b/docs/ug/cli.md index e0ec3c370b..c676635cc2 100644 --- a/docs/ug/cli.md +++ b/docs/ug/cli.md @@ -140,7 +140,7 @@ This flag overrides the `Ignore file size limit` field in the CSV config file. ### `--init` **`--init`**: Launches the RepoSense CLI set-up wizard. -* Example:`--init` +* Example: `--init` From d45ecdeceb1dc87978531a07eebc665fa92882f9 Mon Sep 17 00:00:00 2001 From: sikai00 Date: Mon, 27 Mar 2023 01:49:23 +0800 Subject: [PATCH 20/25] Remove redundant translatecommandline method declaration --- .../java/reposense/wizard/InputBuilder.java | 69 ------------------- .../java/reposense/wizard/WizardRunner.java | 2 +- 2 files changed, 1 insertion(+), 70 deletions(-) diff --git a/src/main/java/reposense/wizard/InputBuilder.java b/src/main/java/reposense/wizard/InputBuilder.java index 0c6edb2609..f1075a9dbf 100644 --- a/src/main/java/reposense/wizard/InputBuilder.java +++ b/src/main/java/reposense/wizard/InputBuilder.java @@ -290,73 +290,4 @@ private static String addQuotationMarksToPath(Path path) { public boolean isShallowCloning() { return shallowCloning; } - - /** - * Crack a command line. - * - * @param toProcess the command line to process. - * @return the command line broken into strings. - * @throws BuildException if there are unbalanced quotes. - * An empty or null toProcess parameter results in a zero sized array. - */ - public static String[] translateCommandline(String toProcess) { - if (toProcess == null || toProcess.isEmpty()) { - //no command? no string - return new String[0]; - } - // parse with a simple finite state machine - - final int normal = 0; - final int inQuote = 1; - final int inDoubleQuote = 2; - int state = normal; - final StringTokenizer tok = new StringTokenizer(toProcess, "\"' ", true); - final ArrayList result = new ArrayList<>(); - final StringBuilder current = new StringBuilder(); - boolean lastTokenHasBeenQuoted = false; - - while (tok.hasMoreTokens()) { - String nextTok = tok.nextToken(); - switch (state) { - case inQuote: - if ("'".equals(nextTok)) { - lastTokenHasBeenQuoted = true; - state = normal; - } else { - current.append(nextTok); - } - break; - case inDoubleQuote: - if ("\"".equals(nextTok)) { - lastTokenHasBeenQuoted = true; - state = normal; - } else { - current.append(nextTok); - } - break; - default: - if ("'".equals(nextTok)) { - state = inQuote; - } else if ("\"".equals(nextTok)) { - state = inDoubleQuote; - } else if (" ".equals(nextTok)) { - if (lastTokenHasBeenQuoted || current.length() > 0) { - result.add(current.toString()); - current.setLength(0); - } - } else { - current.append(nextTok); - } - lastTokenHasBeenQuoted = false; - break; - } - } - if (lastTokenHasBeenQuoted || current.length() > 0) { - result.add(current.toString()); - } - if (state == inQuote || state == inDoubleQuote) { - throw new BuildException("unbalanced quotes in " + toProcess); - } - return result.toArray(new String[0]); - } } diff --git a/src/main/java/reposense/wizard/WizardRunner.java b/src/main/java/reposense/wizard/WizardRunner.java index 42072bc1cb..afb29a7580 100644 --- a/src/main/java/reposense/wizard/WizardRunner.java +++ b/src/main/java/reposense/wizard/WizardRunner.java @@ -1,6 +1,6 @@ package reposense.wizard; -import static reposense.wizard.InputBuilder.translateCommandline; +import static org.apache.tools.ant.types.Commandline.translateCommandline; import java.util.ArrayDeque; import java.util.Deque; From 70297b33e07f06e392b1e20654d375825b363687 Mon Sep 17 00:00:00 2001 From: sikai00 Date: Mon, 27 Mar 2023 02:07:08 +0800 Subject: [PATCH 21/25] Fix checkstyle --- src/main/java/reposense/wizard/InputBuilder.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/reposense/wizard/InputBuilder.java b/src/main/java/reposense/wizard/InputBuilder.java index f1075a9dbf..6317bf5a05 100644 --- a/src/main/java/reposense/wizard/InputBuilder.java +++ b/src/main/java/reposense/wizard/InputBuilder.java @@ -2,10 +2,6 @@ import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.StringTokenizer; - -import org.apache.tools.ant.BuildException; import reposense.parser.ArgsParser; From 60563c04132e8a87f8eb55d166cdab93767d39e4 Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Sun, 2 Apr 2023 21:59:00 +0800 Subject: [PATCH 22/25] Fix addRepos missing whitespace bug, Remove unused methods in inputBuilder, Update BasicWizard order --- .../java/reposense/wizard/BasicWizard.java | 4 +- .../java/reposense/wizard/InputBuilder.java | 195 +----------------- 2 files changed, 4 insertions(+), 195 deletions(-) diff --git a/src/main/java/reposense/wizard/BasicWizard.java b/src/main/java/reposense/wizard/BasicWizard.java index b0e31f1358..a1bc766c32 100644 --- a/src/main/java/reposense/wizard/BasicWizard.java +++ b/src/main/java/reposense/wizard/BasicWizard.java @@ -11,10 +11,10 @@ */ public class BasicWizard extends Wizard { private static final Prompt[] INITIAL_PROMPTS = new Prompt[] { + new RepoPrompt(), new OptionalSincePrompt(), new OptionalUntilPrompt(), - new OptionalViewPrompt(), - new RepoPrompt() + new OptionalViewPrompt() }; public BasicWizard() { super(INITIAL_PROMPTS); diff --git a/src/main/java/reposense/wizard/InputBuilder.java b/src/main/java/reposense/wizard/InputBuilder.java index 6317bf5a05..daf9aa87e2 100644 --- a/src/main/java/reposense/wizard/InputBuilder.java +++ b/src/main/java/reposense/wizard/InputBuilder.java @@ -1,7 +1,6 @@ package reposense.wizard; import java.nio.file.Path; -import java.nio.file.Paths; import reposense.parser.ArgsParser; @@ -14,7 +13,6 @@ public class InputBuilder { private static final String WHITESPACE = " "; private StringBuilder input; - private boolean shallowCloning; public InputBuilder() { init(); @@ -22,11 +20,10 @@ public InputBuilder() { /** * Initialize variables to default values. - * Used by {@link InputBuilder#InputBuilder() constructor} and {@link InputBuilder#reset() reset} method. + * Used by {@link InputBuilder#InputBuilder() constructor}. */ private void init() { input = new StringBuilder(); - shallowCloning = false; } /** @@ -36,26 +33,6 @@ public String build() { return input.toString(); } - /** - * Add a help flag to the input. - * This method should only be called once in one build. - */ - public InputBuilder addHelp() { - input.append(ArgsParser.HELP_FLAGS[0] + WHITESPACE); - return this; - } - - /** - * Adds the config flag with the {@code path} as argument to the input. - * This method should only be called once in one build. - * - * @param path The config folder path. - */ - public InputBuilder addConfig(Path path) { - input.append(ArgsParser.CONFIG_FLAGS[0] + WHITESPACE + addQuotationMarksToPath(path) + WHITESPACE); - return this; - } - /** * Adds the repo flag with the {@code paths} as arguments to the input. * This method should only be called once in one build. @@ -63,7 +40,7 @@ public InputBuilder addConfig(Path path) { * @param paths The repo paths. */ public InputBuilder addRepos(String paths) { - input.append(ArgsParser.REPO_FLAGS[0] + WHITESPACE + paths); + input.append(ArgsParser.REPO_FLAGS[0] + WHITESPACE + paths + WHITESPACE); return this; } @@ -87,27 +64,6 @@ public InputBuilder addView() { return this; } - /** - * Adds the output flag with the {@code path} as argument to the input. - * This method should only be called once in one build. - * - * @param path The output folder path (type {@link Path}). - */ - public InputBuilder addOutput(Path path) { - input.append(ArgsParser.OUTPUT_FLAGS[0] + WHITESPACE + addQuotationMarksToPath(path) + WHITESPACE); - return this; - } - - /** - * Adds the output flag with the {@code path} as argument to the input. - * This method should only be called once in one build. - * - * @param path The output folder path (type {@link String}). - */ - public InputBuilder addOutput(String path) { - return addOutput(Paths.get(path)); - } - /** * Adds the since flag with the {@code date} as argument to the input. * This method should only be called once in one build. @@ -130,150 +86,6 @@ public InputBuilder addUntilDate(String date) { return this; } - /** - * Adds the period flag with the {@code period} as argument to the input. - * This method should only be called once in one build. - * - * @param period The period. - */ - public InputBuilder addPeriod(String period) { - input.append(ArgsParser.PERIOD_FLAGS[0] + WHITESPACE + period + WHITESPACE); - return this; - } - - /** - * Adds the format flag with the {@code formats} as argument to the input. - * This method should only be called once in one build. - * - * @param formats The formats that need to be evaluated. - */ - public InputBuilder addFormats(String formats) { - input.append(ArgsParser.FORMAT_FLAGS[0] + WHITESPACE + formats + WHITESPACE); - return this; - } - - /** - * Adds the ignoreStandaloneConfig flag to the input. - * This method should only be called once in one build. - */ - public InputBuilder addIgnoreStandaloneConfig() { - input.append(ArgsParser.IGNORE_CONFIG_FLAGS[0] + WHITESPACE); - return this; - } - - /** - * Adds the ignoreFilesizeLimit flag to the input. - * This method should only be called once in one build. - */ - public InputBuilder addIgnoreFilesizeLimit() { - input.append(ArgsParser.IGNORE_SIZELIMIT_FLAGS[0] + WHITESPACE); - return this; - } - - /** - * Adds the timezone flag with the {@code zoneId} as argument to the input. - * This method should only be called once in one build. - */ - public InputBuilder addTimezone(String zoneId) { - input.append(ArgsParser.TIMEZONE_FLAGS[0] + WHITESPACE + zoneId + WHITESPACE); - return this; - } - - /** - * Adds the cloning threads flag with the {@code threads} as argument to the input. - * This method should only be called once in one build. - * - * @param threads The number of threads for cloning. - */ - public InputBuilder addNumCloningThreads(int threads) { - input.append(ArgsParser.CLONING_THREADS_FLAG[0] + WHITESPACE + threads + WHITESPACE); - return this; - } - - /** - * Adds the analysis threads flag with the {@code threads} as argument to the input. - * This method should only be called once in one build. - * - * @param threads The number of threads for analysis. - */ - public InputBuilder addNumAnalysisThreads(int threads) { - input.append(ArgsParser.ANALYSIS_THREADS_FLAG[0] + WHITESPACE + threads + WHITESPACE); - return this; - } - - /** - * Adds the flag to enable shallow cloning. - * This method should only be called once in one build. - */ - public InputBuilder addShallowCloning() { - input.append(ArgsParser.SHALLOW_CLONING_FLAGS[0] + WHITESPACE); - shallowCloning = true; - return this; - } - - /** - * Adds the flag to enable find previous authors. - * This method should only be called once in one build. - */ - public InputBuilder addFindPreviousAuthors() { - input.append(ArgsParser.FIND_PREVIOUS_AUTHORS_FLAGS[0] + WHITESPACE); - return this; - } - - /** - * Adds the flag to enable test mode. - * This method should only be called once in one build. - */ - public InputBuilder addTestMode() { - input.append(ArgsParser.TEST_MODE_FLAG[0] + WHITESPACE); - return this; - } - - /** - * Adds the flag to include modified date in lines. - * This method should only be called once in one build. - */ - public InputBuilder addLastModifiedDateFlags() { - input.append(ArgsParser.LAST_MODIFIED_DATE_FLAGS[0] + WHITESPACE); - return this; - } - - /** - * Adds the flag to enable fresh cloning. - * This method should only be called once in one build. - */ - public InputBuilder addFreshCloning() { - input.append(ArgsParser.FRESH_CLONING_FLAG[0] + WHITESPACE); - return this; - } - - /** - * Adds {@code content} to the input. - */ - public InputBuilder add(String content) { - input.append(content + WHITESPACE); - return this; - } - - /** - * Adds {@code num} of white spaces to the input. - * - * @param num The number of white spaces to add. - */ - public InputBuilder addWhiteSpace(int num) { - for (int i = 0; i < num; i++) { - input.append(WHITESPACE); - } - return this; - } - - /** - * Clears all input and flags given. - */ - public InputBuilder reset() { - init(); - return this; - } private static String addQuotationMarksToPath(String path) { return '"' + path + '"'; @@ -283,7 +95,4 @@ private static String addQuotationMarksToPath(Path path) { return addQuotationMarksToPath(path.toString()); } - public boolean isShallowCloning() { - return shallowCloning; - } } From 41e76698118b109629b2851680e2b2fe460c1d92 Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Sun, 2 Apr 2023 22:07:22 +0800 Subject: [PATCH 23/25] Fix failing WizardRunner tests --- .../reposense/wizard/WizardRunnerTest.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/test/java/reposense/wizard/WizardRunnerTest.java b/src/test/java/reposense/wizard/WizardRunnerTest.java index eab4968935..c4f57cdeb4 100644 --- a/src/test/java/reposense/wizard/WizardRunnerTest.java +++ b/src/test/java/reposense/wizard/WizardRunnerTest.java @@ -21,10 +21,10 @@ public class WizardRunnerTest { public void buildInput_repoOnly_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); String input = new WizardInputBuilder() + .add(REPO_LINK) .addNoFlag() .addNoFlag() .addNoFlag() - .add(REPO_LINK) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); @@ -39,19 +39,19 @@ public void buildInput_sinceDateAndRepo_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); // Yes only for sinceDate flag String input = new WizardInputBuilder() + .add(REPO_LINK) .addYesFlag() .add(SINCE_DATE) .addNoFlag() .addNoFlag() - .add(REPO_LINK) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); wizardRunner.buildInput(sc); String expectedInput = new InputBuilder() - .addSinceDate(SINCE_DATE) .addRepos(REPO_LINK) + .addSinceDate(SINCE_DATE) .build(); assertEquals(expectedInput, wizardRunner.getBuiltInput()); } @@ -60,19 +60,19 @@ public void buildInput_sinceDateAndRepo_success() { public void buildInput_untilDateAndRepo_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); String input = new WizardInputBuilder() + .add(REPO_LINK) .addNoFlag() .addYesFlag() .add(UNTIL_DATE) .addNoFlag() - .add(REPO_LINK) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); wizardRunner.buildInput(sc); String expectedInput = new InputBuilder() - .addUntilDate(UNTIL_DATE) .addRepos(REPO_LINK) + .addUntilDate(UNTIL_DATE) .build(); assertEquals(expectedInput, wizardRunner.getBuiltInput()); } @@ -81,21 +81,21 @@ public void buildInput_untilDateAndRepo_success() { public void buildInput_sinceDateAndUntilDateAndRepo_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); String input = new WizardInputBuilder() + .add(REPO_LINK) .addYesFlag() .add(SINCE_DATE) .addYesFlag() .add(UNTIL_DATE) .addNoFlag() - .add(REPO_LINK) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); wizardRunner.buildInput(sc); String expectedInput = new InputBuilder() + .addRepos(REPO_LINK) .addSinceDate(SINCE_DATE) .addUntilDate(UNTIL_DATE) - .addRepos(REPO_LINK) .build(); assertEquals(expectedInput, wizardRunner.getBuiltInput()); } @@ -105,19 +105,19 @@ public void buildInput_viewAndRepo_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); // Yes only for view flag String input = new WizardInputBuilder() + .add(REPO_LINK) .addNoFlag() .addNoFlag() .addYesFlag() .add(REPORT_PATH) - .add(REPO_LINK) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); wizardRunner.buildInput(sc); String expectedInput = new InputBuilder() - .addView(Paths.get(REPORT_PATH)) .addRepos(REPO_LINK) + .addView(Paths.get(REPORT_PATH)) .build(); assertEquals(expectedInput, wizardRunner.getBuiltInput()); } @@ -127,23 +127,23 @@ public void buildInput_allFlags_success() { WizardRunner wizardRunner = new WizardRunner(new BasicWizard()); // Yes for all flags String input = new WizardInputBuilder() + .add(REPO_LINK) .addYesFlag() .add(SINCE_DATE) .addYesFlag() .add(UNTIL_DATE) .addYesFlag() .add(REPORT_PATH) - .add(REPO_LINK) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); wizardRunner.buildInput(sc); String expectedInput = new InputBuilder() + .addRepos(REPO_LINK) .addSinceDate(SINCE_DATE) .addUntilDate(UNTIL_DATE) .addView(Paths.get(REPORT_PATH)) - .addRepos(REPO_LINK) .build(); assertEquals(expectedInput, wizardRunner.getBuiltInput()); } From f2815d6ecf6364dbfa9215a7b14a936359b5fa9a Mon Sep 17 00:00:00 2001 From: sikai00 Date: Mon, 3 Apr 2023 20:12:16 +0800 Subject: [PATCH 24/25] Add docs to using the init flag --- docs/_markbind/layouts/ug-sitenav.md | 1 + docs/ug/cli.md | 14 ++++++ docs/ug/generatingReports.md | 5 ++ docs/ug/usingInit.md | 74 ++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 docs/ug/usingInit.md diff --git a/docs/_markbind/layouts/ug-sitenav.md b/docs/_markbind/layouts/ug-sitenav.md index 5622340ed7..7da35f4339 100644 --- a/docs/_markbind/layouts/ug-sitenav.md +++ b/docs/_markbind/layouts/ug-sitenav.md @@ -8,6 +8,7 @@ {level: 2, name: "CLI syntax reference", link: "ug/cli.html"}, {level: 2, name: "Config files format", link: "ug/configFiles.html"}, {level: 2, name: "Using `@@author` tags", link: "ug/usingAuthorTags.html"}, + {level: 2, name: "Using `--init` flag", link: "ug/usingInit.html"}, {level: 2, name: "RepoSense with Netlify", link: "ug/withNetlify.html"}, {level: 2, name: "RepoSense with GitHub Actions", link: "ug/withGithubActions.html"}, {level: 2, name: "RepoSense with Travis", link: "ug/withTravis.html"}, diff --git a/docs/ug/cli.md b/docs/ug/cli.md index c676635cc2..db0829968d 100644 --- a/docs/ug/cli.md +++ b/docs/ug/cli.md @@ -146,6 +146,7 @@ This flag overrides the `Ignore file size limit` field in the CSV config file. * The wizard will run through the basic config flags in this order: `--since`, `--until`, `--view`, `--repos`. * This flag overrides all other flags and thus should be used on its own. +* A guide of the steps performed by the wizard is located at [Appendix: Using --init flag](./usingInit.html). @@ -190,6 +191,8 @@ This flag overrides the `Ignore file size limit` field in the CSV config file. +
+ ### `--repo`, `--repos`, `-r` **`--repo REPO_LOCATION`**: Specifies which repositories to analyze. @@ -203,6 +206,8 @@ This flag overrides the `Ignore file size limit` field in the CSV config file. Cannot be used with `--config`. This flag takes precedence over `--config`. +
+ ### `--shallow-cloning`, `-S` @@ -219,6 +224,8 @@ Cannot be used with `--last-modified-date`. This may result in an incorrect last +
+ ### `--since`, `-s` **`--since START_DATE`**: Specifies the start date for the period to be analyzed. @@ -233,6 +240,7 @@ Cannot be used with `--last-modified-date`. This may result in an incorrect last * If `d1` is specified as the start date (`--since d1` or `-s d1`), then the program will search for the earliest commit date of all repositories and use that as the start date. * If `d1` is specified together with `--period`, then the program will warn that the date range being analyzed may be incorrect. +
### `--timezone`, `-t` @@ -245,6 +253,8 @@ Cannot be used with `--last-modified-date`. This may result in an incorrect last +
+ ### `--until`, `-u` **`--until END_DATE`**: Specifies the end date of the analysis period. @@ -257,6 +267,7 @@ Cannot be used with `--last-modified-date`. This may result in an incorrect last Note: If the end date is not specified, the date of generating the report will be taken as the end date. +
@@ -271,6 +282,8 @@ Cannot be used with any other flags. This flag takes precedence over all other f +
+ ### `--view`, `-v` **`--view [REPORT_FOLDER]`**: Specifies that the report should be opened in the default browser. @@ -278,3 +291,4 @@ Cannot be used with any other flags. This flag takes precedence over all other f Default: `./reposense-report` * Alias: `-v` * Example:`--view` or `-v` +
diff --git a/docs/ug/generatingReports.md b/docs/ug/generatingReports.md index 42f40c97f8..5085bedff1 100644 --- a/docs/ug/generatingReports.md +++ b/docs/ug/generatingReports.md @@ -26,6 +26,8 @@ For other types of repositories, external links are disabled. +
+ ## Generating reports locally 1. **Ensure you have the prerequisites**: @@ -47,6 +49,9 @@ For other types of repositories, external links are disabled. **Alternatively**, you may also use the RepoSense CLI set-up wizard, which will take you through a basic configuration of RepoSense through the following command: * `java -jar RepoSense.jar --init` +A guide to explaining each step of the set-up wizard can also be found at [Appendix: Using --init flag](./usingInit.html), if you would like to follow along to better understand how to use RepoSense in the future. +
+ ## Generating reports remotely diff --git a/docs/ug/usingInit.md b/docs/ug/usingInit.md new file mode 100644 index 0000000000..631ec1cc22 --- /dev/null +++ b/docs/ug/usingInit.md @@ -0,0 +1,74 @@ +{% set title = "Appendix: Using `--init` flag" %} + + title: "{{ title | safe }}" + + +{% from 'scripts/macros.njk' import embed, step with context %} + +

{{ title }}

+ +
+ +The `--init` flag makes it easier for new users to get into using RepoSense, by guiding them step-by-step through a wizard with the most essential flags. +
+ +This guide serves to assist new users in understanding what the `--init` flag is doing, and eventually helps them understand how to use RepoSense without the `init` flag. + +If you have yet to do so, download the latest JAR file from our releases. The instructions are given below. You may ignore Step 3, as the `init` flag supersedes it. + +{{ embed("**Generating reports → Generating reports locally**", "generatingReports.md#section-generating-reports-locally") }} + +### Explanation of each step + +#### List of repository locations to be analyzed: `--repos` + +Upon using `java -jar RepoSense.java --init`, the wizard will ask for a list of repository locations, separated by spaces. + +This list of repository locations is necessary, as it will be the repositories analyzed by RepoSense at the end of the wizard. + +RepoSense accepts both remote Git repository HTTPS links, as well as paths to local Git repositories. + +Given below is the actual CLI flag being used. These embedded subsections will be given throughout this guide to help you pinpoint and locate it in your future references. + +{{ embed("**CLI syntax reference → `--repos`**", "cli.md#section-repos") }} + +
+ +#### Start date of the analysis: `--since` + +The wizard will ask for the start date of the period of the analysis next. + +The start date, by default, will be one month before the current date. It is hence not necessary to include when you are using the CLI to run RepoSense, but it is likely that you will want to analyze a period with a different starting date. + +Given below is the actual CLI flag being used. + +{{ embed("**CLI syntax reference → `--since`**", "cli.md#section-since") }} + +#### Start date of the analysis: `--until` + +The wizard will ask for the until date of the period of the analysis next. + +The until date, by default, will be the current date. Again, it is not necessary to include when you are using the CLI to run RepoSense. + +Given below is the actual CLI flag being used. + +{{ embed("**CLI syntax reference → `--until`**", "cli.md#section-until") }} + +#### Viewing the report locally: `--view` + +The wizard will ask if you want to start a local server to view the report immediately after the report is generated. By indicating `Y`, a server will be started on your computer on port 9000, where the report can be viewed at http://localhost:9000/. + +This flag is used without any arguments in this basic wizard. + +Given below is the actual CLI flag being used. + +{{ embed("**CLI syntax reference → `--view`**", "cli.md#section-view") }} + +
+ +### Conclusion + +At this stage, the `--init` wizard would have completed, and the generation of the RepoSense report is underway. It may take a few seconds to a few minutes, depending on the number of repositories entered, as well as your network speed. + +After the report generates, you may want to proceed to [Using reports](usingReports.html) in order to better understand the interface and how you can use the report generated by RepoSense. You may also want to take a closer look at the other config flags provided by RepoSense at [CLI syntax reference](cli.html) to understand what other features are available. + From 9c3f6c229ed5d1dd9affbce890d5c403136a9ed3 Mon Sep 17 00:00:00 2001 From: Marcus Tang Date: Tue, 4 Apr 2023 01:02:45 +0800 Subject: [PATCH 25/25] Update ViewPrompt --- .../java/reposense/wizard/BasicWizard.java | 4 ++-- .../wizard/prompt/OptionalViewPrompt.java | 17 -------------- .../reposense/wizard/prompt/ViewPrompt.java | 23 ++++++++++++------- .../reposense/wizard/WizardRunnerTest.java | 8 ++----- 4 files changed, 19 insertions(+), 33 deletions(-) delete mode 100644 src/main/java/reposense/wizard/prompt/OptionalViewPrompt.java diff --git a/src/main/java/reposense/wizard/BasicWizard.java b/src/main/java/reposense/wizard/BasicWizard.java index a1bc766c32..4dfd38032b 100644 --- a/src/main/java/reposense/wizard/BasicWizard.java +++ b/src/main/java/reposense/wizard/BasicWizard.java @@ -2,9 +2,9 @@ import reposense.wizard.prompt.OptionalSincePrompt; import reposense.wizard.prompt.OptionalUntilPrompt; -import reposense.wizard.prompt.OptionalViewPrompt; import reposense.wizard.prompt.Prompt; import reposense.wizard.prompt.RepoPrompt; +import reposense.wizard.prompt.ViewPrompt; /** * Represents a basic wizard run. @@ -14,7 +14,7 @@ public class BasicWizard extends Wizard { new RepoPrompt(), new OptionalSincePrompt(), new OptionalUntilPrompt(), - new OptionalViewPrompt() + new ViewPrompt() }; public BasicWizard() { super(INITIAL_PROMPTS); diff --git a/src/main/java/reposense/wizard/prompt/OptionalViewPrompt.java b/src/main/java/reposense/wizard/prompt/OptionalViewPrompt.java deleted file mode 100644 index a75cc54cd5..0000000000 --- a/src/main/java/reposense/wizard/prompt/OptionalViewPrompt.java +++ /dev/null @@ -1,17 +0,0 @@ -package reposense.wizard.prompt; - -/** - * Represents an Optional Prompt to get the view flag. - */ -public class OptionalViewPrompt extends OptionalPrompt { - private static final String DESCRIPTION = "Do you want to start a server to display the report?"; - - public OptionalViewPrompt() { - super(DESCRIPTION); - } - - @Override - public Prompt[] optionallyRun() { - return new Prompt[]{new ViewPrompt()}; - } -} diff --git a/src/main/java/reposense/wizard/prompt/ViewPrompt.java b/src/main/java/reposense/wizard/prompt/ViewPrompt.java index 4363205cde..0a6e92b529 100644 --- a/src/main/java/reposense/wizard/prompt/ViewPrompt.java +++ b/src/main/java/reposense/wizard/prompt/ViewPrompt.java @@ -1,30 +1,37 @@ package reposense.wizard.prompt; -import java.nio.file.Paths; - import reposense.wizard.InputBuilder; /** * Represents a Prompt to get the view flag. */ public class ViewPrompt extends Prompt { - public static final String DESCRIPTION = "Enter directory of report to display in server. " - + "If not specified, default directory will be used"; + private static final String DESCRIPTION = "Do you want to start a server to display the report?"; + private static final String YES_FLAG = "Y"; + private static final String NO_FLAG = "N"; + private static final String FORMAT = String.format("%s/%s", YES_FLAG, NO_FLAG); public ViewPrompt() { - super(DESCRIPTION); + super(DESCRIPTION, FORMAT); } @Override public InputBuilder addToInput(InputBuilder inputBuilder) { - if (getResponse().isEmpty()) { + if (getResponse().compareToIgnoreCase(YES_FLAG) == 0) { return inputBuilder.addView(); } - return inputBuilder.addView(Paths.get(getResponse())); + + return inputBuilder; } @Override public Prompt[] run() { - return new Prompt[] {}; + if (getResponse().compareToIgnoreCase(YES_FLAG) == 0 + || getResponse().compareToIgnoreCase(NO_FLAG) == 0) { + return new Prompt[] {}; + } + + // Repeat ViewPrompt until a valid input is provided + return new Prompt[] {this}; } } diff --git a/src/test/java/reposense/wizard/WizardRunnerTest.java b/src/test/java/reposense/wizard/WizardRunnerTest.java index c4f57cdeb4..801b383661 100644 --- a/src/test/java/reposense/wizard/WizardRunnerTest.java +++ b/src/test/java/reposense/wizard/WizardRunnerTest.java @@ -4,7 +4,6 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; -import java.nio.file.Paths; import java.util.Scanner; import org.junit.jupiter.api.Test; @@ -14,7 +13,6 @@ public class WizardRunnerTest { private static final String SINCE_DATE = "30/09/2022"; private static final String UNTIL_DATE = "15/03/2023"; - private static final String REPORT_PATH = "C:\\User\\RepoSense"; private static final String REPO_LINK = "https://github.com/reposense/RepoSense.git"; @Test @@ -109,7 +107,6 @@ public void buildInput_viewAndRepo_success() { .addNoFlag() .addNoFlag() .addYesFlag() - .add(REPORT_PATH) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); @@ -117,7 +114,7 @@ public void buildInput_viewAndRepo_success() { String expectedInput = new InputBuilder() .addRepos(REPO_LINK) - .addView(Paths.get(REPORT_PATH)) + .addView() .build(); assertEquals(expectedInput, wizardRunner.getBuiltInput()); } @@ -133,7 +130,6 @@ public void buildInput_allFlags_success() { .addYesFlag() .add(UNTIL_DATE) .addYesFlag() - .add(REPORT_PATH) .build(); InputStream targetStream = new ByteArrayInputStream(input.getBytes()); Scanner sc = new Scanner(targetStream); @@ -143,7 +139,7 @@ public void buildInput_allFlags_success() { .addRepos(REPO_LINK) .addSinceDate(SINCE_DATE) .addUntilDate(UNTIL_DATE) - .addView(Paths.get(REPORT_PATH)) + .addView() .build(); assertEquals(expectedInput, wizardRunner.getBuiltInput()); }