diff --git a/BuildSample/BuildSample/Content/Icons/icon-iphone-staging.png b/BuildSample/BuildSample/Content/Icons/icon-iphone-staging.png
new file mode 100644
index 0000000..29526d1
Binary files /dev/null and b/BuildSample/BuildSample/Content/Icons/icon-iphone-staging.png differ
diff --git a/BuildSample/BuildSample/Content/Icons/icon-iphone-staging@2x.png b/BuildSample/BuildSample/Content/Icons/icon-iphone-staging@2x.png
new file mode 100644
index 0000000..1148c8b
Binary files /dev/null and b/BuildSample/BuildSample/Content/Icons/icon-iphone-staging@2x.png differ
diff --git a/BuildSample/BuildSample/Content/Icons/icon-iphone.png b/BuildSample/BuildSample/Content/Icons/icon-iphone.png
new file mode 100644
index 0000000..5bf2b49
Binary files /dev/null and b/BuildSample/BuildSample/Content/Icons/icon-iphone.png differ
diff --git a/BuildSample/BuildSample/Content/Icons/icon-iphone@2x.png b/BuildSample/BuildSample/Content/Icons/icon-iphone@2x.png
new file mode 100644
index 0000000..b19a36d
Binary files /dev/null and b/BuildSample/BuildSample/Content/Icons/icon-iphone@2x.png differ
diff --git a/BuildSample/BuildSample/CoolApp.csproj b/BuildSample/BuildSample/CoolApp.csproj
index 1a17219..f0a3948 100644
--- a/BuildSample/BuildSample/CoolApp.csproj
+++ b/BuildSample/BuildSample/CoolApp.csproj
@@ -70,9 +70,6 @@
-
-
-
@@ -88,4 +85,13 @@
Domain
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BuildSample/BuildSample/Info.plist b/BuildSample/BuildSample/Info.plist
index 476c4f2..7b6c0be 100644
--- a/BuildSample/BuildSample/Info.plist
+++ b/BuildSample/BuildSample/Info.plist
@@ -16,5 +16,10 @@
com.touchin.buildscript
CFBundleVersion
0.0.0
+ CFBundleIconFiles
+
+ Content/Icons/icon-iphone@2x
+ Content/Icons/icon-iphone
+
diff --git a/scripts/IosSetupSteps.txt b/scripts/IosSetupSteps.txt
index 062ea56..bccee30 100644
--- a/scripts/IosSetupSteps.txt
+++ b/scripts/IosSetupSteps.txt
@@ -9,4 +9,6 @@ inside 'BuildSample/BuildSample/CoolApp.csproj' set OutputPath to 'Output' for '
inside 'BuildSample/BuildSample/Info.plist' set CFBundleVersion to '{@version}'
inside 'BuildSample/BuildSample/Info.plist' set CFBundleDisplayName to 'CoolApp'
+inside 'BuildSample/BuildSample/Info.plist' set CFBundleIconFiles with values '{@icons}'
+
install profile 'BuildSample/BuildSample/Profiles/8F606DAE-F9C9-4A19-8EFF-34B990D76C28.mobileprovision'
\ No newline at end of file
diff --git a/scripts/TouchinBuild/CommandBuilders/PatchInfoPlistArrayCommandBuilder.py b/scripts/TouchinBuild/CommandBuilders/PatchInfoPlistArrayCommandBuilder.py
new file mode 100644
index 0000000..0b1425a
--- /dev/null
+++ b/scripts/TouchinBuild/CommandBuilders/PatchInfoPlistArrayCommandBuilder.py
@@ -0,0 +1,31 @@
+from commands.PatchInfoPlistCommand import PatchInfoPlistCommand
+from parsers.InsideParser.InsideSetArrayParser import InsideSetArrayParser
+
+
+class PatchInfoPlistArrayCommandBuilder:
+ def __init__(self):
+ pass
+
+ def isPatchInfoPlist(self, line):
+ assert line is not None
+
+ parser = self.createParser()
+ isValid = parser.isValidLine(line)
+
+ return isValid
+
+ def getCommandFor(self, line):
+ parser = self.createParser()
+ result = parser.parseLine(line)
+
+ path = result[0]
+ key = result[1]
+ value = parser.values
+
+ command = PatchInfoPlistCommand(path, key, value)
+ return command
+
+ def createParser(self):
+ parser = InsideSetArrayParser('plist')
+ return parser
+
diff --git a/scripts/TouchinBuild/CommandBuilders/PatchInfoplistCommandBuilder.py b/scripts/TouchinBuild/CommandBuilders/PatchInfoplistCommandBuilder.py
index 7c56d72..612e15d 100644
--- a/scripts/TouchinBuild/CommandBuilders/PatchInfoplistCommandBuilder.py
+++ b/scripts/TouchinBuild/CommandBuilders/PatchInfoplistCommandBuilder.py
@@ -11,13 +11,13 @@ class PatchInfoplistCommandBuilder:
def isPatchInfoPlist(self, line):
assert line is not None
- parser = self.__createParser()
+ parser = self.createParser()
isValid = parser.isValidLine(line)
return isValid
def getCommandFor(self, line):
- parser = self.__createParser()
+ parser = self.createParser()
result = parser.parseLine(line)
path = result[0]
@@ -27,7 +27,7 @@ class PatchInfoplistCommandBuilder:
command = PatchInfoPlistCommand(path, key, value)
return command
- def __createParser(self):
+ def createParser(self):
parser = InsideSetParser('plist')
return parser
diff --git a/scripts/TouchinBuild/Core/StepsRunner.py b/scripts/TouchinBuild/Core/StepsRunner.py
index 6b58ec6..4e5894b 100644
--- a/scripts/TouchinBuild/Core/StepsRunner.py
+++ b/scripts/TouchinBuild/Core/StepsRunner.py
@@ -5,6 +5,7 @@ from CommandBuilders.DeleteBackupCommandBuilder import DeleteBackupCommandBuilde
from CommandBuilders.InstallProfileCommandBuilder import InstallProfileCommandBuilder
from CommandBuilders.MakeDirsCommandBuilder import MakeDirsCommandBuilder
from CommandBuilders.PatchCsprojCommandBuilder import PatchCsprojCommandBuilder
+from CommandBuilders.PatchInfoPlistArrayCommandBuilder import PatchInfoPlistArrayCommandBuilder
from CommandBuilders.PatchInfoplistCommandBuilder import PatchInfoplistCommandBuilder
from CommandBuilders.RemoveProjectCommandBuilder import RemoveProjectCommandBuilder
from CommandBuilders.RestoreBackupCommandBuilder import RestoreBackupCommandBuilder
@@ -29,6 +30,7 @@ class StepsRunner:
self.createDirs = MakeDirsCommandBuilder()
self.patchCsproj = PatchCsprojCommandBuilder()
self.patchInfoPlist = PatchInfoplistCommandBuilder(self.valueProvider)
+ self.patchInfoPlistArray = PatchInfoPlistArrayCommandBuilder()
self.copyBuilder = CopyCommandBuilder()
self.testflightBuilder = TestflightCommandBuilder()
self.installProfileBuilder = InstallProfileCommandBuilder()
@@ -66,6 +68,8 @@ class StepsRunner:
cmd = self.patchCsproj.getCommandFor(line)
elif self.patchInfoPlist.isPatchInfoPlist(line):
cmd = self.patchInfoPlist.getCommandFor(line)
+ elif self.patchInfoPlistArray.isPatchInfoPlist(line):
+ cmd = self.patchInfoPlistArray.getCommandFor(line)
elif self.copyBuilder.isCopy(line):
cmd =self.copyBuilder.getCommandFor(line)
elif self.restoreFromBackupBuilder.isRestoreBackup(line):
diff --git a/scripts/TouchinBuild/Tests/ManualTests/infoPlistMultipleValues_test.py b/scripts/TouchinBuild/Tests/ManualTests/infoPlistMultipleValues_test.py
new file mode 100644
index 0000000..0934e61
--- /dev/null
+++ b/scripts/TouchinBuild/Tests/ManualTests/infoPlistMultipleValues_test.py
@@ -0,0 +1,8 @@
+from CommandBuilders.PatchInfoPlistArrayCommandBuilder import PatchInfoPlistArrayCommandBuilder
+
+line = "inside 'BuildSample/BuildSample/Info.plist' set UISupportedInterfaceOrientations with values 'value1:value2:value3'"
+
+cmdBuilder = PatchInfoPlistArrayCommandBuilder()
+command = cmdBuilder.getCommandFor(line)
+command.execute()
+
diff --git a/scripts/TouchinBuild/Tests/ManualTests/infoplist_test.py b/scripts/TouchinBuild/Tests/ManualTests/infoPlistSingleValue_test.py
similarity index 100%
rename from scripts/TouchinBuild/Tests/ManualTests/infoplist_test.py
rename to scripts/TouchinBuild/Tests/ManualTests/infoPlistSingleValue_test.py
diff --git a/scripts/TouchinBuild/Tests/UnitTests/IncludeText/test_includeText.py b/scripts/TouchinBuild/Tests/UnitTests/IncludeText/test_includeText.py
index d0c8550..79b5505 100644
--- a/scripts/TouchinBuild/Tests/UnitTests/IncludeText/test_includeText.py
+++ b/scripts/TouchinBuild/Tests/UnitTests/IncludeText/test_includeText.py
@@ -27,7 +27,7 @@ another bla
yet another bla"""
- processedText = self.includeText.processText(text)
+ processedText = self.includeText.processText(text, self.includeText)
expected = """
bla bla
diff --git a/scripts/TouchinBuild/Tests/UnitTests/InsideParsers/__init__.py b/scripts/TouchinBuild/Tests/UnitTests/InsideParsers/__init__.py
new file mode 100644
index 0000000..cc31abc
--- /dev/null
+++ b/scripts/TouchinBuild/Tests/UnitTests/InsideParsers/__init__.py
@@ -0,0 +1 @@
+__author__ = 'rzaitov'
diff --git a/scripts/TouchinBuild/Tests/UnitTests/InsideParsers/test_insideSetArrayParser.py b/scripts/TouchinBuild/Tests/UnitTests/InsideParsers/test_insideSetArrayParser.py
new file mode 100644
index 0000000..224d8e2
--- /dev/null
+++ b/scripts/TouchinBuild/Tests/UnitTests/InsideParsers/test_insideSetArrayParser.py
@@ -0,0 +1,46 @@
+import unittest
+from Tests.UnitTests.LineParserTestCaseBase import LineParserTestCaseBase
+from parsers.InsideParser.InsideSetArrayParser import InsideSetArrayParser
+
+
+class TestInsideSetArrayParser(LineParserTestCaseBase):
+ _validSingleValueTest = "inside 'my.txt' set KEY with values 'value1'"
+ _validMultiValueTest = "inside 'my.txt' set KEY with values 'value1:value2:value3'"
+
+ def setUp(self):
+ self.textParser = InsideSetArrayParser('txt')
+
+ def test_isValid(self):
+ self.isValidText(TestInsideSetArrayParser._validSingleValueTest)
+ self.isValidText(TestInsideSetArrayParser._validMultiValueTest)
+ self.isValidText("inside 'my.txt' set KEY with values 'value1:value2:value3'")
+
+ def test_isNotValid(self):
+ self.isNotValidText("inside 'my.sln' set KEY with values 'value1'")
+ self.isNotValidText("inside 'my.sln' set KEY with values 'value1:value2'")
+ self.isNotValidText("inside 'my.txt' set KEY with values 'value1' ")
+ self.isNotValidText("inside 'my.txt' set KEY with values 'value1' bla bla")
+
+
+ def test_parse(self):
+ self.checkParse(TestInsideSetArrayParser._validSingleValueTest, 'my.txt', 'KEY', 'value1')
+ self.checkParse(TestInsideSetArrayParser._validMultiValueTest, 'my.txt', 'KEY', 'value1:value2:value3')
+
+ def test_values(self):
+ self.checkValues(TestInsideSetArrayParser._validSingleValueTest, ['value1'])
+ self.checkValues(TestInsideSetArrayParser._validMultiValueTest, ['value1', 'value2', 'value3'])
+
+ def checkParse(self, line, filePath, key, value):
+ result = self.textParser.parseLine(line)
+
+ self.assertEqual(filePath, result[0])
+ self.assertEqual(key, result[1])
+ self.assertEqual(value, result[2])
+
+ def checkValues(self, text, expectedValues):
+ self.textParser.parseLine(text)
+
+ self.assertEqual(len(expectedValues), len(self.textParser.values))
+
+ for v in self.textParser.values:
+ self.assertTrue(v in expectedValues)
\ No newline at end of file
diff --git a/scripts/TouchinBuild/Tests/UnitTests/LineConveyor/test_commentRemover.py b/scripts/TouchinBuild/Tests/UnitTests/LineConveyor/test_commentRemover.py
index 97c27aa..028d416 100644
--- a/scripts/TouchinBuild/Tests/UnitTests/LineConveyor/test_commentRemover.py
+++ b/scripts/TouchinBuild/Tests/UnitTests/LineConveyor/test_commentRemover.py
@@ -8,12 +8,12 @@ class TestCommentRemover(unittest.TestCase):
def test_startsWithComment(self):
line = '# this line is comment'
- newLine = self.commentRemover.processText(line)
+ newLine = self.commentRemover.processText(line, self.commentRemover)
self.assertEqual('', newLine)
def test_containsComment(self):
line = 'this line contains # a comment'
- newLine = self.commentRemover.processText(line)
+ newLine = self.commentRemover.processText(line, self.commentRemover)
self.assertEqual('this line contains ', newLine)
\ No newline at end of file
diff --git a/scripts/TouchinBuild/Tests/UnitTests/LineConveyor/test_macroResolver.py b/scripts/TouchinBuild/Tests/UnitTests/LineConveyor/test_macroResolver.py
index 803a358..5fea29b 100644
--- a/scripts/TouchinBuild/Tests/UnitTests/LineConveyor/test_macroResolver.py
+++ b/scripts/TouchinBuild/Tests/UnitTests/LineConveyor/test_macroResolver.py
@@ -21,6 +21,6 @@ class TestMacroResolver(unittest.TestCase):
def test_resolveLine(self):
line = '{@key1} bla {@some_name} version: {@version}'
- newLine = self.macroResolver.processText(line)
+ newLine = self.macroResolver.processText(line, self.macroResolver)
self.assertEqual('hello world bla another name version: 1.2.3', newLine)
\ No newline at end of file
diff --git a/scripts/TouchinBuild/Tests/UnitTests/LineConveyor/test_stripper.py b/scripts/TouchinBuild/Tests/UnitTests/LineConveyor/test_stripper.py
index ecd6b81..256c7b1 100644
--- a/scripts/TouchinBuild/Tests/UnitTests/LineConveyor/test_stripper.py
+++ b/scripts/TouchinBuild/Tests/UnitTests/LineConveyor/test_stripper.py
@@ -8,6 +8,6 @@ class TestStripper(unittest.TestCase):
def test_stripLine(self):
line = ' \tSome text \t\r\n'
- newLine = self.stripper.processText(line)
+ newLine = self.stripper.processText(line, self.stripper)
self.assertEqual('Some text', newLine)
\ No newline at end of file
diff --git a/scripts/TouchinBuild/Tests/UnitTests/LineParserTestCaseBase.py b/scripts/TouchinBuild/Tests/UnitTests/LineParserTestCaseBase.py
new file mode 100644
index 0000000..4dc497e
--- /dev/null
+++ b/scripts/TouchinBuild/Tests/UnitTests/LineParserTestCaseBase.py
@@ -0,0 +1,18 @@
+from unittest.case import TestCase
+
+
+class LineParserTestCaseBase(TestCase):
+ def __init__(self, methodName):
+ TestCase.__init__(self, methodName)
+
+ self.textParser = None
+
+ def isValidText(self, text):
+ isValid = self.textParser.isValidLine(text)
+
+ self.assertEqual(True, isValid)
+
+ def isNotValidText(self, text):
+ isValid = self.textParser.isValidLine(text)
+
+ self.assertEqual(False, isValid)
diff --git a/scripts/TouchinBuild/Tests/UnitTests/ParserBackup/test_create_backup.py b/scripts/TouchinBuild/Tests/UnitTests/ParserBackup/test_create_backup.py
index c415aff..e3fc7e2 100644
--- a/scripts/TouchinBuild/Tests/UnitTests/ParserBackup/test_create_backup.py
+++ b/scripts/TouchinBuild/Tests/UnitTests/ParserBackup/test_create_backup.py
@@ -1,19 +1,15 @@
-import unittest
+from Tests.UnitTests.LineParserTestCaseBase import LineParserTestCaseBase
from parsers.ParserBackup.CreateBackupParser import CreateBackupParser
-class TestCreateBackup(unittest.TestCase):
+class TestCreateBackup(LineParserTestCaseBase):
def setUp(self):
- self.parser = CreateBackupParser()
+ self.textParser = CreateBackupParser()
def test_isValid(self):
- line = "create backup"
- isValid = self.parser.isValidLine(line)
-
- self.assertEqual(True, isValid)
+ self.isValidText('create backup')
+ self.isValidText('create backup')
def test_isNotValid(self):
- line = "create backup bla bla"
- isValid = self.parser.isValidLine(line)
-
- self.assertEqual(False, isValid)
\ No newline at end of file
+ self.isNotValidText('create backup ')
+ self.isNotValidText('create backup bla bla')
\ No newline at end of file
diff --git a/scripts/TouchinBuild/Tests/UnitTests/ParserBackup/test_deleteBackup.py b/scripts/TouchinBuild/Tests/UnitTests/ParserBackup/test_deleteBackup.py
index c8dfbd5..464427e 100644
--- a/scripts/TouchinBuild/Tests/UnitTests/ParserBackup/test_deleteBackup.py
+++ b/scripts/TouchinBuild/Tests/UnitTests/ParserBackup/test_deleteBackup.py
@@ -1,25 +1,15 @@
-import unittest
+from Tests.UnitTests.LineParserTestCaseBase import LineParserTestCaseBase
from parsers.ParserBackup.DeleteBackupParser import DeleteBackupParser
-class TestDeleteBackup(unittest.TestCase):
+class TestDeleteBackup(LineParserTestCaseBase):
def setUp(self):
- self.parser = DeleteBackupParser()
+ self.textParser = DeleteBackupParser()
- def test_parseCurrentDir(self):
- line = "delete backup '.'"
- folderPath = self.parser.parseLine(line)
+ def test_isValid(self):
+ self.isValidText('delete backup')
+ self.isValidText('delete backup')
- 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)
\ No newline at end of file
+ def test_isNotValid(self):
+ self.isNotValidText('delete backup ')
+ self.isNotValidText('delete backup bla bla')
diff --git a/scripts/TouchinBuild/Tests/UnitTests/ParserBackup/test_restoreBackup.py b/scripts/TouchinBuild/Tests/UnitTests/ParserBackup/test_restoreBackup.py
index 6e9437e..0acce9b 100644
--- a/scripts/TouchinBuild/Tests/UnitTests/ParserBackup/test_restoreBackup.py
+++ b/scripts/TouchinBuild/Tests/UnitTests/ParserBackup/test_restoreBackup.py
@@ -1,25 +1,15 @@
-import unittest
+from Tests.UnitTests.LineParserTestCaseBase import LineParserTestCaseBase
from parsers.ParserBackup.RestoreBackupParser import RestoreBackupParser
-class TestRestoreBackup(unittest.TestCase):
+class TestRestoreBackup(LineParserTestCaseBase):
def setUp(self):
- self.parser = RestoreBackupParser()
+ self.textParser = RestoreBackupParser()
- def test_parseCurrentDir(self):
- line = "restore from backup '.'"
- folderPath = self.parser.parseLine(line)
+ def test_isValid(self):
+ self.isValidText('restore from backup')
+ self.isValidText('restore from backup')
- 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)
\ No newline at end of file
+ def test_isNotValid(self):
+ self.isNotValidText('restore from backup ')
+ self.isNotValidText('restore from backup bla bla')
\ No newline at end of file
diff --git a/scripts/TouchinBuild/commands/BaseBackupCommand/CreateBackupCommand.py b/scripts/TouchinBuild/commands/BaseBackupCommand/CreateBackupCommand.py
index 32b76a9..cb559dd 100644
--- a/scripts/TouchinBuild/commands/BaseBackupCommand/CreateBackupCommand.py
+++ b/scripts/TouchinBuild/commands/BaseBackupCommand/CreateBackupCommand.py
@@ -8,11 +8,14 @@ class CreateBackupCommand(BaseBackupCommand):
BaseBackupCommand.__init__(self)
def execute(self):
- if os.path.exists(self.backupDirAbsPath):
- raise Exception('folder: {0} already exists'.format(self.backupDirAbsPath))
+ #if os.path.exists(self.backupDirAbsPath):
+ # raise Exception('folder: {0} already exists'.format(self.backupDirAbsPath))
dirContent = os.listdir(self.srcAbsDirPath)
+ if os.path.exists(self.backupDirAbsPath):
+ shutil.rmtree(self.backupDirAbsPath)
+
os.mkdir(self.backupDirAbsPath)
for fileOrDir in dirContent:
diff --git a/scripts/TouchinBuild/parsers/InsideParser/InsideCsprojSetParser.py b/scripts/TouchinBuild/parsers/InsideParser/InsideCsprojSetParser.py
index 2dcf2e9..d7f62bc 100644
--- a/scripts/TouchinBuild/parsers/InsideParser/InsideCsprojSetParser.py
+++ b/scripts/TouchinBuild/parsers/InsideParser/InsideCsprojSetParser.py
@@ -1,21 +1,13 @@
import re
-
-from parsers.LineParser import LineParser
+from parsers.InsideParser.InsideParserBase import InsideParserBase
-class InsideCsprojSetParser(LineParser):
+class InsideCsprojSetParser(InsideParserBase):
def __init__(self, fileExt):
- LineParser.__init__(self)
-
- self.__extension = fileExt
+ InsideParserBase.__init__(self, fileExt)
def parseLine(self, line):
- assert line is not None
-
- matchInfo = self.getMatchInfo(line)
- match = matchInfo[0]
- regexpSource = matchInfo[1]
- self._guardMatch(match, line, regexpSource)
+ match = self.fetchMatchFor(line)
filePath = match.group('file')
key = match.group('key')
@@ -27,22 +19,13 @@ class InsideCsprojSetParser(LineParser):
def getMatchInfo(self, line):
assert line is not None
- filePathRegexp = r"'(?P[./ a-zA-Z]+\.{0})'".format(self.__extension)
keyRegexp = r'(?P[a-zA-Z]+)'
valueRegexp = r"'(?P[^']+)'"
slnConfigRegexp = r"'(?P[a-zA-Z|]+)'$"
- regexpSource = self.startsWith('inside') + filePathRegexp + self.keywordToken('set') + keyRegexp + \
+ regexpSource = self.startsWith('inside') + self.filePathRegexp + self.keywordToken('set') + keyRegexp + \
self.keywordToken('to') + valueRegexp + self.keywordToken('for') + slnConfigRegexp
regexp = re.compile(regexpSource, re.UNICODE)
match = regexp.match(line)
- return match, regexpSource
-
- def isValidLine(self, line):
- assert line is not None
-
- matchInfo = self.getMatchInfo(line)
- match = matchInfo[0]
-
- return match is not None
\ No newline at end of file
+ return match, regexpSource
\ No newline at end of file
diff --git a/scripts/TouchinBuild/parsers/InsideParser/InsideParserBase.py b/scripts/TouchinBuild/parsers/InsideParser/InsideParserBase.py
new file mode 100644
index 0000000..c824749
--- /dev/null
+++ b/scripts/TouchinBuild/parsers/InsideParser/InsideParserBase.py
@@ -0,0 +1,38 @@
+import abc
+from parsers.LineParser import LineParser
+
+
+class InsideParserBase(object, LineParser):
+ __metaclass__ = abc.ABCMeta
+
+ def __init__(self, fileExt):
+ LineParser.__init__(self)
+
+ assert fileExt is not None
+ self.fileExt = fileExt
+ self.filePathRegexp = r"'(?P[./ a-zA-Z]+\.{0})'".format(self.fileExt)
+
+ @abc.abstractmethod
+ def getMatchInfo(self, line):
+ "Not implemented"
+ return None, None
+
+ def fetchMatchFor(self, text):
+ assert text is not None
+
+ matchInfo = self.getMatchInfo(text)
+ match = matchInfo[0]
+ regexpSource = matchInfo[1]
+
+ self._guardMatch(match, text, regexpSource)
+
+ return match
+
+
+ def isValidLine(self, line):
+ assert line is not None
+
+ matchInfo = self.getMatchInfo(line)
+ match = matchInfo[0]
+
+ return match is not None
diff --git a/scripts/TouchinBuild/parsers/InsideParser/InsideRemoveParser.py b/scripts/TouchinBuild/parsers/InsideParser/InsideRemoveParser.py
index 4c72539..435acd2 100644
--- a/scripts/TouchinBuild/parsers/InsideParser/InsideRemoveParser.py
+++ b/scripts/TouchinBuild/parsers/InsideParser/InsideRemoveParser.py
@@ -1,35 +1,27 @@
import re
-
-from parsers.LineParser import LineParser
+from parsers.InsideParser.InsideParserBase import InsideParserBase
-class InsideRemoveParser(LineParser):
+class InsideRemoveParser(InsideParserBase):
def __init__(self, fileExt):
- LineParser.__init__(self)
- assert fileExt is not None
-
- self.__extension = fileExt
+ InsideParserBase.__init__(self, fileExt)
def parseLine(self, line):
- assert line is not None
-
- filePathRegexp = r"'(?P[./ a-zA-Z]+\.{0})'".format(self.__extension)
- projectNameRegexp = r'(?P[.a-zA-Z]+)'
-
- regexpSource = self.startsWith('inside') + filePathRegexp + self.keywordToken('remove') + projectNameRegexp + self.spaceEndsWith('project')
- regexp = re.compile(regexpSource, re.UNICODE)
-
- match = regexp.match(line)
- self._guardMatch(match, line, regexpSource)
+ match = self.fetchMatchFor(line)
filePath = match.group('file')
projectName = match.group('project')
return filePath, projectName
- def isValidLine(self, line):
- regexpSrc = r"inside\s+'[./ a-zA-Z]+\.{0}'\s+remove".format(self.__extension)
- regexp = re.compile(regexpSrc, re.UNICODE)
+ def getMatchInfo(self, line):
+ assert line is not None
+
+ filePathRegexp = r"'(?P[./ a-zA-Z]+\.{0})'".format(self.fileExt)
+ projectNameRegexp = r'(?P[.a-zA-Z]+)'
+
+ regexpSource = self.startsWith('inside') + filePathRegexp + self.keywordToken('remove') + projectNameRegexp + self.spaceEndsWith('project')
+ regexp = re.compile(regexpSource, re.UNICODE)
match = regexp.match(line)
- return match is not None
\ No newline at end of file
+ return match, regexpSource
\ No newline at end of file
diff --git a/scripts/TouchinBuild/parsers/InsideParser/InsideSetArrayParser.py b/scripts/TouchinBuild/parsers/InsideParser/InsideSetArrayParser.py
new file mode 100644
index 0000000..d0de972
--- /dev/null
+++ b/scripts/TouchinBuild/parsers/InsideParser/InsideSetArrayParser.py
@@ -0,0 +1,41 @@
+import re
+from parsers.InsideParser.InsideParserBase import InsideParserBase
+
+
+class InsideSetArrayParser(InsideParserBase):
+ def __init__(self, fileExt):
+ InsideParserBase.__init__(self, fileExt)
+
+ self.values = None
+
+ def parseLine(self, line):
+ match = self.fetchMatchFor(line)
+
+ filePath = match.group('file')
+ key = match.group('key')
+ valuesStr = match.group('values')
+
+ self.values = self.parseValues(valuesStr)
+
+ return filePath, key, valuesStr
+
+ def getMatchInfo(self, line):
+ assert line is not None
+
+ keyRegexp = r'(?P[a-zA-Z]+)'
+ valueRegexp = r"'(?P[^']+)'$"
+
+ regexpSource = self.startsWith('inside') + self.filePathRegexp + self.keywordToken('set') + keyRegexp + \
+ self.keywordToken('with') + self.than('values') + valueRegexp
+ regexp = re.compile(regexpSource, re.UNICODE)
+
+ match = regexp.match(line)
+
+ return match, regexpSource
+
+ def parseValues(self, valuesStr):
+ assert valuesStr is not None
+ assert len(valuesStr) > 0
+
+ values = valuesStr.split(':')
+ return values
\ No newline at end of file
diff --git a/scripts/TouchinBuild/parsers/InsideParser/InsideSetParser.py b/scripts/TouchinBuild/parsers/InsideParser/InsideSetParser.py
index 7269940..2c9f883 100644
--- a/scripts/TouchinBuild/parsers/InsideParser/InsideSetParser.py
+++ b/scripts/TouchinBuild/parsers/InsideParser/InsideSetParser.py
@@ -1,20 +1,13 @@
import re
-
-from parsers.LineParser import LineParser
+from parsers.InsideParser.InsideParserBase import InsideParserBase
-class InsideSetParser(LineParser):
+class InsideSetParser(InsideParserBase):
def __init__(self, fileExt):
- LineParser.__init__(self)
- self.__extension = fileExt
+ InsideParserBase.__init__(self, fileExt)
def parseLine(self, line):
- assert line is not None
-
- matchInfo = self.getMatchInfo(line)
- match = matchInfo[0]
- regexpSource = matchInfo[1]
- self._guardMatch(match, line, regexpSource)
+ match = self.fetchMatchFor(line)
filePath = match.group('file')
key = match.group('key')
@@ -25,21 +18,13 @@ class InsideSetParser(LineParser):
def getMatchInfo(self, line):
assert line is not None
- filePathRegexp = r"'(?P[./ a-zA-Z]+\.{0})'".format(self.__extension)
keyRegexp = r'(?P[a-zA-Z]+)'
valueRegexp = r"'(?P[^']+)'$"
- regexpSource = self.startsWith('inside') + filePathRegexp + self.keywordToken('set') + keyRegexp + \
+ regexpSource = self.startsWith('inside') + self.filePathRegexp + self.keywordToken('set') + keyRegexp + \
self.keywordToken('to') + valueRegexp
regexp = re.compile(regexpSource, re.UNICODE)
match = regexp.match(line)
- return match, regexpSource
-
- def isValidLine(self, line):
- assert line is not None
-
- matchInfo = self.getMatchInfo(line)
- match = matchInfo[0]
- return match is not None
\ No newline at end of file
+ return match, regexpSource
\ No newline at end of file
diff --git a/scripts/TouchinBuild/run_manual_tests.py b/scripts/TouchinBuild/run_manual_tests.py
index 2a4db75..20deb9d 100644
--- a/scripts/TouchinBuild/run_manual_tests.py
+++ b/scripts/TouchinBuild/run_manual_tests.py
@@ -12,7 +12,7 @@ print 'current working dir: {0}'.format(baseDirAbsPath)
#import ManualTests.info_plist_test
#import ManualTests.copy_test
#import Tests.ManualTests.create_backup_test
-import Tests.ManualTests.delete_backup_test
+#import Tests.ManualTests.delete_backup_test
#import Tests.ManualTests.restore_backup_test
#import ManualTests.csproj_test
#import ManualTests.run_sh_command
@@ -23,4 +23,6 @@ import Tests.ManualTests.delete_backup_test
#import Tests.ManualTests.testflight_test
#import Tests.ManualTests.install_profile
#import Tests.ManualTests.macros_include_test
-#import Tests.ManualTests.resolve_settings
\ No newline at end of file
+#import Tests.ManualTests.resolve_settings
+
+import Tests.ManualTests.infoPlistMultipleValues_test
\ No newline at end of file
diff --git a/scripts/TouchinBuild/utils/InfoPlistPatcher.py b/scripts/TouchinBuild/utils/InfoPlistPatcher.py
index 3dc15f6..1d26fac 100644
--- a/scripts/TouchinBuild/utils/InfoPlistPatcher.py
+++ b/scripts/TouchinBuild/utils/InfoPlistPatcher.py
@@ -9,8 +9,12 @@ class InfoPlistPatcher():
tree = eT.parse(self.__infoPlistPath)
plist_dict = tree.getroot().find('dict')
- for key_name in key_value_dict:
- self.AppendOrReplaceValueByKey(key_name, key_value_dict[key_name], plist_dict)
+ for keyName in key_value_dict:
+ value = key_value_dict[keyName]
+ if type(value) is str:
+ self.AppendOrReplaceValueByKey(keyName, value, plist_dict)
+ else:
+ self.AppendOrReplaceValuesByKey(keyName, value, plist_dict)
tree.write(self.__infoPlistPath, xml_declaration=True, encoding='UTF-8', method="xml")
@@ -23,6 +27,15 @@ class InfoPlistPatcher():
else:
self.AppendKeyValue(key_name, value, dict_element)
+ def AppendOrReplaceValuesByKey(self, keyName, valuesArr, dictElement):
+ keyIndex = self.FindIndexByKey(keyName, dictElement)
+ elementExists = keyIndex >= 0
+
+ if elementExists:
+ self.ReplaceValuesByKeyIndex(keyIndex, valuesArr, dictElement)
+ else:
+ self.AppendValues(keyName, valuesArr, dictElement)
+
def FindIndexByKey(self, key_name, dict_element):
all_keys_elements = dict_element.findall('key')
@@ -43,15 +56,50 @@ class InfoPlistPatcher():
value_element = dict_element[value_index]
value_element.text = value
- def AppendKeyValue(self, key_name, value, dict_element):
- key_element = eT.Element('key')
- key_element.text = key_name
+ def ReplaceValuesByKeyIndex(self, keyIndex, valueArr, dict_element):
+ valuesIndex = keyIndex + 1
+ arrayElement = dict_element[valuesIndex]
- value_element = eT.Element('string')
- value_element.text = value
+ children = arrayElement.findall('string')
+ for ch in children:
+ arrayElement.remove(ch)
+
+ self.fillArrayElementWithValues(arrayElement, valueArr)
+
+ def AppendKeyValue(self, keyName, value, dict_element):
+ key_element = self.createKeyElement(keyName)
+ value_element = self.createValueElement(value)
dict_element.append(key_element)
dict_element.append(value_element)
+ def AppendValues(self, keyName, valuesArr, parentElement):
+ keyElement = self.createKeyElement(keyName)
+
+ arrayElement = eT.Element('array')
+ self.fillArrayElementWithValues(arrayElement, valuesArr)
+
+ parentElement.append(keyElement)
+ parentElement.append(arrayElement)
+
+ def createKeyElement(self, keyName):
+ keyElement = eT.Element('key')
+ keyElement.text = keyName
+
+ return keyElement
+
+ def createValueElement(self, value):
+ valueElement = eT.Element('string')
+ valueElement.text = value
+
+ return valueElement
+
+ def fillArrayElementWithValues(self, arrayElement, values):
+ for value in values:
+ valueElement = self.createValueElement(value)
+ arrayElement.append(valueElement)
+
+
+
diff --git a/scripts/settings.txt b/scripts/settings.txt
index 198829e..17963b1 100644
--- a/scripts/settings.txt
+++ b/scripts/settings.txt
@@ -6,6 +6,8 @@ configs = 'appstore, staging'
# ios platform settings
ios.sln_config = 'Release|iPhone'
ios.steps = 'scripts/IosSteps.txt'
+ios.setup_steps = 'IosSetupSteps.txt'
+
ios.tf_api_token = '0e6925075d4fc10fed0e7bbf43fa6894_NjQ0OTI2MjAxMi0wOS0yNSAxMTo0MDozNi40OTY5MjU'
ios.tf_team_token = 'c5c3cf7a6dae2bea4382dfbd181a2075_Mjc4ODkwMjAxMy0wOS0yOSAxNDowOTo1OC40Mzg5MTY'
@@ -15,8 +17,8 @@ ios.tf_team_token = 'c5c3cf7a6dae2bea4382dfbd181a2075_Mjc4ODkwMjAxMy0wOS0yOSAxND
# config settings
ios.appstore.app_name = 'CoolApp'
ios.appstore.author = 'Rustam'
-ios.appstore.setup_steps = 'IosSetupSteps.txt'
+ios.appstore.icons = 'Content/Icons/icon-iphone@2x:Content/Icons/icon-iphone'
ios.staging.app_name = 'CoolApp staging'
-ios.staging.steps = 'scripts/StagingSteps.txt'
-ios.staging.author = 'Fedor'
\ No newline at end of file
+ios.staging.author = 'Fedor'
+ios.staging.icons = 'Content/Icons/icon-iphone-staging@2x.png:Content/Icons/icon-iphone-staging.png'