diff --git a/BuildSample/BuildSample/Profiles/8F606DAE-F9C9-4A19-8EFF-34B990D76C28.mobileprovision b/BuildSample/BuildSample/Profiles/8F606DAE-F9C9-4A19-8EFF-34B990D76C28.mobileprovision new file mode 100644 index 0000000..61b689d Binary files /dev/null and b/BuildSample/BuildSample/Profiles/8F606DAE-F9C9-4A19-8EFF-34B990D76C28.mobileprovision differ diff --git a/scripts/CommandBuilders/CopyCommandBuilder.py b/scripts/CommandBuilders/CopyCommandBuilder.py new file mode 100644 index 0000000..475cdc8 --- /dev/null +++ b/scripts/CommandBuilders/CopyCommandBuilder.py @@ -0,0 +1,23 @@ +from commands.CopyCommand import CopyCommand +from parser.CopyParser.CopyLineParser import CopyLineParser + + +class CopyCommandBuilder: + def __init__(self, pathProvider): + assert pathProvider is not None + + self.__pathProvider = pathProvider + + def isCopy(self, line): + assert line is not None + + return line.startswith('copy') + + def getCommandFor(self, line): + assert line is not None + + parser = CopyLineParser() + cpArg = parser.parseLine(line) + + command = CopyCommand(self.__pathProvider, cpArg) + return command diff --git a/scripts/CommandBuilders/__init__.py b/scripts/CommandBuilders/__init__.py new file mode 100644 index 0000000..cc31abc --- /dev/null +++ b/scripts/CommandBuilders/__init__.py @@ -0,0 +1 @@ +__author__ = 'rzaitov' diff --git a/scripts/ManualTests/copy_test.py b/scripts/ManualTests/copy_test.py new file mode 100644 index 0000000..91a8085 --- /dev/null +++ b/scripts/ManualTests/copy_test.py @@ -0,0 +1,16 @@ +from CommandBuilders.CopyCommandBuilder import CopyCommandBuilder +from ManualTests.path_provider import PathProvider + +line1 = "copy 'BuildSample/BuildSample.sln' to 'BuildSample/BuildSample.txt'" +line2 = "copy 'BuildSample/BuildSample/Profiles/8F606DAE-F9C9-4A19-8EFF-34B990D76C28.mobileprovision' to '~/Library/MobileDevice/Provisioning Profiles/BuildScript.mobileprovision'" + +baseDir = '../' +path_provider = PathProvider(baseDir) + +copyCmdBuilder = CopyCommandBuilder(path_provider) + +#copyCmdToRel = copyCmdBuilder.getCommandFor(line1) +#copyCmdToRel.execute() + +copyCmdToAbs = copyCmdBuilder.getCommandFor(line2) +copyCmdToAbs.execute() diff --git a/scripts/UnitTests/CopyParser/__init__.py b/scripts/UnitTests/CopyParser/__init__.py new file mode 100644 index 0000000..cc31abc --- /dev/null +++ b/scripts/UnitTests/CopyParser/__init__.py @@ -0,0 +1 @@ +__author__ = 'rzaitov' diff --git a/scripts/UnitTests/CopyParser/test_copyArguments.py b/scripts/UnitTests/CopyParser/test_copyArguments.py new file mode 100644 index 0000000..e610773 --- /dev/null +++ b/scripts/UnitTests/CopyParser/test_copyArguments.py @@ -0,0 +1,37 @@ +import unittest +from parser.CopyParser.CopyArguments import CopyArguments + + +class TestCopyArguments(unittest.TestCase): + def setUp(self): + self.__copyArguments = CopyArguments() + + def test_isValid(self): + self.__copyArguments.setArguments("someVal1", "someVal2") + isValid = self.__copyArguments.isValid() + + self.assertEqual(True, isValid) + + def test_notValid(self): + self.__copyArguments.setArguments(None, "someVal2") + isValid = self.__copyArguments.isValid() + + self.assertEqual(False, isValid) + + def test_safeValues(self): + self.__copyArguments.setArguments('val1', 'val2') + + safeSrc = self.__copyArguments.getSafeSource() + safeDst = self.__copyArguments.getSaveTarget() + + self.assertEqual('val1', safeSrc) + self.assertEqual('val2', safeDst) + + def test_unsafeValues(self): + self.__copyArguments.setArguments('val1 with ws', 'val2 with ws') + + safeSrc = self.__copyArguments.getSafeSource() + safeDst = self.__copyArguments.getSaveTarget() + + self.assertEqual('"val1 with ws"', safeSrc) + self.assertEqual('"val2 with ws"', safeDst) diff --git a/scripts/UnitTests/CopyParser/test_copyParser.py b/scripts/UnitTests/CopyParser/test_copyParser.py new file mode 100644 index 0000000..60e54ca --- /dev/null +++ b/scripts/UnitTests/CopyParser/test_copyParser.py @@ -0,0 +1,23 @@ +import unittest +from parser.CopyParser.CopyLineParser import CopyLineParser + + +class TestCopyParser(unittest.TestCase): + def setUp(self): + self.__parser = CopyLineParser() + + def test_validSrcDst(self): + cpArgs = self.__parser.parseLine("copy 'File1' to 'File2'") + self.assertEqual('File1', cpArgs.source) + self.assertEqual('File2', cpArgs.target) + + def test_withFolder(self): + cpArgs = self.__parser.parseLine("copy 'dir1/dir2/src.txt' to 'dir3/dir4/dst.txt'") + self.assertEqual('dir1/dir2/src.txt', cpArgs.source) + self.assertEqual('dir3/dir4/dst.txt', cpArgs.target) + + def test_withWiteSpace(self): + cpArgs = self.__parser.parseLine("copy 'dir1 with ws/dir2 with ws/s r c.txt' to 'dir3 with ws/dir4/d s t.txt'") + self.assertEqual('dir1 with ws/dir2 with ws/s r c.txt', cpArgs.source) + self.assertEqual('dir3 with ws/dir4/d s t.txt', cpArgs.target) + diff --git a/scripts/UnitTests/ProjectParser/test_projectLineParser.py b/scripts/UnitTests/ProjectParser/test_projectLineParser.py index 79385ba..d26eb9c 100644 --- a/scripts/UnitTests/ProjectParser/test_projectLineParser.py +++ b/scripts/UnitTests/ProjectParser/test_projectLineParser.py @@ -32,7 +32,7 @@ class TestCsprojParser(unittest.TestCase): def test_parse_keyedCsprojLine(self): statement = r"csproj app:coolApp key:CodesignKey 'iPhone Developer: Рустам Заитов (CTL85FZX6K)'" - setting = self.parser.parse(statement) + setting = self.parser.parseLine(statement) self.assertEqual(setting.projectName, 'coolApp') self.assertEqual(setting.key, 'CodesignKey') @@ -40,7 +40,7 @@ class TestCsprojParser(unittest.TestCase): def test_parse_attributedCsprojLine(self): statement = r"csproj app:coolApp rel_path '../parent_dir/some_file.extension'" - setting = self.parser.parse(statement) + setting = self.parser.parseLine(statement) self.assertEqual(setting.projectName, 'coolApp') self.assertEqual(setting.attribute_name, 'rel_path') diff --git a/scripts/UnitTests/readme.txt b/scripts/UnitTests/readme.txt new file mode 100644 index 0000000..44b8579 --- /dev/null +++ b/scripts/UnitTests/readme.txt @@ -0,0 +1,5 @@ +Запуск всех тестов +python -m unittest discover -s UnitTests/ + +Запуск части тестов +python -m unittest discover -s UnitTests/CopyParser/ \ No newline at end of file diff --git a/scripts/commands/CopyCommand.py b/scripts/commands/CopyCommand.py new file mode 100644 index 0000000..30d01be --- /dev/null +++ b/scripts/commands/CopyCommand.py @@ -0,0 +1,25 @@ +import shutil +import os + +class CopyCommand: + def __init__(self, pathProvider, copyArguments): + assert pathProvider is not None + assert copyArguments is not None + + self.__pathProvider = pathProvider + self.__copyArguments = copyArguments + + def execute(self): + source = self.__expandPath(self.__copyArguments.source) + target = self.__expandPath(self.__copyArguments.target) + + shutil.copy(source, target) + + def __expandPath(self, path): + path = os.path.expanduser(path) + if not os.path.isabs(path): + path = self.__pathProvider.resolveAbsPath(path) + + return path + + diff --git a/scripts/parser/CopyParser/CopyArguments.py b/scripts/parser/CopyParser/CopyArguments.py new file mode 100644 index 0000000..a0b9bc7 --- /dev/null +++ b/scripts/parser/CopyParser/CopyArguments.py @@ -0,0 +1,31 @@ +__author__ = 'rzaitov' + + +class CopyArguments(): + def __init__(self): + self.source = None + self.target = None + + def setArguments(self, source, target): + self.source = source + self.target = target + + def isValid(self): + result = self.source is not None + result &= self.target is not None + + return result + + def getSafeSource(self): + safeSource = self.__makeSafe(self.source) + return safeSource + + def getSaveTarget(self): + safeTarget = self.__makeSafe(self.target) + return safeTarget + + def __makeSafe(self, filePath): + assert filePath is not None + + safe = filePath if ' ' not in filePath else '"{0}"'.format(filePath) + return safe \ No newline at end of file diff --git a/scripts/parser/CopyParser/CopyLineParser.py b/scripts/parser/CopyParser/CopyLineParser.py new file mode 100644 index 0000000..6e9c81e --- /dev/null +++ b/scripts/parser/CopyParser/CopyLineParser.py @@ -0,0 +1,39 @@ +from parser.CopyParser.CopyArguments import CopyArguments +from parser.LineParser import LineParser +import re + +class CopyLineParser(LineParser): + def __init__(self): + self.__copyArguments = CopyArguments() + + def parseLine(self, line): + assert line is not None + + srcFileNameRegexp = r"'(?P[^']+)'" + dstFileNameRegexp = r"'(?P[^']+)'$" + + regexpSource = self.startsWithKeywordToken('copy') + srcFileNameRegexp + self.keywordToken('to') + dstFileNameRegexp + regexp = re.compile(regexpSource, re.UNICODE) + + match = regexp.match(line) + self._guardMatch(match, line, regexpSource) + + src = match.group('src') + dst = match.group('dst') + + self.__copyArguments.setArguments(src, dst) + return self.__copyArguments + + def keywordToken(self, keyword): + assert keyword is not None + return r'\s+' + keyword + r'\s+' + + def startsWithKeywordToken(self, keyword): + assert keyword is not None + return r'^' + keyword + r'\s+' + + def isValidLine(self, line): + assert line is not None + + isValid = line.startswith("copy"); + return isValid \ No newline at end of file diff --git a/scripts/parser/CopyParser/__init__.py b/scripts/parser/CopyParser/__init__.py new file mode 100644 index 0000000..cc31abc --- /dev/null +++ b/scripts/parser/CopyParser/__init__.py @@ -0,0 +1 @@ +__author__ = 'rzaitov' diff --git a/scripts/parser/LineParser.py b/scripts/parser/LineParser.py new file mode 100644 index 0000000..3a077bc --- /dev/null +++ b/scripts/parser/LineParser.py @@ -0,0 +1,15 @@ +class LineParser: + def parseLine(self, line): + assert line is not None + pass + + def isValidLine(self, line): + assert line is not None + return False + + def _guardMatch(self, match_object, source, regexpSource = None): + if match_object is None: + msg = 'Recognition exception: {0} for {1}'.format(source, regexpSource) + raise Exception(msg) + + diff --git a/scripts/parser/ProjectParser/ProjectLineParser.py b/scripts/parser/ProjectParser/ProjectLineParser.py index 11c5873..3b822ba 100644 --- a/scripts/parser/ProjectParser/ProjectLineParser.py +++ b/scripts/parser/ProjectParser/ProjectLineParser.py @@ -1,15 +1,17 @@ +from parser.LineParser import LineParser from parser.ProjectParser.ProjectSetting.AttribureSetting import AttributeSetting from parser.ProjectParser.ProjectSetting.KeyValueSetting import KeyValueSetting import re -class ProjectLineParser: +class ProjectLineParser(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 parse(self, line): + def parseLine(self, line): + LineParser.parseLine(line) ws = ' ' cmd_name_regexp = "^(?P{0})".format(self._command_token) app_regexp = r"(?Papp:\S+)" @@ -19,7 +21,7 @@ class ProjectLineParser: regexp = re.compile(source, re.UNICODE) match = regexp.search(line) - self.__guardMatch(match, line) + self._guardMatch(match, line) cmd_name = match.group('cmd_name') self.__parseProjectStatement(cmd_name) @@ -40,7 +42,7 @@ class ProjectLineParser: patt = r'app:(?P\w+)' match = re.match(patt, statement) - self.__guardMatch(match, statement) + self._guardMatch(match, statement) return match.group('app_name') @@ -59,7 +61,7 @@ class ProjectLineParser: patt = r"key:(?P\w+) '(?P[^']+)'" match = re.search(patt, statement) - self.__guardMatch(match, statement) + self._guardMatch(match, statement) key = match.group('key') value_link = match.group('value') @@ -73,7 +75,7 @@ class ProjectLineParser: patt = r"(?P\w+) '(?P[^']+)'" match = re.search(patt, statement) - self.__guardMatch(match, statement) + self._guardMatch(match, statement) attribute_name = match.group('attribute_name') value_link = match.group('attribute_value') @@ -82,10 +84,5 @@ class ProjectLineParser: setting = AttributeSetting(attribute_name, attribute_value) return setting - def __guardMatch(self, match_object, source): - if match_object is None: - msg = 'Recognition exception: {0}'.format(source) - raise Exception(msg) - def __guardSource(self, source_text): assert source_text is not None and len(source_text) > 0 \ No newline at end of file diff --git a/scripts/parser/ProjectParser/ProjectParser.py b/scripts/parser/ProjectParser/ProjectParser.py index 9322faa..fd26482 100644 --- a/scripts/parser/ProjectParser/ProjectParser.py +++ b/scripts/parser/ProjectParser/ProjectParser.py @@ -33,6 +33,6 @@ class ProjectParser: def __parse_line(self, line): line_parser = ProjectLineParser(self._value_provider, self._command_token) - setting = line_parser.parse(line) + setting = line_parser.parseLine(line) return setting \ No newline at end of file diff --git a/scripts/run_manual_tests.py b/scripts/run_manual_tests.py index 117f43b..dab7faf 100644 --- a/scripts/run_manual_tests.py +++ b/scripts/run_manual_tests.py @@ -1,2 +1,3 @@ -import ManualTests.csproj_test -import ManualTests.info_plist_test \ No newline at end of file +#import ManualTests.csproj_test +#import ManualTests.info_plist_test +import ManualTests.copy_test \ No newline at end of file