diff --git a/.gitignore b/.gitignore index 36a62c6..217ce48 100644 --- a/.gitignore +++ b/.gitignore @@ -168,7 +168,6 @@ Generated_Code #added for RIA/Silverlight projects # Backup & report files from converting an old project file to a newer # Visual Studio version. Backup files are not needed, because we have git ;-) _UpgradeReport_Files/ -Backup*/ UpgradeLog*.XML diff --git a/scripts/CommandBuilders/CreateBackupCommandBuilder.py b/scripts/CommandBuilders/CreateBackupCommandBuilder.py new file mode 100644 index 0000000..f1f7f17 --- /dev/null +++ b/scripts/CommandBuilders/CreateBackupCommandBuilder.py @@ -0,0 +1,24 @@ +from commands.CreateBackupCommand import CreateBackupCommand +from parser.BackupParser.CreateBackupParser import CreateBackupParser + + +class CreateBackupCommandBuilder: + def __init__(self, pathProvider): + assert pathProvider is not None + + self.__pathProvider = pathProvider + + def isCreateBackup(self, line): + assert line is not None + + parser = CreateBackupParser() + return parser.isValidLine(line) + + def getCommandFor(self, line): + assert line is not None + + parser = CreateBackupParser() + backupArguments = parser.parseLine(line) + + command = CreateBackupCommand(self.__pathProvider, backupArguments) + return command diff --git a/scripts/CommandBuilders/DeleteBackupCommandBuilder.py b/scripts/CommandBuilders/DeleteBackupCommandBuilder.py new file mode 100644 index 0000000..0e9eb76 --- /dev/null +++ b/scripts/CommandBuilders/DeleteBackupCommandBuilder.py @@ -0,0 +1,25 @@ +from commands.DeleteBackupCommand import DeleteBackupCommand +from parser.BackupParser.DeleteBackupParser import DeleteBackupParser + + +class DeleteBackupCommandBuilder: + def __init__(self, pathProvider): + assert pathProvider is not None + self.__pathProvider = pathProvider + + def isDeleteBackup(self, line): + assert line is not None + + parser = DeleteBackupParser() + isValid = parser.isValidLine(line) + + return isValid + + def getCommandFor(self, line): + assert line is not None + + parser = DeleteBackupParser() + parser.parseLine(line) + + command = DeleteBackupCommand(self.__pathProvider) + return command diff --git a/scripts/CommandBuilders/RestoreBackupCommandBuilder.py b/scripts/CommandBuilders/RestoreBackupCommandBuilder.py new file mode 100644 index 0000000..4b7c9a3 --- /dev/null +++ b/scripts/CommandBuilders/RestoreBackupCommandBuilder.py @@ -0,0 +1,25 @@ +from commands.RestoreBackupCommand import RestoreBackupCommand +from parser.BackupParser.RestoreBackupParser import RestoreBackupParser + + +class RestoreBackupCommandBuilder: + def __init__(self, pathProvider): + assert pathProvider is not None + self.__pathProvider = pathProvider + + def isRestoreBackup(self, line): + assert line is not None + + parser = RestoreBackupParser() + isValid = parser.isValidLine(line) + + return isValid + + def getCommandFor(self, line): + assert line is not None + + parser = RestoreBackupParser() + parser.parseLine(line) + + command = RestoreBackupCommand(self.__pathProvider) + return command diff --git a/scripts/ManualTests/create_backup_test.py b/scripts/ManualTests/create_backup_test.py new file mode 100644 index 0000000..8362787 --- /dev/null +++ b/scripts/ManualTests/create_backup_test.py @@ -0,0 +1,12 @@ +from CommandBuilders.CreateBackupCommandBuilder import CreateBackupCommandBuilder +from ManualTests.path_provider import PathProvider + +line = "create backup for 'BuildSample'" + +baseDir = '../' +path_provider = PathProvider(baseDir) + +cmdBuilder = CreateBackupCommandBuilder(path_provider) +command = cmdBuilder.getCommandFor(line) + +command.execute() \ No newline at end of file diff --git a/scripts/ManualTests/delete_backup_test.py b/scripts/ManualTests/delete_backup_test.py new file mode 100644 index 0000000..7ac8044 --- /dev/null +++ b/scripts/ManualTests/delete_backup_test.py @@ -0,0 +1,12 @@ +from CommandBuilders.DeleteBackupCommandBuilder import DeleteBackupCommandBuilder +from ManualTests.path_provider import PathProvider + +line = "delete backup" + +baseDir = '../' +path_provider = PathProvider(baseDir) + +cmdBuilder = DeleteBackupCommandBuilder(path_provider) +command = cmdBuilder.getCommandFor(line) + +command.execute() \ No newline at end of file diff --git a/scripts/ManualTests/restore_backup_test.py b/scripts/ManualTests/restore_backup_test.py new file mode 100644 index 0000000..8bbd378 --- /dev/null +++ b/scripts/ManualTests/restore_backup_test.py @@ -0,0 +1,15 @@ +from CommandBuilders.RestoreBackupCommandBuilder import RestoreBackupCommandBuilder +from ManualTests.path_provider import PathProvider + +line = "restore from backup" + +baseDir = '../' +path_provider = PathProvider(baseDir) + +builder = RestoreBackupCommandBuilder(path_provider) +command = builder.getCommandFor(line) + +command.execute() + + + diff --git a/scripts/UnitTests/BackupParser/__init__.py b/scripts/UnitTests/BackupParser/__init__.py new file mode 100644 index 0000000..cc31abc --- /dev/null +++ b/scripts/UnitTests/BackupParser/__init__.py @@ -0,0 +1 @@ +__author__ = 'rzaitov' diff --git a/scripts/UnitTests/BackupParser/test_createBackupParser.py b/scripts/UnitTests/BackupParser/test_createBackupParser.py new file mode 100644 index 0000000..8b5b199 --- /dev/null +++ b/scripts/UnitTests/BackupParser/test_createBackupParser.py @@ -0,0 +1,13 @@ +import unittest +from parser.BackupParser.CreateBackupParser import CreateBackupParser + + +class TestCreateBackupParser(unittest.TestCase): + def setUp(self): + self.__parser = CreateBackupParser() + + def test_validInput(self): + line = "create backup for 'SomeFolder'" + createBackupArgs = self.__parser.parseLine(line) + + self.assertEqual('SomeFolder', createBackupArgs.folderName) \ No newline at end of file diff --git a/scripts/UnitTests/BackupParser/test_deleteBackupParser.py b/scripts/UnitTests/BackupParser/test_deleteBackupParser.py new file mode 100644 index 0000000..fbe91a7 --- /dev/null +++ b/scripts/UnitTests/BackupParser/test_deleteBackupParser.py @@ -0,0 +1,23 @@ +import unittest +from parser.BackupParser.DeleteBackupParser import DeleteBackupParser + + +class TestDeleteBackupParser(unittest.TestCase): + def setUp(self): + self.__parser = DeleteBackupParser() + + def test_isValid(self): + line = 'delete backup' + isValid = self.__parser.isValidLine(line) + + self.assertEqual(True, isValid) + + def test_isNotValid(self): + line = 'bla backup' + isValid = self.__parser.isValidLine(line) + + self.assertEqual(False, isValid) + + def test_validInput(self): + line = 'delete backup' + self.__parser.parseLine(line) \ No newline at end of file diff --git a/scripts/UnitTests/BackupParser/test_restoreBackupParser.py b/scripts/UnitTests/BackupParser/test_restoreBackupParser.py new file mode 100644 index 0000000..2168d78 --- /dev/null +++ b/scripts/UnitTests/BackupParser/test_restoreBackupParser.py @@ -0,0 +1,11 @@ +import unittest +from parser.BackupParser.RestoreBackupParser import RestoreBackupParser + + +class TestRestoreBackupParser(unittest.TestCase): + def setUp(self): + self.__parser = RestoreBackupParser() + + def test_ValidInput(self): + line = 'restore from backup' + self.__parser.parseLine(line) \ No newline at end of file diff --git a/scripts/commands/CreateBackupCommand.py b/scripts/commands/CreateBackupCommand.py new file mode 100644 index 0000000..59d5ab9 --- /dev/null +++ b/scripts/commands/CreateBackupCommand.py @@ -0,0 +1,16 @@ +import shutil + +class CreateBackupCommand: + def __init__(self, pathProvider, createBackupArguments): + assert pathProvider is not None + assert createBackupArguments is not None + + self.__pathProvider = pathProvider + self.__createBackupArguments = createBackupArguments + + def execute(self): + src = self.__pathProvider.resolveAbsPath(self.__createBackupArguments.getSourceFolderName()) + dst = self.__pathProvider.resolveAbsPath(self.__createBackupArguments.getBackupFolderName()) + + shutil.rmtree(dst, ignore_errors=True) + shutil.copytree(src, dst, symlinks=False) diff --git a/scripts/commands/DeleteBackupCommand.py b/scripts/commands/DeleteBackupCommand.py new file mode 100644 index 0000000..6eb9735 --- /dev/null +++ b/scripts/commands/DeleteBackupCommand.py @@ -0,0 +1,15 @@ +import os +import shutil + +class DeleteBackupCommand: + def __init__(self, pathProvider): + assert pathProvider is not None + + self.__pathProvider = pathProvider + + def execute(self): + baseDir = self.__pathProvider.resolveAbsPath('.') + + dirs = [self.__pathProvider.resolveAbsPath(name) for name in os.listdir(baseDir) if os.path.isdir(os.path.join(baseDir, name)) & name.startswith('backup.')] + for dir in dirs: + shutil.rmtree(dir) \ No newline at end of file diff --git a/scripts/commands/RestoreBackupCommand.py b/scripts/commands/RestoreBackupCommand.py new file mode 100644 index 0000000..edf56de --- /dev/null +++ b/scripts/commands/RestoreBackupCommand.py @@ -0,0 +1,22 @@ +import os +import shutil + + +class RestoreBackupCommand: + def __init__(self, pathProvider): + assert pathProvider is not None + + self.__pathProvider = pathProvider + + def execute(self): + baseDir = self.__pathProvider.resolveAbsPath('.') + + dirPairs = [(name, "backup.{0}".format(name)) for name in os.listdir(baseDir) if os.path.isdir(self.__pathProvider.resolveAbsPath(name)) and not name.startswith('backup.')] + + for pair in dirPairs: + absPair = (self.__pathProvider.resolveAbsPath(pair[0]), self.__pathProvider.resolveAbsPath(pair[1])) + if not os.path.exists(absPair[1]): + continue + + shutil.rmtree(absPair[0]) # delete src + shutil.copytree(absPair[1], absPair[0]) # restore from backup diff --git a/scripts/parser/BackupParser/CreateBackupArguments.py b/scripts/parser/BackupParser/CreateBackupArguments.py new file mode 100644 index 0000000..fbeea2b --- /dev/null +++ b/scripts/parser/BackupParser/CreateBackupArguments.py @@ -0,0 +1,11 @@ +class CreateBackupArguments: + def __init__(self): + self.folderName = None + + def getSourceFolderName(self): + return self.folderName + + def getBackupFolderName(self): + return "backup.{0}".format(self.folderName) + + diff --git a/scripts/parser/BackupParser/CreateBackupParser.py b/scripts/parser/BackupParser/CreateBackupParser.py new file mode 100644 index 0000000..2e897f6 --- /dev/null +++ b/scripts/parser/BackupParser/CreateBackupParser.py @@ -0,0 +1,29 @@ +from parser.BackupParser.CreateBackupArguments import CreateBackupArguments +from parser.LineParser import LineParser +import re + +class CreateBackupParser(LineParser): + def __init__(self): + self.__createBackupArguments = CreateBackupArguments() + + def parseLine(self, line): + assert line is not None + + folderNameRegexp = r"'(?P[^']+)'$" + + regexpSource = self.startsWithKeywordToken('create backup for') + folderNameRegexp + regexp = re.compile(regexpSource, re.UNICODE) + + match = regexp.match(line) + self._guardMatch(match, line, regexpSource) + + folderName = match.group('folder') + self.__createBackupArguments.folderName = folderName + + return self.__createBackupArguments + + def isValidLine(self, line): + assert line is not None + + isValid = line.startswith('create backup') + return isValid diff --git a/scripts/parser/BackupParser/DeleteBackupParser.py b/scripts/parser/BackupParser/DeleteBackupParser.py new file mode 100644 index 0000000..cf92e91 --- /dev/null +++ b/scripts/parser/BackupParser/DeleteBackupParser.py @@ -0,0 +1,18 @@ +from parser.LineParser import LineParser +import re + +class DeleteBackupParser(LineParser): + def parseLine(self, line): + assert line is not None + + regexpSource = r'delete backup\s*' + regexp = re.compile(regexpSource, re.UNICODE) + + match = regexp.match(line) + self._guardMatch(match, line, regexpSource) + + def isValidLine(self, line): + assert line is not None + + isValid = line.startswith('delete backup') + return isValid diff --git a/scripts/parser/BackupParser/RestoreBackupParser.py b/scripts/parser/BackupParser/RestoreBackupParser.py new file mode 100644 index 0000000..f8bafb5 --- /dev/null +++ b/scripts/parser/BackupParser/RestoreBackupParser.py @@ -0,0 +1,19 @@ +from parser.LineParser import LineParser +import re + + +class RestoreBackupParser(LineParser): + def parseLine(self, line): + assert line is not None + + regexpSource = r'restore from backup\s*' + regexp = re.compile(regexpSource, re.UNICODE) + + match = regexp.match(line) + self._guardMatch(match, line, regexpSource) + + def isValidLine(self, line): + assert line is not None + + isValid = line.startswith('restore from backup') + diff --git a/scripts/parser/BackupParser/__init__.py b/scripts/parser/BackupParser/__init__.py new file mode 100644 index 0000000..cc31abc --- /dev/null +++ b/scripts/parser/BackupParser/__init__.py @@ -0,0 +1 @@ +__author__ = 'rzaitov' diff --git a/scripts/parser/CopyParser/CopyLineParser.py b/scripts/parser/CopyParser/CopyLineParser.py index 6e9c81e..6166b2f 100644 --- a/scripts/parser/CopyParser/CopyLineParser.py +++ b/scripts/parser/CopyParser/CopyLineParser.py @@ -24,14 +24,6 @@ class CopyLineParser(LineParser): self.__copyArguments.setArguments(src, dst) return self.__copyArguments - def keywordToken(self, keyword): - assert keyword is not None - return r'\s+' + keyword + r'\s+' - - def startsWithKeywordToken(self, keyword): - assert keyword is not None - return r'^' + keyword + r'\s+' - def isValidLine(self, line): assert line is not None diff --git a/scripts/parser/LineParser.py b/scripts/parser/LineParser.py index 3a077bc..014c94c 100644 --- a/scripts/parser/LineParser.py +++ b/scripts/parser/LineParser.py @@ -7,9 +7,17 @@ class LineParser: assert line is not None return False + def keywordToken(self, keyword): + assert keyword is not None + return r'\s+' + keyword + r'\s+' + + def startsWithKeywordToken(self, keyword): + assert keyword is not None + return r'^' + keyword + r'\s+' + def _guardMatch(self, match_object, source, regexpSource = None): if match_object is None: - msg = 'Recognition exception: {0} for {1}'.format(source, regexpSource) + msg = 'Recognition exception: "{0}" for "{1}"'.format(source, regexpSource) raise Exception(msg) diff --git a/scripts/run_manual_tests.py b/scripts/run_manual_tests.py index dab7faf..5eb4d29 100644 --- a/scripts/run_manual_tests.py +++ b/scripts/run_manual_tests.py @@ -1,3 +1,7 @@ #import ManualTests.csproj_test #import ManualTests.info_plist_test -import ManualTests.copy_test \ No newline at end of file +#import ManualTests.copy_test +#import ManualTests.create_backup_test +#import ManualTests.delete_backup_test + +import ManualTests.restore_backup_test \ No newline at end of file