From 94045d128ac4ea07ee09546abe0e496e48789527 Mon Sep 17 00:00:00 2001 From: Andrei Kirilenko Date: Tue, 19 Feb 2019 21:54:01 +0300 Subject: [PATCH 1/6] add cdls --- bash/README.md | 0 bash/build.gradle | 0 bash/gradle/wrapper/gradle-wrapper.jar | Bin bash/gradle/wrapper/gradle-wrapper.properties | 0 bash/gradlew | 0 bash/gradlew.bat | 0 bash/settings.gradle | 0 .../kotlin/hse/nedikov/bash/Controller.kt | 0 .../kotlin/hse/nedikov/bash/Environment.kt | 40 ++++++++++ .../src/main/kotlin/hse/nedikov/bash/Lexer.kt | 0 .../main/kotlin/hse/nedikov/bash/Parser.kt | 0 .../nedikov/bash/exceptions/ParseException.kt | 0 .../kotlin/hse/nedikov/bash/logic/Command.kt | 14 ++-- .../nedikov/bash/logic/EnvironmentCommand.kt | 8 -- .../hse/nedikov/bash/logic/commands/Cat.kt | 5 +- .../hse/nedikov/bash/logic/commands/Cd.kt | 36 +++++++++ .../hse/nedikov/bash/logic/commands/Echo.kt | 3 +- .../hse/nedikov/bash/logic/commands/Ls.kt | 52 ++++++++++++ .../bash/logic/commands/OuterCommand.kt | 3 +- .../hse/nedikov/bash/logic/commands/Pwd.kt | 5 +- .../nedikov/bash/logic/commands/WordCount.kt | 5 +- .../nedikov/bash/logic/environment/Assign.kt | 4 +- .../nedikov/bash/logic/environment/Exit.kt | 4 +- .../test/kotlin/hse/nedikov/bash/LexerTest.kt | 0 .../kotlin/hse/nedikov/bash/ParserTest.kt | 0 .../test/kotlin/hse/nedikov/bash/TestUtil.kt | 0 .../bash/logic/commands/CommandsTest.kt | 74 +++++++++++++++++- .../environment/EnvironmentCommandsTest.kt | 0 28 files changed, 223 insertions(+), 30 deletions(-) mode change 100644 => 100755 bash/README.md mode change 100644 => 100755 bash/build.gradle mode change 100644 => 100755 bash/gradle/wrapper/gradle-wrapper.jar mode change 100644 => 100755 bash/gradle/wrapper/gradle-wrapper.properties mode change 100644 => 100755 bash/gradlew mode change 100644 => 100755 bash/gradlew.bat mode change 100644 => 100755 bash/settings.gradle mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/Controller.kt mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/Environment.kt mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/Lexer.kt mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/Parser.kt mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/exceptions/ParseException.kt mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/logic/Command.kt delete mode 100644 bash/src/main/kotlin/hse/nedikov/bash/logic/EnvironmentCommand.kt mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cat.kt create mode 100644 bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Echo.kt create mode 100644 bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/logic/commands/OuterCommand.kt mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Pwd.kt mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/logic/commands/WordCount.kt mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/logic/environment/Assign.kt mode change 100644 => 100755 bash/src/main/kotlin/hse/nedikov/bash/logic/environment/Exit.kt mode change 100644 => 100755 bash/src/test/kotlin/hse/nedikov/bash/LexerTest.kt mode change 100644 => 100755 bash/src/test/kotlin/hse/nedikov/bash/ParserTest.kt mode change 100644 => 100755 bash/src/test/kotlin/hse/nedikov/bash/TestUtil.kt mode change 100644 => 100755 bash/src/test/kotlin/hse/nedikov/bash/logic/commands/CommandsTest.kt mode change 100644 => 100755 bash/src/test/kotlin/hse/nedikov/bash/logic/environment/EnvironmentCommandsTest.kt diff --git a/bash/README.md b/bash/README.md old mode 100644 new mode 100755 diff --git a/bash/build.gradle b/bash/build.gradle old mode 100644 new mode 100755 diff --git a/bash/gradle/wrapper/gradle-wrapper.jar b/bash/gradle/wrapper/gradle-wrapper.jar old mode 100644 new mode 100755 diff --git a/bash/gradle/wrapper/gradle-wrapper.properties b/bash/gradle/wrapper/gradle-wrapper.properties old mode 100644 new mode 100755 diff --git a/bash/gradlew b/bash/gradlew old mode 100644 new mode 100755 diff --git a/bash/gradlew.bat b/bash/gradlew.bat old mode 100644 new mode 100755 diff --git a/bash/settings.gradle b/bash/settings.gradle old mode 100644 new mode 100755 diff --git a/bash/src/main/kotlin/hse/nedikov/bash/Controller.kt b/bash/src/main/kotlin/hse/nedikov/bash/Controller.kt old mode 100644 new mode 100755 diff --git a/bash/src/main/kotlin/hse/nedikov/bash/Environment.kt b/bash/src/main/kotlin/hse/nedikov/bash/Environment.kt old mode 100644 new mode 100755 index 7176d9c..23f960c --- a/bash/src/main/kotlin/hse/nedikov/bash/Environment.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/Environment.kt @@ -1,6 +1,7 @@ package hse.nedikov.bash import hse.nedikov.bash.Environment.State.* +import java.io.File /** * Environment of the interpreter @@ -12,6 +13,45 @@ class Environment { private val varMap = HashMap() private var state: State = Working + private var curDir = File("./") + + /** + * Switches directory + * @param change new directory path + * @return true is change was successful false otherwise + */ + fun updateDir(change: String): Boolean { + val newDirectory = getFile(change) + val success = newDirectory.isDirectory + + if (success) { + curDir = newDirectory + } + + return success + } + + /** + * Function for full path for current path + * @param path path to convert + * @return full path + */ + fun getPath(path: String): String { + return getFile(path).canonicalPath + } + + /** + * Function for getting file for path + * @param path path to file + * @return file for path + */ + fun getFile(path: String): File { + return if (File(path).isAbsolute) { + File(path).canonicalFile + } else { + File(curDir, path).canonicalFile + } + } /** * Map of the local variables diff --git a/bash/src/main/kotlin/hse/nedikov/bash/Lexer.kt b/bash/src/main/kotlin/hse/nedikov/bash/Lexer.kt old mode 100644 new mode 100755 diff --git a/bash/src/main/kotlin/hse/nedikov/bash/Parser.kt b/bash/src/main/kotlin/hse/nedikov/bash/Parser.kt old mode 100644 new mode 100755 diff --git a/bash/src/main/kotlin/hse/nedikov/bash/exceptions/ParseException.kt b/bash/src/main/kotlin/hse/nedikov/bash/exceptions/ParseException.kt old mode 100644 new mode 100755 diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/Command.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/Command.kt old mode 100644 new mode 100755 index 25eef02..e8067b4 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/Command.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/Command.kt @@ -9,7 +9,7 @@ import java.io.* /** * Base class for all interpreter commands */ -abstract class Command { +abstract class Command(open val env: Environment) { protected abstract fun execute(input: PipedReader, output: PipedWriter) protected abstract fun execute(output: PipedWriter) @@ -46,12 +46,14 @@ abstract class Command { return Assign(name.take(name.length - 1), args, env) } return when (name) { - "echo" -> Echo(args) - "wc" -> WordCount(args) - "pwd" -> Pwd() + "echo" -> Echo(args, env) + "wc" -> WordCount(args, env) + "pwd" -> Pwd(env) "exit" -> Exit(env) - "cat" -> Cat(args) - else -> OuterCommand(name, args) + "cat" -> Cat(args, env) + "cd" -> Cd(args, env) + "ls" -> Ls(args, env) + else -> OuterCommand(name, args, env) } } } diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/EnvironmentCommand.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/EnvironmentCommand.kt deleted file mode 100644 index 69e7c33..0000000 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/EnvironmentCommand.kt +++ /dev/null @@ -1,8 +0,0 @@ -package hse.nedikov.bash.logic - -import hse.nedikov.bash.Environment - -/** - * Base class for commands which uses environment - */ -abstract class EnvironmentCommand(open val env: Environment) : Command() \ No newline at end of file diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cat.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cat.kt old mode 100644 new mode 100755 index f117f99..a6c4504 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cat.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cat.kt @@ -1,5 +1,6 @@ package hse.nedikov.bash.logic.commands +import hse.nedikov.bash.Environment import hse.nedikov.bash.logic.Command import java.io.* import java.lang.Exception @@ -7,7 +8,7 @@ import java.lang.Exception /** * cat command which prints files entries to the output stream */ -class Cat(private val arguments: ArrayList) : Command() { +class Cat(private val arguments: ArrayList, override val env: Environment) : Command(env) { /** * Prints input to the output if has no arguments and prints entries of files from arguments otherwise */ @@ -22,7 +23,7 @@ class Cat(private val arguments: ArrayList) : Command() { override fun execute(output: PipedWriter) { for (arg in arguments) { try { - FileReader(arg).forEachLine { output.write(arg) } + FileReader(env.getPath(arg)).forEachLine { output.write(arg) } } catch (e: Exception) { output.write("cat: ${e.message}") } diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt new file mode 100644 index 0000000..aa67280 --- /dev/null +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt @@ -0,0 +1,36 @@ +package hse.nedikov.bash.logic.commands + +import hse.nedikov.bash.Environment +import hse.nedikov.bash.logic.Command +import java.io.PipedReader +import java.io.PipedWriter + +/** + * Class that switches current directory + */ +class Cd(private val arguments: ArrayList, override val env: Environment) : Command(env) { + /** + * Changes the working directory + */ + override fun execute(input: PipedReader, output: PipedWriter) { + return execute(output) + } + + /** + * Changes the working directory + * switches to home of zero arguments + * switches to input dir if one argument and success + */ + override fun execute(output: PipedWriter) { + if (arguments.size > 1) { + output.write("Error: extra args in cd command") + return + } + + val path = arguments.getOrElse(0) { "./" } + + if (!env.updateDir(path)) { + output.write("File not found error") + } + } +} \ No newline at end of file diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Echo.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Echo.kt old mode 100644 new mode 100755 index fc25d94..bd356b2 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Echo.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Echo.kt @@ -1,5 +1,6 @@ package hse.nedikov.bash.logic.commands +import hse.nedikov.bash.Environment import hse.nedikov.bash.logic.Command import java.io.* import java.util.* @@ -8,7 +9,7 @@ import java.util.* /** * echo command which prints arguments to the output */ -class Echo(private val arguments: ArrayList) : Command() { +class Echo(private val arguments: ArrayList, override val env: Environment = Environment()) : Command(env) { /** * Prints arguments which are joined with spaces to the output */ diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt new file mode 100644 index 0000000..a04ed18 --- /dev/null +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt @@ -0,0 +1,52 @@ +package hse.nedikov.bash.logic.commands + +import hse.nedikov.bash.Environment +import hse.nedikov.bash.logic.Command +import java.io.PipedReader +import java.io.PipedWriter + +/** + * Class that prints all files and directories in specified path or current directory + */ +class Ls(private val arguments: ArrayList, override val env: Environment) : Command(env) { + /** + * Prints all files and directories in specified path or current directory + * @param input input stream + * @param output output stream + */ + override fun execute(input: PipedReader, output: PipedWriter) { + return execute(output) + } + + /** + * Prints all files and directories in specified path or current directory + * if arguments more than one error will occur + * @param output output stream + */ + override fun execute(output: PipedWriter) { + if (arguments.size > 1) { + output.write("Error: extra args in ls command") + return + } + + val arg = env.getFile(arguments.getOrElse(0) { "./" }) + val sep = System.lineSeparator() + + if (!(arg.isFile || arg.isDirectory)) { + output.write("Directory not found for ls") + return + } + + if (arg.isDirectory) { + arg.listFiles().sorted().forEach { + if (!it.isHidden) { + output.write(it.name + sep) + } + } + + return + } + + output.write(arg.name + sep) + } +} diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/OuterCommand.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/OuterCommand.kt old mode 100644 new mode 100755 index ec44fd5..e74f374 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/OuterCommand.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/OuterCommand.kt @@ -1,5 +1,6 @@ package hse.nedikov.bash.logic.commands +import hse.nedikov.bash.Environment import hse.nedikov.bash.logic.Command import java.io.* import java.util.concurrent.Executors @@ -12,7 +13,7 @@ import java.util.concurrent.TimeUnit * Class for calling commands in outer interpreter * @param name name of the command */ -class OuterCommand(private val name: String, private val arguments: ArrayList) : Command() { +class OuterCommand(private val name: String, private val arguments: ArrayList, override val env: Environment) : Command(env) { /** * Calls the command in outer interpreter and print theirs output or error to the output * in case when the command is executed in less than 10 seconds diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Pwd.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Pwd.kt old mode 100644 new mode 100755 index 3084c17..aac5d02 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Pwd.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Pwd.kt @@ -1,12 +1,13 @@ package hse.nedikov.bash.logic.commands +import hse.nedikov.bash.Environment import hse.nedikov.bash.logic.Command import java.io.* /** * pwd command which prints current working directory */ -class Pwd : Command() { +class Pwd(override val env: Environment) : Command(env) { /** * Prints current working directory to the output */ @@ -19,7 +20,7 @@ class Pwd : Command() { * Prints current working directory to the output */ override fun execute(output: PipedWriter) { - output.write(System.getProperty("user.dir") + "\n") + output.write(env.getPath("./") + "\n") } } \ No newline at end of file diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/WordCount.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/WordCount.kt old mode 100644 new mode 100755 index a51069f..796e55d --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/WordCount.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/WordCount.kt @@ -1,5 +1,6 @@ package hse.nedikov.bash.logic.commands +import hse.nedikov.bash.Environment import hse.nedikov.bash.logic.Command import java.io.* import java.lang.Exception @@ -7,7 +8,7 @@ import java.lang.Exception /** * wc command which calculates count of lines, words and bytes in files or input */ -class WordCount(private val arguments: ArrayList) : Command() { +class WordCount(private val arguments: ArrayList, override val env: Environment) : Command(env) { /** * Calculates count of lines, words and bytes in input if arguments is empty and in files otherwise */ @@ -27,7 +28,7 @@ class WordCount(private val arguments: ArrayList) : Command() { val result = WCResult() for (arg in arguments) { try { - val r = calcInput(FileReader(arg)) + val r = calcInput(FileReader(env.getPath(arg))) output.write("${r.lines} ${r.words} ${r.bytes} $arg\n") } catch (e: Exception) { output.write("wc: ${e.message}\n") diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/environment/Assign.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/environment/Assign.kt old mode 100644 new mode 100755 index ae66e21..2927188 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/environment/Assign.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/environment/Assign.kt @@ -1,7 +1,7 @@ package hse.nedikov.bash.logic.environment import hse.nedikov.bash.Environment -import hse.nedikov.bash.logic.EnvironmentCommand +import hse.nedikov.bash.logic.Command import java.io.PipedReader import java.io.PipedWriter import java.lang.Exception @@ -11,7 +11,7 @@ import java.lang.Exception * @param name name of variable */ class Assign(private val name:String, private val arguments: ArrayList, override val env: Environment) - : EnvironmentCommand(env) { + : Command(env) { /** * Do nothing in this case diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/environment/Exit.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/environment/Exit.kt old mode 100644 new mode 100755 index 1c00c5a..f89d32c --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/environment/Exit.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/environment/Exit.kt @@ -1,13 +1,13 @@ package hse.nedikov.bash.logic.environment import hse.nedikov.bash.Environment -import hse.nedikov.bash.logic.EnvironmentCommand +import hse.nedikov.bash.logic.Command import java.io.* /** * Class for command which closes the interpreter */ -class Exit(override val env: Environment) : EnvironmentCommand(env) { +class Exit(override val env: Environment) : Command(env) { /** * Stops the interpreter */ diff --git a/bash/src/test/kotlin/hse/nedikov/bash/LexerTest.kt b/bash/src/test/kotlin/hse/nedikov/bash/LexerTest.kt old mode 100644 new mode 100755 diff --git a/bash/src/test/kotlin/hse/nedikov/bash/ParserTest.kt b/bash/src/test/kotlin/hse/nedikov/bash/ParserTest.kt old mode 100644 new mode 100755 diff --git a/bash/src/test/kotlin/hse/nedikov/bash/TestUtil.kt b/bash/src/test/kotlin/hse/nedikov/bash/TestUtil.kt old mode 100644 new mode 100755 diff --git a/bash/src/test/kotlin/hse/nedikov/bash/logic/commands/CommandsTest.kt b/bash/src/test/kotlin/hse/nedikov/bash/logic/commands/CommandsTest.kt old mode 100644 new mode 100755 index 5b1c74a..159394b --- a/bash/src/test/kotlin/hse/nedikov/bash/logic/commands/CommandsTest.kt +++ b/bash/src/test/kotlin/hse/nedikov/bash/logic/commands/CommandsTest.kt @@ -1,12 +1,17 @@ package hse.nedikov.bash.logic.commands +import hse.nedikov.bash.Environment import org.junit.Test import java.io.PipedReader import java.io.PipedWriter import java.util.* import hse.nedikov.bash.list +import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Rule +import org.junit.rules.TemporaryFolder class CommandsTest { @Test @@ -35,25 +40,25 @@ class CommandsTest { @Test fun catInputStream() { - val reader = Cat(list()).execute(readerFromString("kekes leles")) + val reader = Cat(list(), Environment()).execute(readerFromString("kekes leles")) assertEquals("kekes leles", stringFromReader(reader)) } @Test fun pwdSimple() { - val reader = Pwd().execute() + val reader = Pwd(Environment()).execute() assertTrue(stringFromReader(reader).isNotEmpty()) } @Test fun pwdSimpleWithInputStream() { - val reader = Pwd().execute(readerFromString("kekes leles")) + val reader = Pwd(Environment()).execute(readerFromString("kekes leles")) assertTrue(stringFromReader(reader).isNotEmpty()) } @Test fun wordCountSimple() { - val reader = WordCount(list()).execute(readerFromString("lol kek cheburek")) + val reader = WordCount(list(), Environment()).execute(readerFromString("lol kek cheburek")) assertEquals("1 3 16", stringFromReader(reader)) } @@ -70,4 +75,65 @@ class CommandsTest { return joiner.toString() } } + + @Rule + @JvmField + val testDir = TemporaryFolder() + + @Before + fun setup() { + testDir.newFolder("dir") + testDir.newFile("dir/file") + testDir.newFile("file") + } + + @After + fun clear() { + testDir.delete() + } + + /** + * Tests ls from current dir + */ + @Test + fun lsTest() { + val env = Environment() + env.updateDir(testDir.root.canonicalPath) + val reader = Ls(list(), env).execute() + assertEquals("dir\nfile", stringFromReader(reader)) + } + + /** + * Test ls with dir in argument + */ + @Test + fun lsTestSubdir() { + val env = Environment() + env.updateDir(testDir.root.canonicalPath) + val reader = Ls(list("dir"), env).execute() + assertEquals("file", stringFromReader(reader)) + } + + /** + * Test cd command forward step + */ + @Test + fun cdTestForward() { + val env = Environment() + env.updateDir(testDir.root.canonicalPath) + Cd(list("dir"), env).execute() + assertEquals("file", stringFromReader(Ls(list(), env).execute())) + } + + /** + * Test cd command backward step + */ + @Test + fun cdTestBackward() { + val env = Environment() + env.updateDir(testDir.root.canonicalPath) + Cd(list("dir"), env).execute() + Cd(list(".."), env).execute() + assertEquals("dir\nfile", stringFromReader(Ls(list(), env).execute())) + } } \ No newline at end of file diff --git a/bash/src/test/kotlin/hse/nedikov/bash/logic/environment/EnvironmentCommandsTest.kt b/bash/src/test/kotlin/hse/nedikov/bash/logic/environment/EnvironmentCommandsTest.kt old mode 100644 new mode 100755 From 7819d51b5bc13520f36dbd472564d17867363cea Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 26 Mar 2019 21:07:08 +0300 Subject: [PATCH 2/6] Add exceptions to cd and ls --- bash/src/main/kotlin/hse/nedikov/bash/Environment.kt | 6 +----- .../nedikov/bash/exceptions/DirectoryUpdateException.kt | 8 ++++++++ .../bash/exceptions/IncorrectArgumentsException.kt | 8 ++++++++ .../main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt | 7 ++++--- .../main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt | 9 +++++---- 5 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 bash/src/main/kotlin/hse/nedikov/bash/exceptions/DirectoryUpdateException.kt create mode 100644 bash/src/main/kotlin/hse/nedikov/bash/exceptions/IncorrectArgumentsException.kt diff --git a/bash/src/main/kotlin/hse/nedikov/bash/Environment.kt b/bash/src/main/kotlin/hse/nedikov/bash/Environment.kt index 23f960c..4b0db24 100755 --- a/bash/src/main/kotlin/hse/nedikov/bash/Environment.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/Environment.kt @@ -46,11 +46,7 @@ class Environment { * @return file for path */ fun getFile(path: String): File { - return if (File(path).isAbsolute) { - File(path).canonicalFile - } else { - File(curDir, path).canonicalFile - } + return curDir.resolve(path) } /** diff --git a/bash/src/main/kotlin/hse/nedikov/bash/exceptions/DirectoryUpdateException.kt b/bash/src/main/kotlin/hse/nedikov/bash/exceptions/DirectoryUpdateException.kt new file mode 100644 index 0000000..7c27b8f --- /dev/null +++ b/bash/src/main/kotlin/hse/nedikov/bash/exceptions/DirectoryUpdateException.kt @@ -0,0 +1,8 @@ +package hse.nedikov.bash.exceptions + +import java.lang.Exception + +/** + * Exception for incorrect arguments + */ +internal class DirectoryUpdateException(message: String) : Exception("Error occurred while updating directory: $message") \ No newline at end of file diff --git a/bash/src/main/kotlin/hse/nedikov/bash/exceptions/IncorrectArgumentsException.kt b/bash/src/main/kotlin/hse/nedikov/bash/exceptions/IncorrectArgumentsException.kt new file mode 100644 index 0000000..c35827a --- /dev/null +++ b/bash/src/main/kotlin/hse/nedikov/bash/exceptions/IncorrectArgumentsException.kt @@ -0,0 +1,8 @@ +package hse.nedikov.bash.exceptions + +import java.lang.Exception + +/** + * Exception for incorrect arguments + */ +internal class IncorrectArgumentsException(message: String) : Exception("Incorrect arguments exception: $message") \ No newline at end of file diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt index aa67280..982cbcd 100644 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt @@ -1,6 +1,8 @@ package hse.nedikov.bash.logic.commands import hse.nedikov.bash.Environment +import hse.nedikov.bash.exceptions.DirectoryUpdateException +import hse.nedikov.bash.exceptions.IncorrectArgumentsException import hse.nedikov.bash.logic.Command import java.io.PipedReader import java.io.PipedWriter @@ -23,14 +25,13 @@ class Cd(private val arguments: ArrayList, override val env: Environment */ override fun execute(output: PipedWriter) { if (arguments.size > 1) { - output.write("Error: extra args in cd command") - return + throw IncorrectArgumentsException("extra arguments in cd command") } val path = arguments.getOrElse(0) { "./" } if (!env.updateDir(path)) { - output.write("File not found error") + throw DirectoryUpdateException("can't update current directory: specified directory doesn't exist or not a directory") } } } \ No newline at end of file diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt index a04ed18..5064cd8 100644 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt @@ -1,7 +1,10 @@ package hse.nedikov.bash.logic.commands import hse.nedikov.bash.Environment +import hse.nedikov.bash.exceptions.DirectoryUpdateException +import hse.nedikov.bash.exceptions.IncorrectArgumentsException import hse.nedikov.bash.logic.Command +import java.io.FileNotFoundException import java.io.PipedReader import java.io.PipedWriter @@ -25,16 +28,14 @@ class Ls(private val arguments: ArrayList, override val env: Environment */ override fun execute(output: PipedWriter) { if (arguments.size > 1) { - output.write("Error: extra args in ls command") - return + throw IncorrectArgumentsException("extra arguments in ls command") } val arg = env.getFile(arguments.getOrElse(0) { "./" }) val sep = System.lineSeparator() if (!(arg.isFile || arg.isDirectory)) { - output.write("Directory not found for ls") - return + throw FileNotFoundException("Not a file or directory") } if (arg.isDirectory) { From 95304993e5404e0ca354de73a2c619efadd0d4ac Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 26 Mar 2019 21:16:39 +0300 Subject: [PATCH 3/6] Add cd support with no arguments --- .../hse/nedikov/bash/exceptions/DirectoryUpdateException.kt | 2 +- bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bash/src/main/kotlin/hse/nedikov/bash/exceptions/DirectoryUpdateException.kt b/bash/src/main/kotlin/hse/nedikov/bash/exceptions/DirectoryUpdateException.kt index 7c27b8f..b181f26 100644 --- a/bash/src/main/kotlin/hse/nedikov/bash/exceptions/DirectoryUpdateException.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/exceptions/DirectoryUpdateException.kt @@ -3,6 +3,6 @@ package hse.nedikov.bash.exceptions import java.lang.Exception /** - * Exception for incorrect arguments + * Exception for directory updates errors */ internal class DirectoryUpdateException(message: String) : Exception("Error occurred while updating directory: $message") \ No newline at end of file diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt index 982cbcd..76049e6 100644 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt @@ -28,7 +28,7 @@ class Cd(private val arguments: ArrayList, override val env: Environment throw IncorrectArgumentsException("extra arguments in cd command") } - val path = arguments.getOrElse(0) { "./" } + val path = arguments.getOrElse(0) { System.getProperty("user.home") } if (!env.updateDir(path)) { throw DirectoryUpdateException("can't update current directory: specified directory doesn't exist or not a directory") From 5b5bef3c11725426931c72257be7a600d98f72dc Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 26 Mar 2019 21:38:39 +0300 Subject: [PATCH 4/6] fix git status issue --- .../main/kotlin/hse/nedikov/bash/logic/commands/OuterCommand.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/OuterCommand.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/OuterCommand.kt index e74f374..9dc5963 100755 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/OuterCommand.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/OuterCommand.kt @@ -49,7 +49,7 @@ class OuterCommand(private val name: String, private val arguments: ArrayList arguments.forEach { joiner.add(it) } }.toString() - return Runtime.getRuntime().exec("$environmentStart $command") + return Runtime.getRuntime().exec("$environmentStart $command", null, env.getFile("./")) } private class StreamGobbler(private val inputStream: InputStream, private val consumer: (String) -> Unit) : Runnable { From 66ba27eb6b33b462ded1d29c6719196dece9601b Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 26 Mar 2019 22:01:50 +0300 Subject: [PATCH 5/6] paths instead of strings --- .../kotlin/hse/nedikov/bash/Environment.kt | 35 +++++++++++++------ .../hse/nedikov/bash/logic/commands/Cat.kt | 2 +- .../hse/nedikov/bash/logic/commands/Cd.kt | 4 +-- .../hse/nedikov/bash/logic/commands/Ls.kt | 1 - .../hse/nedikov/bash/logic/commands/Pwd.kt | 2 +- .../nedikov/bash/logic/commands/WordCount.kt | 2 +- 6 files changed, 28 insertions(+), 18 deletions(-) diff --git a/bash/src/main/kotlin/hse/nedikov/bash/Environment.kt b/bash/src/main/kotlin/hse/nedikov/bash/Environment.kt index 4b0db24..4ce7846 100755 --- a/bash/src/main/kotlin/hse/nedikov/bash/Environment.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/Environment.kt @@ -1,7 +1,13 @@ package hse.nedikov.bash import hse.nedikov.bash.Environment.State.* +import hse.nedikov.bash.exceptions.DirectoryUpdateException import java.io.File +import java.nio.file.Path +import java.nio.file.Paths +import java.nio.file.Files + + /** * Environment of the interpreter @@ -13,22 +19,20 @@ class Environment { private val varMap = HashMap() private var state: State = Working - private var curDir = File("./") + private var curPath = Paths.get(".").toAbsolutePath().normalize() /** * Switches directory * @param change new directory path * @return true is change was successful false otherwise */ - fun updateDir(change: String): Boolean { - val newDirectory = getFile(change) - val success = newDirectory.isDirectory - - if (success) { - curDir = newDirectory + fun updateDir(change: String) { + val newDirectory = curPath.resolve(change) + if (!Files.exists(newDirectory) || !Files.isDirectory(newDirectory)) { + throw DirectoryUpdateException("can't update current directory: specified directory doesn't exist or not a directory") } - return success + curPath = newDirectory.toAbsolutePath().normalize() } /** @@ -36,8 +40,8 @@ class Environment { * @param path path to convert * @return full path */ - fun getPath(path: String): String { - return getFile(path).canonicalPath + fun getPathString(path: String): String { + return getPath(path).toAbsolutePath().normalize().toString() } /** @@ -45,8 +49,17 @@ class Environment { * @param path path to file * @return file for path */ + private fun getPath(path: String): Path { + return curPath.resolve(path) + } + + /** + * Function for getting Path for path string + * @param path path string + * @return Path for path string + */ fun getFile(path: String): File { - return curDir.resolve(path) + return getPath(path).toFile() } /** diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cat.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cat.kt index a6c4504..f526b24 100755 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cat.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cat.kt @@ -23,7 +23,7 @@ class Cat(private val arguments: ArrayList, override val env: Environmen override fun execute(output: PipedWriter) { for (arg in arguments) { try { - FileReader(env.getPath(arg)).forEachLine { output.write(arg) } + FileReader(env.getPathString(arg)).forEachLine { output.write(arg) } } catch (e: Exception) { output.write("cat: ${e.message}") } diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt index 76049e6..15e6926 100644 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Cd.kt @@ -30,8 +30,6 @@ class Cd(private val arguments: ArrayList, override val env: Environment val path = arguments.getOrElse(0) { System.getProperty("user.home") } - if (!env.updateDir(path)) { - throw DirectoryUpdateException("can't update current directory: specified directory doesn't exist or not a directory") - } + env.updateDir(path) } } \ No newline at end of file diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt index 5064cd8..ebda1f1 100644 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Ls.kt @@ -1,7 +1,6 @@ package hse.nedikov.bash.logic.commands import hse.nedikov.bash.Environment -import hse.nedikov.bash.exceptions.DirectoryUpdateException import hse.nedikov.bash.exceptions.IncorrectArgumentsException import hse.nedikov.bash.logic.Command import java.io.FileNotFoundException diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Pwd.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Pwd.kt index aac5d02..fa0d31e 100755 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Pwd.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/Pwd.kt @@ -20,7 +20,7 @@ class Pwd(override val env: Environment) : Command(env) { * Prints current working directory to the output */ override fun execute(output: PipedWriter) { - output.write(env.getPath("./") + "\n") + output.write(env.getPathString("./") + "\n") } } \ No newline at end of file diff --git a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/WordCount.kt b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/WordCount.kt index 796e55d..01e709e 100755 --- a/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/WordCount.kt +++ b/bash/src/main/kotlin/hse/nedikov/bash/logic/commands/WordCount.kt @@ -28,7 +28,7 @@ class WordCount(private val arguments: ArrayList, override val env: Envi val result = WCResult() for (arg in arguments) { try { - val r = calcInput(FileReader(env.getPath(arg))) + val r = calcInput(FileReader(env.getPathString(arg))) output.write("${r.lines} ${r.words} ${r.bytes} $arg\n") } catch (e: Exception) { output.write("wc: ${e.message}\n") From bec7ca412efe43c2006bd0ae4a0015e30c6fc7bd Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 27 Mar 2019 20:01:27 +0300 Subject: [PATCH 6/6] add junit --- bash/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/bash/build.gradle b/bash/build.gradle index f232c95..7f073f2 100755 --- a/bash/build.gradle +++ b/bash/build.gradle @@ -10,6 +10,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8" + testCompile group: 'junit', name: 'junit', version: '4.12' } compileKotlin {