Переписал создание команды патчинга csproj файлов
This commit is contained in:
parent
97f941ec9a
commit
67b5fcf73a
|
|
@ -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
|
||||||
|
|
@ -1,20 +1,13 @@
|
||||||
|
from CommandBuilders.PatchCsprojCommandBuilder import PatchCsprojCommandBuilder
|
||||||
|
from ManualTests.path_provider import PathProvider
|
||||||
from commands.ValueProvider import ValueProvider
|
from commands.ValueProvider import ValueProvider
|
||||||
import path_provider
|
|
||||||
import commands.patch_csproj_command as csproj
|
|
||||||
|
|
||||||
config = {
|
config = {}
|
||||||
'csproj app:CoolApp rel_path': 'BuildSample/BuildSample/CoolApp.csproj',
|
line = "inside 'BuildSample/BuildSample/CoolApp.csproj' set OutputPath to 'Output'"
|
||||||
'csproj app:CoolApp key:CodesignProvision': '@codesign_provision',
|
|
||||||
'csproj app:CoolApp key:CodesignKey': '@codesign_key',
|
|
||||||
|
|
||||||
'codesign_provision': 'MyProvisioningValue',
|
base_dir = '../'
|
||||||
'codesign_key': 'MyCodesignValue',
|
path_provider = PathProvider(base_dir)
|
||||||
'sln_config': 'Release|iPhone'
|
|
||||||
}
|
|
||||||
|
|
||||||
base_dir = '/Users/rzaitov/Documents/Apps/BuildScript'
|
|
||||||
path_provider = path_provider.PathProvider(base_dir)
|
|
||||||
value_provider = ValueProvider(config)
|
value_provider = ValueProvider(config)
|
||||||
|
|
||||||
patcher = csproj.PatchCsproj(config, path_provider, value_provider)
|
builder = PatchCsprojCommandBuilder(config, path_provider, value_provider)
|
||||||
patcher.execute()
|
command = builder.getCommandFor(line)
|
||||||
|
|
@ -1,32 +1,32 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import unittest
|
import unittest
|
||||||
from UnitTests.ProjectParser.ValueProvider import ValueProvider
|
from UnitTests.ProjectParser.ValueProvider import ValueProvider
|
||||||
from parser.ProjectParser.ProjectParser import ProjectParser
|
from parser.ProjectParser.InsideParser import InsideParser
|
||||||
|
|
||||||
|
|
||||||
class TestCsprojParser(unittest.TestCase):
|
class TestCsprojParser(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
value_provider = ValueProvider()
|
value_provider = ValueProvider()
|
||||||
self.parser = ProjectParser(value_provider, 'csproj')
|
self.parser = InsideParser(value_provider, 'csproj')
|
||||||
|
|
||||||
|
|
||||||
def test_isValid(self):
|
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)
|
isValid = self.parser.isValidLine(line)
|
||||||
|
|
||||||
self.assertEqual(True, isValid)
|
self.assertEqual(True, isValid)
|
||||||
|
|
||||||
def test_isNotValid(self):
|
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)
|
isValid = self.parser.isValidLine(line)
|
||||||
|
|
||||||
self.assertEqual(False, isValid)
|
self.assertEqual(False, isValid)
|
||||||
|
|
||||||
def test_parse(self):
|
def test_parse(self):
|
||||||
line = "for CoolApp.Touch csproj set OutputPath to 'Output'"
|
line = "inside 'Dir/../Some Folder/CoolApp.csproj' set OutputPath to 'Output'"
|
||||||
settings = self.parser.parseLine(line)
|
tuple = self.parser.parseLine(line)
|
||||||
|
|
||||||
self.assertEqual('CoolApp.Touch', settings.projectName)
|
self.assertEqual('Dir/../Some Folder/CoolApp.csproj', tuple[0])
|
||||||
self.assertEqual('OutputPath', settings.key)
|
self.assertEqual('OutputPath', tuple[1])
|
||||||
self.assertEqual('Output', settings.value)
|
self.assertEqual('Output', tuple[2])
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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'])
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -3,5 +3,6 @@
|
||||||
#import ManualTests.copy_test
|
#import ManualTests.copy_test
|
||||||
#import ManualTests.create_backup_test
|
#import ManualTests.create_backup_test
|
||||||
#import ManualTests.delete_backup_test
|
#import ManualTests.delete_backup_test
|
||||||
|
#import ManualTests.restore_backup_test
|
||||||
|
|
||||||
import ManualTests.restore_backup_test
|
import ManualTests.csproj_test
|
||||||
Loading…
Reference in New Issue