Реализовал парсинг патчинга csproj файла

This commit is contained in:
Rustam Zaitov 2013-10-03 22:31:55 +04:00
parent b0abdcccdb
commit 970be15c16
5 changed files with 135 additions and 42 deletions

View File

@ -0,0 +1,16 @@
import path_provider
import commands.patch_csproj_command as csproj
config = {
'csproj group:CoolApp key:rel_path': 'BuildSample/CoolApp.csproj',
'csproj group:CoolApp key:CodesignProvision': '@codesign_provision',
'csproj group:CoolApp key:CodesignKey': '@codesign_key',
'codesign_provision': 'MyProvisioningValue',
'codesign_key': 'MyCodesignValue'
}
base_dir = '/Users/rzaitov/Documents/Apps/BuildScript',
provider = path_provider.PathProvider(base_dir)
patcher = csproj.PatchCsproj(config, provider)
patcher.Execute()

View File

@ -0,0 +1,10 @@
import os
class PathProvider:
def __init__(self, base_dir):
self._base_dir = base_dir
def ResolveAbsPath(self, rel_path):
abs_path = os.path.join(self._base_dir, rel_path)
return abs_path

View File

@ -29,19 +29,6 @@ class BuildCommand:
return all_keys
def ParseKeyToken(self, key_token):
# csproj-AppName-Key
identifiers = key_token.split(self._separator)
result = {
self._prefix_name: identifiers[0],
self._app_name: identifiers[1],
self._key_name: identifiers[2]
}
return result
def ParseValueFromToken(self, value_token):
value = value_token

View File

@ -1,11 +1,12 @@
import commands.build_command as bcmd
import utils.csproj.patcher as csproj
import utils.PathConverter.path_converter as path
import parser.CsprojParser as parser
class PatchCsproj(bcmd.BuildCommand):
def __init__(self, config):
bcmd.BuildCommand.__init__(self, config, 'csproj-')
self._patch_settings = {}
def __init__(self, config, path_provider):
bcmd.BuildCommand.__init__(self, config, 'csproj')
self._path_provider = path_provider
self._parser = None
def ParseConfig(self):
csproj_keys = self.FetchAllKeysFromConfig()
@ -13,36 +14,20 @@ class PatchCsproj(bcmd.BuildCommand):
def FillPatchSettings(self, key_tokens):
self._parser = parser.CsprojParser(self._config)
for key_token in key_tokens:
key_info = self.ParseKeyToken(key_token)
self._parser.parse(key_token, self._config[key_token])
project_name = key_info[self._app_name]
key = key_info[self._key_name]
value = self.ParseValueFromToken(self._config[key_token])
project_settings = self.FetchSettingForProject(project_name)
project_settings[key] = value
def FetchSettingForProject(self, project_name):
project_settings = self._patch_settings.get(project_name, None)
if project_settings is None:
project_settings = {}
self._patch_settings[project_name] = project_settings
return project_settings
def Execute(self):
converter = path.PathConverter(self._config['sln_path'])
projects_list = self._parser.projects
for project_name in self._patch_settings.keys():
project_settings = self._patch_settings[project_name]
self.PatchProject(project_settings, converter)
for project in projects_list:
self.PatchProject(project)
def PatchProject(self, project_settings, path_converter):
csproj_rel_path = project_settings['rel_path']
csproj_abs_path = path_converter.Convert(csproj_rel_path)
def PatchProject(self, project):
csproj_abs_path = self._path_provider.fetchAbsPath(project.rel_path)
patcher = csproj.Patcher(csproj_abs_path)
patcher.AddOrReplace(project_settings, self._config['sln_config'])
patcher.AddOrReplace(project.settings, self._config['sln_config'])

View File

@ -0,0 +1,95 @@
from parser.StringValueParser import *
from parser.AttributeNameParser import *
class CsprojParser:
def __init__(self, config):
self._config = config
self._token_buffer = None
self._token_index = 0
self._current_project = None
self.projects = {}
def initTokenBuffer(self, string_to_parse, value_token):
self._token_buffer = string_to_parse.split(' ')
self._token_buffer.append(value_token)
self._token_index = 0
def parse(self, string_to_parse, value_token):
self.initTokenBuffer(string_to_parse, value_token)
while self._token_index < len(self._token_buffer):
self.ProcessToken()
def ProcessToken(self):
token = self.getCurrentToken()
if self.isCsprojStatement(token):
self._token_index += 1
elif self.isAppToken(token):
self.processAppToken(token)
self._token_index += 1
elif self.isKeyToken(token):
key_name = self.processKeyToken(token)
self._token_index += 1
token = self.getCurrentToken()
value = self.processValueToken()
self._token_index += 1
self._current_project.settings[key_name] = value
elif self.isAttributeToken(token):
attribute_name = self.processAttributeNameToken(token)
self._token_index += 1
token = self.getCurrentToken()
attribute_value = self.processValueToken(token)
self._token_index += 1
setattr(self.project, attribute_name, attribute_value)
def isCsprojStatement(self, token):
return token == 'csproj'
def isAppToken(self, token):
return token.startswith('app:')
def isKeyToken(self, token):
return token.startswith('key:')
def isAttributeToken(self, token):
return ':' not in token
def processAppToken(self, appToken):
appName = appToken[len('app:')]
self.setCurrentProject(appName)
def setCurrentProject(self, appName):
exists = appName in self.projects
self._current_project = self.projects[appName] if exists else Csproj(appName)
self.projects[appName] = self._current_project
def processKeyToken(self, token):
key_name = token[len('key:')]
return key_name
def processAttributeNameToken(self, token):
attribute_name = token
return attribute_name
def processValueToken(self, token):
value = token
if token.startswith('@'):
key = token[1:]
value = self._config[key]
return value
def getCurrentToken(self):
token = self._token_buffer[self._token_index]
return token
class Csproj:
def __init__(self, appName):
self.appName = appName
self.settings = {}