diff --git a/README.md b/README.md new file mode 100644 index 0000000..3654983 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +
+

File Merger

+

CLI tool for merging files considering dependencies

+ Logo +
+ + +### Restrictions + +In order for this tool to find the dependencies, the files must contain a directive with the following format: + + require ‘relative/path/from/root’ + +In case of a circular dependency, the tool will print an error and exit. + +In case of a missing dependency, the tool will print a warning and continue. + +### Usage + +1. Run the application. +2. Enter the path to the root directory. _(Can be relative or absolute)_ +3. Enter the path to the output file. _(Can be relative or absolute)_ + +### Example + +To test the tool, you can use `example/` folder. It should work without any errors and warnings. + +1. Run the application. +2. Type `example` +3. Press enter. +4. Type `output.txt` +5. Press enter. + +The tool will print a mering order and create a file `output.txt` in the root directory with the merged content. \ No newline at end of file diff --git a/example/Folder 2/File 2-2 b/example/Folder 2/File 2-2 index c6ff359..7d91e2a 100644 --- a/example/Folder 2/File 2-2 +++ b/example/Folder 2/File 2-2 @@ -1,5 +1,5 @@ require ‘Folder 1/File 1-1’ -require ‘Folder 2/File 2-2’ +require ‘Folder 2/File 2-1’ In pretium dictum lacinia. In rutrum, neque a dignissim maximus, dolor mi pretium ante, nec volutpat justo dolor non nulla. Vivamus nec suscipit nisl, ornare luctus erat. Aliquam eget est diff --git a/example/Folder 3/InFolder 3/File 3-1 b/example/Folder 3/InFolder 3/File 3-1 deleted file mode 100644 index c91f53b..0000000 --- a/example/Folder 3/InFolder 3/File 3-1 +++ /dev/null @@ -1 +0,0 @@ -sjfklasdjfsdfkslflkhakljhakljhalkjsa \ No newline at end of file diff --git a/example/Folder 3/SubFolder 3/File 3-1 b/example/Folder 3/SubFolder 3/File 3-1 new file mode 100644 index 0000000..a331757 --- /dev/null +++ b/example/Folder 3/SubFolder 3/File 3-1 @@ -0,0 +1,4 @@ +Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. +Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. +Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. +Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. diff --git a/src/timnekk/Application.java b/src/timnekk/Application.java index 834c9ce..7c86377 100644 --- a/src/timnekk/Application.java +++ b/src/timnekk/Application.java @@ -1,7 +1,8 @@ package timnekk; -import timnekk.exceptions.CanNotGetDependenciesException; +import timnekk.exceptions.DependenciesGettingException; import timnekk.exceptions.CircularDependencyException; +import timnekk.exceptions.FileWritingException; import timnekk.models.DependenciesFinder; import timnekk.models.FileDependenciesFinder; import timnekk.models.Graph; @@ -19,12 +20,33 @@ public Application(InputStream inputStream, OutputStream outputStream) { } public void run() { - File root = getRootDirectory(); - getGraphOfFiles(root).ifPresent(this::printGraphInfo); + File root = getFileFromUser("Enter root directory: "); + File output = getFileFromUser("Enter output file: "); + + Optional> graph = getGraphOfFiles(root); + if (graph.isEmpty()) { + return; + } + + Optional> sortedFiles = getSortedListOfFiles(graph.get()); + if (sortedFiles.isEmpty()) { + return; + } + + if (graph.get().hasMissingDependencies()) { + printStream.println("\nMissing dependencies: "); + printMissingDependencies(graph.get()); + } + + printStream.println("\nFiles merging order:"); + printFilesMergingOrder(sortedFiles.get()); + + mergeContent(sortedFiles.get(), output); + printStream.println("\nFiles merged successfully to " + output.getAbsolutePath()); } - private File getRootDirectory() { - printStream.println("Enter the path to the root directory: "); + private File getFileFromUser(String promptMessage) { + printStream.println(promptMessage); String path = scanner.nextLine(); return new File(path); } @@ -41,31 +63,12 @@ private Optional> getGraphOfFiles(File root) { try { return Optional.of(new Graph<>(files, dependenciesFinder)); - } catch (CanNotGetDependenciesException e) { + } catch (DependenciesGettingException e) { printStream.println(e.getMessage()); return Optional.empty(); } } - private void printGraphInfo(Graph graph) { - Optional> sortedFiles = getSortedListOfFiles(graph); - - if (sortedFiles.isEmpty()) { - return; - } - - if (graph.hasMissingDependencies()) { - printStream.println("\nMissing dependencies: "); - printMissingDependencies(graph); - } - - printStream.println("\nFiles merging order:"); - printFilesMergingOrder(sortedFiles.get()); - - printStream.println("\nMerged content:"); - printMergedContent(sortedFiles.get()); - } - private Optional> getSortedListOfFiles(Graph graph) { try { return Optional.of(graph.getSortedListOfItems()); @@ -83,13 +86,16 @@ private void printFilesMergingOrder(Collection files) { } } - private void printMergedContent(Collection files) { + private void mergeContent(Collection files, File outputFile) { Set notReadFiles = new HashSet<>(); for (File file : files) { try { - FileUtils.printFile(file, printStream); + FileUtils.addFileContentToFile(file, outputFile); } catch (FileNotFoundException e) { notReadFiles.add(file); + } catch (FileWritingException e) { + printStream.println(e.getMessage()); + return; } } diff --git a/src/timnekk/FileUtils.java b/src/timnekk/FileUtils.java index bf0a3f9..672c043 100644 --- a/src/timnekk/FileUtils.java +++ b/src/timnekk/FileUtils.java @@ -1,8 +1,8 @@ package timnekk; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.PrintStream; +import timnekk.exceptions.FileWritingException; + +import java.io.*; import java.util.HashSet; import java.util.Objects; import java.util.Scanner; @@ -30,16 +30,18 @@ public static Set getFiles(File directory) { return files; } - /** - * Prints contents of a file - * - * @param file File to print - * @throws FileNotFoundException if the file can not be read - */ - public static void printFile(File file, PrintStream printStream) throws FileNotFoundException { + + public static void addFileContentToFile(File file, File fileToAdd) + throws FileNotFoundException, FileWritingException { Scanner scanner = new Scanner(file); - while (scanner.hasNextLine()) { - printStream.println(scanner.nextLine()); + + try (Writer writer = new FileWriter(fileToAdd, true)) { + while (scanner.hasNextLine()) { + writer.write(scanner.nextLine()); + writer.write(System.lineSeparator()); + } + } catch (IOException e) { + throw new FileWritingException("Could not write to file: " + fileToAdd.getAbsolutePath(), e); } } } diff --git a/src/timnekk/exceptions/CanNotGetDependenciesException.java b/src/timnekk/exceptions/CanNotGetDependenciesException.java deleted file mode 100644 index 24c6c62..0000000 --- a/src/timnekk/exceptions/CanNotGetDependenciesException.java +++ /dev/null @@ -1,7 +0,0 @@ -package timnekk.exceptions; - -public class CanNotGetDependenciesException extends Exception { - public CanNotGetDependenciesException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/timnekk/exceptions/DependenciesGettingException.java b/src/timnekk/exceptions/DependenciesGettingException.java new file mode 100644 index 0000000..a42c429 --- /dev/null +++ b/src/timnekk/exceptions/DependenciesGettingException.java @@ -0,0 +1,7 @@ +package timnekk.exceptions; + +public class DependenciesGettingException extends Exception { + public DependenciesGettingException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/timnekk/exceptions/FileWritingException.java b/src/timnekk/exceptions/FileWritingException.java new file mode 100644 index 0000000..c718889 --- /dev/null +++ b/src/timnekk/exceptions/FileWritingException.java @@ -0,0 +1,7 @@ +package timnekk.exceptions; + +public class FileWritingException extends Exception { + public FileWritingException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/timnekk/models/DependenciesFinder.java b/src/timnekk/models/DependenciesFinder.java index 47e0925..bd2670c 100644 --- a/src/timnekk/models/DependenciesFinder.java +++ b/src/timnekk/models/DependenciesFinder.java @@ -1,6 +1,6 @@ package timnekk.models; -import timnekk.exceptions.CanNotGetDependenciesException; +import timnekk.exceptions.DependenciesGettingException; import java.util.Set; @@ -10,7 +10,7 @@ public interface DependenciesFinder { * * @param item Item to find dependencies of * @return Set of items that the item depends on - * @throws CanNotGetDependenciesException if dependencies can not be gotten + * @throws DependenciesGettingException if dependencies can not be gotten */ - Set findDependencies(E item) throws CanNotGetDependenciesException; + Set findDependencies(E item) throws DependenciesGettingException; } diff --git a/src/timnekk/models/FileDependenciesFinder.java b/src/timnekk/models/FileDependenciesFinder.java index f683722..105238a 100644 --- a/src/timnekk/models/FileDependenciesFinder.java +++ b/src/timnekk/models/FileDependenciesFinder.java @@ -1,6 +1,6 @@ package timnekk.models; -import timnekk.exceptions.CanNotGetDependenciesException; +import timnekk.exceptions.DependenciesGettingException; import java.io.File; import java.io.FileNotFoundException; @@ -23,16 +23,16 @@ public FileDependenciesFinder(File projectRoot) { * * @param file File to find dependencies of * @return Set of files that the file depends on - * @throws CanNotGetDependenciesException if the file can not be read + * @throws DependenciesGettingException if the file can not be read */ - public Set findDependencies(File file) throws CanNotGetDependenciesException { + public Set findDependencies(File file) throws DependenciesGettingException { Set dependencies = new HashSet<>(); Scanner scanner; try { scanner = new Scanner(file); } catch (FileNotFoundException e) { - throw new CanNotGetDependenciesException( + throw new DependenciesGettingException( "Can not read file to find dependencies: " + file.getAbsolutePath(), e); } diff --git a/src/timnekk/models/Graph.java b/src/timnekk/models/Graph.java index 2883141..859177d 100644 --- a/src/timnekk/models/Graph.java +++ b/src/timnekk/models/Graph.java @@ -1,6 +1,6 @@ package timnekk.models; -import timnekk.exceptions.CanNotGetDependenciesException; +import timnekk.exceptions.DependenciesGettingException; import timnekk.exceptions.CircularDependencyException; import java.util.*; @@ -10,7 +10,7 @@ public final class Graph { private final Set missingDependencies = new HashSet<>(); private final DependenciesFinder dependenciesFinder; - public Graph(Set items, DependenciesFinder dependenciesFinder) throws CanNotGetDependenciesException { + public Graph(Set items, DependenciesFinder dependenciesFinder) throws DependenciesGettingException { this.dependenciesFinder = dependenciesFinder; createNodes(items); @@ -29,7 +29,7 @@ private void createNodes(Set items) { } } - private void addNodesDependencies() throws CanNotGetDependenciesException { + private void addNodesDependencies() throws DependenciesGettingException { for (Node node : nodes) { Set dependentItems = dependenciesFinder.findDependencies(node.getValue());