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'