Переписал создание команды патчинга csproj файлов

This commit is contained in:
rzaitov 2013-10-30 16:15:57 +04:00
parent 97f941ec9a
commit 67b5fcf73a
9 changed files with 103 additions and 123 deletions

View File

@ -0,0 +1,29 @@
from commands.PatchCsprojCommand import PatchCsprojCommand
from parser.ProjectParser.InsideParser import InsideParser
class PatchCsprojCommandBuilder:
def __init__(self, config, pathProvider, valueProvider):
assert config is not None
assert pathProvider is not None
assert valueProvider is not None
self.__config = config
self.__pathProvider = pathProvider
self.__valueProvider = valueProvider
def getCommandFor(self, line):
assert line is not None
parser = InsideParser(self.__valueProvider, 'csproj')
result = parser.parseLine(line)
relPath = result[0]
key = result[1]
value = self.__valueProvider.getValueFor(result[2])
csprojAbsPath = self.__valueProvider.resolveAbsPath(relPath)
slnConfig = self.__config['sln_config']
command = PatchCsprojCommand(csprojAbsPath, key, value, slnConfig)
return command

View File

@ -1,20 +1,13 @@
from CommandBuilders.PatchCsprojCommandBuilder import PatchCsprojCommandBuilder
from ManualTests.path_provider import PathProvider
from commands.ValueProvider import ValueProvider
import path_provider
import commands.patch_csproj_command as csproj
config = {
'csproj app:CoolApp rel_path': 'BuildSample/BuildSample/CoolApp.csproj',
'csproj app:CoolApp key:CodesignProvision': '@codesign_provision',
'csproj app:CoolApp key:CodesignKey': '@codesign_key',
config = {}
line = "inside 'BuildSample/BuildSample/CoolApp.csproj' set OutputPath to 'Output'"
'codesign_provision': 'MyProvisioningValue',
'codesign_key': 'MyCodesignValue',
'sln_config': 'Release|iPhone'
}
base_dir = '/Users/rzaitov/Documents/Apps/BuildScript'
path_provider = path_provider.PathProvider(base_dir)
base_dir = '../'
path_provider = PathProvider(base_dir)
value_provider = ValueProvider(config)
patcher = csproj.PatchCsproj(config, path_provider, value_provider)
patcher.execute()
builder = PatchCsprojCommandBuilder(config, path_provider, value_provider)
command = builder.getCommandFor(line)

View File

@ -1,32 +1,32 @@
# -*- coding: utf-8 -*-
import unittest
from UnitTests.ProjectParser.ValueProvider import ValueProvider
from parser.ProjectParser.ProjectParser import ProjectParser
from parser.ProjectParser.InsideParser import InsideParser
class TestCsprojParser(unittest.TestCase):
def setUp(self):
value_provider = ValueProvider()
self.parser = ProjectParser(value_provider, 'csproj')
self.parser = InsideParser(value_provider, 'csproj')
def test_isValid(self):
line = "for CoolApp csproj set KEY to 'VALUE'"
line = "inside 'CoolApp.csproj' set KEY to 'VALUE'"
isValid = self.parser.isValidLine(line)
self.assertEqual(True, isValid)
def test_isNotValid(self):
line = "for CoolApp InvalidCmdToken set KEY to 'VALUE'"
line = "inside 'CoolApp.txt' set KEY to 'VALUE'"
isValid = self.parser.isValidLine(line)
self.assertEqual(False, isValid)
def test_parse(self):
line = "for CoolApp.Touch csproj set OutputPath to 'Output'"
settings = self.parser.parseLine(line)
line = "inside 'Dir/../Some Folder/CoolApp.csproj' set OutputPath to 'Output'"
tuple = self.parser.parseLine(line)
self.assertEqual('CoolApp.Touch', settings.projectName)
self.assertEqual('OutputPath', settings.key)
self.assertEqual('Output', settings.value)
self.assertEqual('Dir/../Some Folder/CoolApp.csproj', tuple[0])
self.assertEqual('OutputPath', tuple[1])
self.assertEqual('Output', tuple[2])

View File

@ -0,0 +1,19 @@
import utils.csproj.patcher as csproj
class PatchCsprojCommand():
def __init__(self, csprojAbsPath, key, value, slnConfig):
assert csprojAbsPath is not None
assert key is not None
assert value is not None
assert slnConfig is not None
self.__csprojAbsPath = csprojAbsPath
self.__key = key
self.__value = value
self.__slnConfig = slnConfig
def execute(self):
patcher = csproj.Patcher(self.__csprojAbsPath)
dict = { self.__key : self.__value }
patcher.AddOrReplace(dict, self.__slnConfig)

View File

@ -1,12 +0,0 @@
from commands.patch_project import PatchProject
import utils.csproj.patcher as csproj
class PatchCsproj(PatchProject):
def __init__(self, config, path_provider, value_provider):
PatchProject.__init__(self, config, path_provider, value_provider, 'csproj')
def _patchProject(self, project):
csproj_abs_path = self._path_provider.resolveAbsPath(project.rel_path)
patcher = csproj.Patcher(csproj_abs_path)
patcher.AddOrReplace(project.settings, self._config['sln_config'])

View File

@ -1,47 +0,0 @@
import commands.build_command as bcmd
from parser.ProjectParser.ProjectParser import ProjectParser
class PatchProject(bcmd.BuildCommand):
def __init__(self, config, path_provider, value_provider, command_token):
assert path_provider is not None
assert value_provider is not None
assert command_token is not None
bcmd.BuildCommand.__init__(self, config, command_token)
self._path_provider = path_provider
self._value_provider = value_provider
self._command_token = command_token
self._parser = None
self._parseConfig()
def _parseConfig(self):
csproj_keys = self.FetchAllKeysFromConfig()
line_collection = self.__fetchLineCollection(csproj_keys)
self.__fillPatchSettings(line_collection)
def __fetchLineCollection(self, keys):
assert keys is not None
line_collection = ["{0} '{1}'".format(k, self._config[k]) for k in keys]
return line_collection
def __fillPatchSettings(self, line_collection):
assert line_collection is not None
self._parser = ProjectParser(line_collection, self._value_provider, self._command_token)
self._parser.parse()
def execute(self):
projects = self._parser.projects_dict.values()
for project in projects:
self._patchProject(project)
def _patchProject(self, project):
print 'Do nothing'
# override this method to do useful work
pass

View File

@ -0,0 +1,36 @@
from parser.LineParser import LineParser
import re
class InsideParser(LineParser):
def __init__(self, value_provider, fileExt):
assert value_provider is not None
self.__value_provider = value_provider
self.__extension = fileExt
def parseLine(self, line):
assert line is not None
filePathRegexp = r"'(?P<file>[./ a-zA-Z]+\.{0})'".format(self.__extension)
keyRegexp = r'(?P<key>[a-zA-Z]+)'
valueRegexp = r"'(?P<value>[^']+)'"
regexpSource = self.startsWithKeywordToken('inside') + filePathRegexp + self.keywordToken('set') + keyRegexp + self.keywordToken('to') + valueRegexp
regexp = re.compile(regexpSource, re.UNICODE)
match = regexp.match(line)
self._guardMatch(match, line, regexpSource)
filePath = match.group('file')
key = match.group('key')
value = match.group('value')
return (filePath, key, value)
def isValidLine(self, line):
regexpSrc = r"inside\s+'[./ a-zA-Z]+\.{0}'\s+set".format(self.__extension)
print regexpSrc
regexp = re.compile(regexpSrc, re.UNICODE)
match = regexp.match(line)
return match is not None

View File

@ -1,39 +0,0 @@
from parser.LineParser import LineParser
from parser.ProjectParser.ProjectSetting.KeyValueSetting import KeyValueSetting
import re
class ProjectParser(LineParser):
def __init__(self, value_provider, command_token):
assert value_provider is not None
self._value_provider = value_provider
self._command_token = command_token
def parseLine(self, line):
assert line is not None
projectNameRegexp = r"(?P<name>[.a-zA-Z]+)"
keyRegexp = r'(?P<key>[a-zA-Z]+)'
valueRegexp = r"'(?P<value>[^']+)'"
regexpSource = self.startsWithKeywordToken('for') + projectNameRegexp + self.keywordToken(self._command_token + r'\s+set') + keyRegexp + self.keywordToken('to') + valueRegexp
regexp = re.compile(regexpSource, re.UNICODE)
match = regexp.match(line)
self._guardMatch(match, line)
projectName = match.group('name')
key = match.group('key')
value = match.group('value')
settings = KeyValueSetting(key, value)
settings.projectName = projectName
return settings
def isValidLine(self, line):
regexpSrc = r'for\s+.*'+ self._command_token +r'\s+set'
regexp = re.compile(regexpSrc, re.UNICODE)
match = regexp.match(line)
return match is not None

View File

@ -3,5 +3,6 @@
#import ManualTests.copy_test
#import ManualTests.create_backup_test
#import ManualTests.delete_backup_test
#import ManualTests.restore_backup_test
import ManualTests.restore_backup_test
import ManualTests.csproj_test