Merge branch 'BS-32'

This commit is contained in:
rzaitov 2013-11-12 16:12:31 +04:00
commit 213e47c8a3
31 changed files with 255 additions and 121 deletions

View File

@ -1,5 +1,5 @@
restore from backup # восстанавливаем из бэкапа (исходники от сборки предыдущей конфигурации могут быть модифицированными)
create backup for 'BuildSample'
create backup
inside 'BuildSample/BuildSample.sln' remove NotCompileApp project

View File

@ -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

View File

@ -1,4 +1,4 @@
from commands.DeleteBackupCommand import DeleteBackupCommand
from commands.BaseBackupCommand.DeleteBackupCommand import DeleteBackupCommand
from parsers.ParserBackup.DeleteBackupParser import DeleteBackupParser

View File

@ -1,4 +1,4 @@
from commands.RestoreBackupCommand import RestoreBackupCommand
from commands.BaseBackupCommand.RestoreBackupCommand import RestoreBackupCommand
from parsers.ParserBackup.RestoreBackupParser import RestoreBackupParser

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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')

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,6 +1,6 @@
from CommandBuilders.CreateBackupCommandBuilder import CreateBackupCommandBuilder
line = "create backup for 'BuildSample'"
line = "create backup"
cmdBuilder = CreateBackupCommandBuilder()
command = cmdBuilder.getCommandFor(line)

View File

@ -0,0 +1 @@
__author__ = 'rzaitov'

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -0,0 +1 @@
__author__ = 'rzaitov'

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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