Merge branch 'BS-32'
This commit is contained in:
commit
213e47c8a3
|
|
@ -1,5 +1,5 @@
|
|||
restore from backup # восстанавливаем из бэкапа (исходники от сборки предыдущей конфигурации могут быть модифицированными)
|
||||
create backup for 'BuildSample'
|
||||
create backup
|
||||
|
||||
inside 'BuildSample/BuildSample.sln' remove NotCompileApp project
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from commands.CreateBackupCommand import CreateBackupCommand
|
||||
from commands.BaseBackupCommand.CreateBackupCommand import CreateBackupCommand
|
||||
from parsers.ParserBackup.CreateBackupParser import CreateBackupParser
|
||||
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ class CreateBackupCommandBuilder:
|
|||
assert line is not None
|
||||
|
||||
parser = CreateBackupParser()
|
||||
backupArguments = parser.parseLine(line)
|
||||
parser.parseLine(line)
|
||||
|
||||
command = CreateBackupCommand(backupArguments)
|
||||
command = CreateBackupCommand()
|
||||
return command
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from commands.DeleteBackupCommand import DeleteBackupCommand
|
||||
from commands.BaseBackupCommand.DeleteBackupCommand import DeleteBackupCommand
|
||||
from parsers.ParserBackup.DeleteBackupParser import DeleteBackupParser
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from commands.RestoreBackupCommand import RestoreBackupCommand
|
||||
from commands.BaseBackupCommand.RestoreBackupCommand import RestoreBackupCommand
|
||||
from parsers.ParserBackup.RestoreBackupParser import RestoreBackupParser
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,6 @@ class SettingsResolver:
|
|||
|
||||
for node in resolvedDependencies:
|
||||
unresolvedSettingValue = self.settings[node.name]
|
||||
resolvedSettingValue = macroResolver.processText(unresolvedSettingValue)
|
||||
resolvedSettingValue = macroResolver.processText(unresolvedSettingValue, None)
|
||||
|
||||
self.settings[node.name] = resolvedSettingValue
|
||||
|
|
@ -2,7 +2,7 @@ class CommentRemover:
|
|||
def __init__(self):
|
||||
pass
|
||||
|
||||
def processText(self, line):
|
||||
def processText(self, line, conveyorProcessor):
|
||||
assert line is not None
|
||||
|
||||
newLine = line
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ class MacroResolver:
|
|||
self.macroProcessor = macroProcessor
|
||||
self.valueProvider = valueProvider
|
||||
|
||||
def processText(self, line):
|
||||
def processText(self, line, conveyorProcessor):
|
||||
assert line is not None
|
||||
|
||||
symbols = self.macroProcessor.getSymbols(line)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ class Stripper:
|
|||
def __init__(self):
|
||||
pass
|
||||
|
||||
def processText(self, line):
|
||||
def processText(self, line, conveyorProcessor):
|
||||
assert line is not None
|
||||
|
||||
return line.strip(' \t\n\r')
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ class TextConveyorPreprocessor:
|
|||
|
||||
self.processors.append(processor)
|
||||
|
||||
def processText(self, text):
|
||||
def processText(self, text, conveyorProcessor):
|
||||
assert text is not None
|
||||
|
||||
for processor in self.processors:
|
||||
text = processor.processText(text)
|
||||
text = processor.processText(text, conveyorProcessor)
|
||||
|
||||
return text
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ class TextInclude:
|
|||
self.includeProcessor = includeProcessor
|
||||
self.contentProvider = contentProvider
|
||||
|
||||
def processText(self, text):
|
||||
def processText(self, text, conveyorProcessor):
|
||||
assert text is not None
|
||||
includesInfo = self.includeProcessor.getIncludesInfo(text)
|
||||
|
||||
|
|
@ -15,6 +15,8 @@ class TextInclude:
|
|||
path = info[1]
|
||||
|
||||
content = self.contentProvider.fetchContent(path)
|
||||
content = conveyorProcessor.processText(content, conveyorProcessor)
|
||||
|
||||
text = text.replace(includeStatement, content)
|
||||
|
||||
return text
|
||||
|
|
@ -42,7 +42,7 @@ class StepsRunner:
|
|||
|
||||
lines = content.splitlines()
|
||||
for line in lines:
|
||||
processedLine = self.lineConveyor.processText(line)
|
||||
processedLine = self.lineConveyor.processText(line, self.lineConveyor)
|
||||
|
||||
if len(processedLine) == 0:
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from CommandBuilders.CreateBackupCommandBuilder import CreateBackupCommandBuilder
|
||||
|
||||
line = "create backup for 'BuildSample'"
|
||||
line = "create backup"
|
||||
|
||||
cmdBuilder = CreateBackupCommandBuilder()
|
||||
command = cmdBuilder.getCommandFor(line)
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
__author__ = 'rzaitov'
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import unittest
|
||||
from parsers.ParserBackup.CreateBackupParser import CreateBackupParser
|
||||
|
||||
|
||||
class TestCreateBackup(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.parser = CreateBackupParser()
|
||||
|
||||
def test_isValid(self):
|
||||
line = "create backup"
|
||||
isValid = self.parser.isValidLine(line)
|
||||
|
||||
self.assertEqual(True, isValid)
|
||||
|
||||
def test_isNotValid(self):
|
||||
line = "create backup bla bla"
|
||||
isValid = self.parser.isValidLine(line)
|
||||
|
||||
self.assertEqual(False, isValid)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import unittest
|
||||
from parsers.ParserBackup.DeleteBackupParser import DeleteBackupParser
|
||||
|
||||
|
||||
class TestDeleteBackup(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.parser = DeleteBackupParser()
|
||||
|
||||
def test_parseCurrentDir(self):
|
||||
line = "delete backup '.'"
|
||||
folderPath = self.parser.parseLine(line)
|
||||
|
||||
self.assertEqual('.', folderPath)
|
||||
|
||||
def test_parseRelativePath(self):
|
||||
line = "delete backup '../Some/Path'"
|
||||
folderPath = self.parser.parseLine(line)
|
||||
|
||||
self.assertEqual('../Some/Path', folderPath)
|
||||
|
||||
def test_parseAbsPath(self):
|
||||
line = "delete backup '/Some/Abs/Path'"
|
||||
folderPath = self.parser.parseLine(line)
|
||||
|
||||
self.assertEqual('/Some/Abs/Path', folderPath)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import unittest
|
||||
from parsers.ParserBackup.RestoreBackupParser import RestoreBackupParser
|
||||
|
||||
|
||||
class TestRestoreBackup(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.parser = RestoreBackupParser()
|
||||
|
||||
def test_parseCurrentDir(self):
|
||||
line = "restore from backup '.'"
|
||||
folderPath = self.parser.parseLine(line)
|
||||
|
||||
self.assertEqual('.', folderPath)
|
||||
|
||||
def test_parseRelativePath(self):
|
||||
line = "restore from backup '../Some/Path'"
|
||||
folderPath = self.parser.parseLine(line)
|
||||
|
||||
self.assertEqual('../Some/Path', folderPath)
|
||||
|
||||
def test_parseAbsPath(self):
|
||||
line = "restore from backup '/Some/Abs/Path'"
|
||||
folderPath = self.parser.parseLine(line)
|
||||
|
||||
self.assertEqual('/Some/Abs/Path', folderPath)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
|
||||
|
||||
class BaseBackupCommand:
|
||||
def __init__(self):
|
||||
self.folderPath = '.'
|
||||
|
||||
# вычислять абсолютные пути надо на этапе создания комманды
|
||||
# поскольку на этапе выполнения текущая директория может быть удалена
|
||||
self.srcAbsDirPath = self.getAbsSrc()
|
||||
self.backupDirAbsPath = self.getAbsDst()
|
||||
|
||||
self.backupIgnore = ['.git', '.gitignore', '.DS_Store', 'backup']
|
||||
|
||||
def getAbsSrc(self):
|
||||
return self.getAbs(self.folderPath)
|
||||
|
||||
def getAbsDst(self):
|
||||
absFolderPath = self.getAbs(self.folderPath)
|
||||
|
||||
backupAbsPath = os.path.join(absFolderPath, 'backup')
|
||||
|
||||
return backupAbsPath
|
||||
|
||||
def getAbs(self, path):
|
||||
return os.path.abspath(path)
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import os
|
||||
import shutil
|
||||
from commands.BaseBackupCommand.BaseBackupCommand import BaseBackupCommand
|
||||
|
||||
|
||||
class CreateBackupCommand(BaseBackupCommand):
|
||||
def __init__(self):
|
||||
BaseBackupCommand.__init__(self)
|
||||
|
||||
def execute(self):
|
||||
if os.path.exists(self.backupDirAbsPath):
|
||||
raise Exception('folder: {0} already exists'.format(self.backupDirAbsPath))
|
||||
|
||||
dirContent = os.listdir(self.srcAbsDirPath)
|
||||
|
||||
os.mkdir(self.backupDirAbsPath)
|
||||
|
||||
for fileOrDir in dirContent:
|
||||
if fileOrDir not in self.backupIgnore:
|
||||
self.copyFileOrDirectoryToBackupFolder(fileOrDir)
|
||||
|
||||
def copyFileOrDirectoryToBackupFolder(self, fileOrDirName):
|
||||
assert fileOrDirName is not None
|
||||
|
||||
srcAbsPath = os.path.join(self.srcAbsDirPath, fileOrDirName)
|
||||
dstAbsPath = os.path.join(self.backupDirAbsPath, fileOrDirName)
|
||||
|
||||
if os.path.isdir(srcAbsPath):
|
||||
shutil.copytree(srcAbsPath, dstAbsPath)
|
||||
else:
|
||||
shutil.copy(srcAbsPath, dstAbsPath)
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import os
|
||||
import shutil
|
||||
from commands.BaseBackupCommand.BaseBackupCommand import BaseBackupCommand
|
||||
|
||||
|
||||
class DeleteBackupCommand(BaseBackupCommand):
|
||||
def __init__(self):
|
||||
BaseBackupCommand.__init__(self)
|
||||
|
||||
def execute(self):
|
||||
if not os.path.exists(self.backupDirAbsPath):
|
||||
raise Exception('backup folder: {0} not exists'.format(self.backupDirAbsPath))
|
||||
|
||||
shutil.rmtree(self.backupDirAbsPath, ignore_errors=True)
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
import os
|
||||
import shutil
|
||||
from commands.BaseBackupCommand.BaseBackupCommand import BaseBackupCommand
|
||||
|
||||
|
||||
class RestoreBackupCommand(BaseBackupCommand):
|
||||
def __init__(self):
|
||||
BaseBackupCommand.__init__(self)
|
||||
|
||||
def execute(self):
|
||||
if not os.path.exists(self.backupDirAbsPath):
|
||||
return
|
||||
|
||||
srcDirContent = os.listdir(self.srcAbsDirPath)
|
||||
for fileOrDir in srcDirContent:
|
||||
if fileOrDir not in self.backupIgnore:
|
||||
self.removeFileOrDirectory(fileOrDir)
|
||||
|
||||
backupDirContent = os.listdir(self.backupDirAbsPath)
|
||||
for fileOrDir in backupDirContent:
|
||||
self.copyFileOrDirectoryFromBackupFolder(fileOrDir)
|
||||
|
||||
def removeFileOrDirectory(self, fileOrDirName):
|
||||
|
||||
srcAbsPath = os.path.join(self.srcAbsDirPath, fileOrDirName)
|
||||
|
||||
if os.path.isdir(srcAbsPath):
|
||||
shutil.rmtree(srcAbsPath)
|
||||
else:
|
||||
os.remove(srcAbsPath)
|
||||
|
||||
def copyFileOrDirectoryFromBackupFolder(self, fileOrDirName):
|
||||
assert fileOrDirName is not None
|
||||
|
||||
srcAbsPath = os.path.join(self.srcAbsDirPath, fileOrDirName)
|
||||
fileInBackupFolderAbsPath = os.path.join(self.backupDirAbsPath, fileOrDirName)
|
||||
|
||||
if os.path.isdir(fileInBackupFolderAbsPath):
|
||||
shutil.copytree(fileInBackupFolderAbsPath, srcAbsPath)
|
||||
else:
|
||||
shutil.copy(fileInBackupFolderAbsPath, srcAbsPath)
|
||||
|
|
@ -0,0 +1 @@
|
|||
__author__ = 'rzaitov'
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
import shutil
|
||||
|
||||
class CreateBackupCommand:
|
||||
def __init__(self, backupArguments):
|
||||
assert backupArguments is not None
|
||||
|
||||
self.__backupArguments = backupArguments
|
||||
|
||||
def execute(self):
|
||||
src = self.__backupArguments.getSourceFolderName()
|
||||
dst = self.__backupArguments.getBackupFolderName()
|
||||
|
||||
shutil.rmtree(dst, ignore_errors=True)
|
||||
shutil.copytree(src, dst, symlinks=False)
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import os
|
||||
import shutil
|
||||
|
||||
class DeleteBackupCommand:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def execute(self):
|
||||
dirs = [name for name in os.listdir('.') if os.path.isdir(os.path.join('.', name)) & name.startswith('backup.')]
|
||||
for d in dirs:
|
||||
shutil.rmtree(d)
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
import os
|
||||
import shutil
|
||||
|
||||
|
||||
class RestoreBackupCommand:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def execute(self):
|
||||
dirPairs = [(name, "backup.{0}".format(name)) for name in os.listdir('.') if os.path.isdir(name) and not name.startswith('backup.')]
|
||||
|
||||
for pair in dirPairs:
|
||||
absPair = (pair[0], 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
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
class CreateBackupArguments:
|
||||
def __init__(self):
|
||||
self.folderName = None
|
||||
|
||||
def getSourceFolderName(self):
|
||||
return self.folderName
|
||||
|
||||
def getBackupFolderName(self):
|
||||
return "backup.{0}".format(self.folderName)
|
||||
|
||||
|
||||
|
|
@ -1,32 +1,17 @@
|
|||
import re
|
||||
|
||||
from parsers.ParserBackup.CreateBackupArguments import CreateBackupArguments
|
||||
from parsers.LineParser import LineParser
|
||||
from parsers.ParserBackup.ParserBackupBase import ParserBackupBase
|
||||
|
||||
|
||||
class CreateBackupParser(LineParser):
|
||||
class CreateBackupParser(ParserBackupBase):
|
||||
def __init__(self):
|
||||
LineParser.__init__(self)
|
||||
self.__createBackupArguments = CreateBackupArguments()
|
||||
ParserBackupBase.__init__(self)
|
||||
|
||||
def parseLine(self, line):
|
||||
def getMatchInfo(self, line):
|
||||
assert line is not None
|
||||
|
||||
folderNameRegexp = r"'(?P<folder>[^']+)'$"
|
||||
|
||||
regexpSource = self.startsWith('create backup for') + folderNameRegexp
|
||||
regexpSource = self.startsWith('create') + self.endsWith('backup')
|
||||
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
|
||||
return match, regexpSource
|
||||
|
|
@ -1,23 +1,17 @@
|
|||
import re
|
||||
|
||||
from parsers.LineParser import LineParser
|
||||
from parsers.ParserBackup.ParserBackupBase import ParserBackupBase
|
||||
|
||||
|
||||
class DeleteBackupParser(LineParser):
|
||||
class DeleteBackupParser(ParserBackupBase):
|
||||
def __init__(self):
|
||||
LineParser.__init__(self)
|
||||
ParserBackupBase.__init__(self)
|
||||
|
||||
def parseLine(self, line):
|
||||
def getMatchInfo(self, line):
|
||||
assert line is not None
|
||||
|
||||
regexpSource = r'delete backup\s*'
|
||||
regexpSource = self.startsWith('delete') + self.endsWith('backup')
|
||||
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
|
||||
return match, regexpSource
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
from parsers.LineParser import LineParser
|
||||
|
||||
|
||||
class ParserBackupBase(LineParser):
|
||||
def __init__(self):
|
||||
LineParser.__init__(self)
|
||||
|
||||
def parseLine(self, line):
|
||||
assert line is not None
|
||||
|
||||
mathInfo = self.getMatchInfo(line)
|
||||
match = mathInfo[0]
|
||||
regexpSource = mathInfo[1]
|
||||
|
||||
self._guardMatch(match, line, regexpSource)
|
||||
|
||||
def getMatchInfo(self, line):
|
||||
return None, None
|
||||
|
||||
def isValidLine(self, line):
|
||||
assert line is not None
|
||||
|
||||
matchInfo = self.getMatchInfo(line)
|
||||
match = matchInfo[0]
|
||||
|
||||
return match is not None
|
||||
|
||||
|
|
@ -1,24 +1,17 @@
|
|||
import re
|
||||
|
||||
from parsers.LineParser import LineParser
|
||||
from parsers.ParserBackup.ParserBackupBase import ParserBackupBase
|
||||
|
||||
|
||||
class RestoreBackupParser(LineParser):
|
||||
class RestoreBackupParser(ParserBackupBase):
|
||||
def __init__(self):
|
||||
LineParser.__init__(self)
|
||||
ParserBackupBase.__init__(self)
|
||||
|
||||
def parseLine(self, line):
|
||||
def getMatchInfo(self, line):
|
||||
assert line is not None
|
||||
|
||||
regexpSource = self.startsWith('restore') + self.than('from') + self.endsWith('backup')
|
||||
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')
|
||||
return isValid
|
||||
|
||||
return match, regexpSource
|
||||
|
|
@ -4,14 +4,16 @@ scriptFilePath = os.path.abspath(__file__)
|
|||
scriptDir = os.path.dirname(scriptFilePath)
|
||||
baseDir = os.path.join(scriptDir, os.pardir, os.pardir)
|
||||
|
||||
os.chdir(baseDir)
|
||||
baseDirAbsPath = os.path.abspath(baseDir)
|
||||
os.chdir(baseDirAbsPath)
|
||||
print 'current working dir: {0}'.format(baseDirAbsPath)
|
||||
|
||||
#import Tests.ManualTests.csproj_test
|
||||
#import ManualTests.info_plist_test
|
||||
#import ManualTests.copy_test
|
||||
#import ManualTests.create_backup_test
|
||||
#import ManualTests.delete_backup_test
|
||||
#import ManualTests.restore_backup_test
|
||||
#import Tests.ManualTests.create_backup_test
|
||||
import Tests.ManualTests.delete_backup_test
|
||||
#import Tests.ManualTests.restore_backup_test
|
||||
#import ManualTests.csproj_test
|
||||
#import ManualTests.run_sh_command
|
||||
#import ManualTests.make_dirs
|
||||
|
|
@ -21,5 +23,4 @@ os.chdir(baseDir)
|
|||
#import Tests.ManualTests.testflight_test
|
||||
#import Tests.ManualTests.install_profile
|
||||
#import Tests.ManualTests.macros_include_test
|
||||
|
||||
import Tests.ManualTests.resolve_settings
|
||||
#import Tests.ManualTests.resolve_settings
|
||||
|
|
@ -73,7 +73,7 @@ class TaskRunner:
|
|||
pathToSteps = config['steps']
|
||||
|
||||
content = self.fileContentProvider.fetchContent(pathToSteps)
|
||||
content = self.textPreprocessor.processText(content)
|
||||
content = self.textPreprocessor.processText(content, self.textPreprocessor)
|
||||
|
||||
return content
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue