From b45ac60a2a593e5e951c8978d8b504752edff693 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Thu, 11 Jun 2020 16:44:14 +0300 Subject: [PATCH 1/2] add configs generation based on build options --- .../build_options_helper/.gitignore | 129 +++++++++++ .../build_options_helper/LICENSE | 201 ++++++++++++++++++ .../build_options_helper/README.md | 2 + .../build_options_helper/argument_parser.py | 25 +++ .../build_options_helper/core/__init__.py | 3 + .../core/models/__init__.py | 9 + .../core/models/build_parameters.py | 27 +++ .../core/models/parameter.py | 25 +++ .../core/models/parameters_set.py | 77 +++++++ .../core/models/restriction.py | 24 +++ .../core/models/selector.py | 23 ++ .../build_options_helper/helper.py | 51 +++++ .../ios_build_settings_renderer/__init__.py | 6 + .../ios_build_settings_renderer/models.py | 120 +++++++++++ .../ios_build_settings_renderer/raw_models.py | 17 ++ .../xcconfigs_renderer.py | 19 ++ .../build_options_helper/requirements.pip | 1 + .../test_data/build_parameters.yaml | 97 +++++++++ .../web_parameters_renderer/__init__.py | 6 + .../web_parameters_renderer/models.py | 13 ++ .../parameter_renderer.py | 20 ++ .../web_parameters_renderer/raw_models.py | 12 ++ xcode/config_generator/custom_settings.json | 25 --- xcode/config_generator/example_settings.yaml | 27 +++ xcode/config_generator/gen_configurations.py | 94 -------- xcode/config_generator/render_xcconfigs.rb | 21 +- 26 files changed, 945 insertions(+), 129 deletions(-) create mode 100644 xcode/config_generator/build_options_helper/.gitignore create mode 100644 xcode/config_generator/build_options_helper/LICENSE create mode 100644 xcode/config_generator/build_options_helper/README.md create mode 100644 xcode/config_generator/build_options_helper/argument_parser.py create mode 100644 xcode/config_generator/build_options_helper/core/__init__.py create mode 100644 xcode/config_generator/build_options_helper/core/models/__init__.py create mode 100644 xcode/config_generator/build_options_helper/core/models/build_parameters.py create mode 100644 xcode/config_generator/build_options_helper/core/models/parameter.py create mode 100644 xcode/config_generator/build_options_helper/core/models/parameters_set.py create mode 100644 xcode/config_generator/build_options_helper/core/models/restriction.py create mode 100644 xcode/config_generator/build_options_helper/core/models/selector.py create mode 100755 xcode/config_generator/build_options_helper/helper.py create mode 100644 xcode/config_generator/build_options_helper/ios_build_settings_renderer/__init__.py create mode 100644 xcode/config_generator/build_options_helper/ios_build_settings_renderer/models.py create mode 100644 xcode/config_generator/build_options_helper/ios_build_settings_renderer/raw_models.py create mode 100644 xcode/config_generator/build_options_helper/ios_build_settings_renderer/xcconfigs_renderer.py create mode 100644 xcode/config_generator/build_options_helper/requirements.pip create mode 100644 xcode/config_generator/build_options_helper/test_data/build_parameters.yaml create mode 100644 xcode/config_generator/build_options_helper/web_parameters_renderer/__init__.py create mode 100644 xcode/config_generator/build_options_helper/web_parameters_renderer/models.py create mode 100644 xcode/config_generator/build_options_helper/web_parameters_renderer/parameter_renderer.py create mode 100644 xcode/config_generator/build_options_helper/web_parameters_renderer/raw_models.py delete mode 100644 xcode/config_generator/custom_settings.json create mode 100644 xcode/config_generator/example_settings.yaml delete mode 100644 xcode/config_generator/gen_configurations.py diff --git a/xcode/config_generator/build_options_helper/.gitignore b/xcode/config_generator/build_options_helper/.gitignore new file mode 100644 index 0000000..b6e4761 --- /dev/null +++ b/xcode/config_generator/build_options_helper/.gitignore @@ -0,0 +1,129 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/xcode/config_generator/build_options_helper/LICENSE b/xcode/config_generator/build_options_helper/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/xcode/config_generator/build_options_helper/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/xcode/config_generator/build_options_helper/README.md b/xcode/config_generator/build_options_helper/README.md new file mode 100644 index 0000000..78a5670 --- /dev/null +++ b/xcode/config_generator/build_options_helper/README.md @@ -0,0 +1,2 @@ +# build_options_helper +An utility to work with build options diff --git a/xcode/config_generator/build_options_helper/argument_parser.py b/xcode/config_generator/build_options_helper/argument_parser.py new file mode 100644 index 0000000..d56499f --- /dev/null +++ b/xcode/config_generator/build_options_helper/argument_parser.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +import argparse +import os +import tempfile + +class writeable_dir(argparse.Action): + def __call__(self, parser, namespace, values, option_string=None): + prospective_dir = values + + if not os.path.isdir(prospective_dir): + raise argparse.ArgumentTypeError("writeable_dir:{0} is not a valid path".format(prospective_dir)) + if os.access(prospective_dir, os.W_OK): + setattr(namespace, self.dest, prospective_dir) + else: + raise argparse.ArgumentTypeError("writeable_dir:{0} is not a writeable dir".format(prospective_dir)) + +class ArgumentParser(argparse.ArgumentParser): + def configure(self): + self.add_argument('--build-parameters-path', '-bp', default="build_parameters.yaml", type=open, required=True) + self.add_argument('--output-folder', '-o', action=writeable_dir, default=tempfile.mkdtemp(), required=True) + self.add_argument('--render', '-r', choices=['ios_build_settings', 'team_city_web_parameters'], type=str, required=True) + self.add_argument('--platform', '-p', choices=['ios', 'android'], type=str, required=True) \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/core/__init__.py b/xcode/config_generator/build_options_helper/core/__init__.py new file mode 100644 index 0000000..85f54f0 --- /dev/null +++ b/xcode/config_generator/build_options_helper/core/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/core/models/__init__.py b/xcode/config_generator/build_options_helper/core/models/__init__.py new file mode 100644 index 0000000..28ba362 --- /dev/null +++ b/xcode/config_generator/build_options_helper/core/models/__init__.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from .selector import Selector +from .restriction import Restriction +from .parameter import Parameter +from .build_parameters import BuildParameters +from .parameters_set import ParametersSet diff --git a/xcode/config_generator/build_options_helper/core/models/build_parameters.py b/xcode/config_generator/build_options_helper/core/models/build_parameters.py new file mode 100644 index 0000000..128ee8f --- /dev/null +++ b/xcode/config_generator/build_options_helper/core/models/build_parameters.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from collections import namedtuple + +from .restriction import Restriction +from .parameter import Parameter + +BuildParametersTuple = namedtuple('BuildParametersTuple', [ + 'all_parameters', + 'project_restrictions', + 'ci_parameters', + 'ios_parameters', + 'android_parameters', +]) + +class BuildParameters(BuildParametersTuple): + @staticmethod + def from_dict(dict_obj): + return BuildParameters( + all_parameters=list(map(Parameter.from_dict, dict_obj["all_parameters"])), + project_restrictions=list(map(Restriction.from_dict, dict_obj["project_restrictions"])), + ci_parameters=list(map(Parameter.from_dict, dict_obj["ci_parameters"])), + ios_parameters=list(map(Parameter.from_dict, dict_obj["ios_parameters"])), + android_parameters=list(map(Parameter.from_dict, dict_obj["android_parameters"])) + ) \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/core/models/parameter.py b/xcode/config_generator/build_options_helper/core/models/parameter.py new file mode 100644 index 0000000..38e780d --- /dev/null +++ b/xcode/config_generator/build_options_helper/core/models/parameter.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from collections import namedtuple + +from .selector import Selector + +ParameterTuple = namedtuple('ParameterTuple', [ + 'key', + 'values', + 'default_value', +]) + +class Parameter(ParameterTuple): + @staticmethod + def from_dict(dict_obj): + return Parameter( + key=dict_obj["key"], + values=dict_obj["values"], + default_value=dict_obj.get("default_value") + ) + + def values_selectors(self): + return [Selector(key=self.key, value=value) for value in self.values] \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/core/models/parameters_set.py b/xcode/config_generator/build_options_helper/core/models/parameters_set.py new file mode 100644 index 0000000..034023d --- /dev/null +++ b/xcode/config_generator/build_options_helper/core/models/parameters_set.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from collections import namedtuple + +from .selector import Selector + +ParametersSetTuple = namedtuple('ParametersSetTuple', [ + 'active_parameters', +]) + +class ParametersSet(ParametersSetTuple): + def filter_using_restrictions_and_selectors(self, restrictions, selectors): + new_parameters = ParametersSet.__filter_parameters_using_restrictions_and_selectors(self.active_parameters, restrictions, selectors) + + return ParametersSet(active_parameters=new_parameters) + + def update_parameters(self, parameters): + parameters_dict = { p.key : p for p in parameters } + parameters_dict_keys = parameters_dict.keys() + + # update & keep ordering + new_active_parameters = [parameters_dict[p.key] if p.key in parameters_dict_keys else p for p in self.active_parameters] + + return ParametersSet(active_parameters=new_active_parameters) + + @staticmethod + def __filter_parameters_using_restrictions_and_selectors(parameters, restrictions, selectors): + active_restrictions = filter(lambda r: r.is_active_for_selectors(selectors), restrictions) + + parameters_keys = list(map(lambda p: p.key, parameters)) + + parameters_from_restrictions = { parameter.key : parameter for restriction in active_restrictions for parameter in restriction.set if parameter.key in parameters_keys } + + # replace with restriction parameters and keep original ordering + return [parameters_from_restrictions.get(p.key, p) for p in parameters] + + @staticmethod + def __difference_for_parameters(parameters, active_parameters): + parameters_keys = list(map(lambda p: p.key, parameters)) + + return list(filter(lambda p: p.key not in parameters_keys, active_parameters)) + + def as_selectors(self, project_restrictions): + non_empty_active_parameters = list(filter(lambda p: len(p.values) > 0, self.active_parameters)) + + if len(non_empty_active_parameters) > 0: + return list(ParametersSet.__as_selectors_recursive([], non_empty_active_parameters[0], non_empty_active_parameters[1:], non_empty_active_parameters, project_restrictions)) + else: + return [] + + @staticmethod + def __as_selectors_recursive(head_selectors, current_parameter, tail_parameters, all_parameters, project_restrictions): + if len(tail_parameters) == 0: + for parameter_value in current_parameter.values: + current_selector = Selector(key=current_parameter.key, value=parameter_value) + new_head_selectors = head_selectors + [current_selector] + + all_parameters_filtered = ParametersSet.__filter_parameters_using_restrictions_and_selectors(all_parameters, project_restrictions, new_head_selectors) + + parameters_selectors = { selector for parameter in all_parameters_filtered for selector in parameter.values_selectors() } + + if set(new_head_selectors).issubset(parameters_selectors): + yield new_head_selectors + + return + + for current_parameter_value in current_parameter.values: + current_selector = Selector(key=current_parameter.key, value=current_parameter_value) + new_head_selectors = head_selectors + [current_selector] + + new_tail_parameters = ParametersSet.__filter_parameters_using_restrictions_and_selectors(tail_parameters[1:], project_restrictions, new_head_selectors) + + for selectors in ParametersSet.__as_selectors_recursive(new_head_selectors, tail_parameters[0], new_tail_parameters, all_parameters, project_restrictions): + yield selectors + diff --git a/xcode/config_generator/build_options_helper/core/models/restriction.py b/xcode/config_generator/build_options_helper/core/models/restriction.py new file mode 100644 index 0000000..b0f12de --- /dev/null +++ b/xcode/config_generator/build_options_helper/core/models/restriction.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from collections import namedtuple + +from .selector import Selector +from .parameter import Parameter + +RestrictionTuple = namedtuple('RestrictionTuple', [ + 'when', + 'set', +]) + +class Restriction(RestrictionTuple): + @staticmethod + def from_dict(dict_obj): + return Restriction( + when=frozenset(map(Selector.from_dict, dict_obj["when"])), + set=list(map(Parameter.from_dict, dict_obj["set"])), + ) + + def is_active_for_selectors(self, selectors): + return not frozenset(selectors).isdisjoint(self.when) \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/core/models/selector.py b/xcode/config_generator/build_options_helper/core/models/selector.py new file mode 100644 index 0000000..fcf5a8f --- /dev/null +++ b/xcode/config_generator/build_options_helper/core/models/selector.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from collections import namedtuple + +SelectorTuple = namedtuple('SelectorTuple', [ + 'key', + 'value', +]) + +class Selector(SelectorTuple): + @staticmethod + def from_dict(dict_obj): + return Selector(**dict_obj) + + def __eq__(self, obj): + return isinstance(obj, Selector) and \ + obj.key == self.key and \ + obj.value == self.value + + def __hash__(self): + return hash((self.key, self.value)) \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/helper.py b/xcode/config_generator/build_options_helper/helper.py new file mode 100755 index 0000000..f33b1c9 --- /dev/null +++ b/xcode/config_generator/build_options_helper/helper.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from argument_parser import ArgumentParser + +import yaml + +from web_parameters_renderer import ParameterRenderer, Option +from ios_build_settings_renderer import XCConfigsRenderer, XCConfig + +from core.models import BuildParameters, ParametersSet + +import os + +parser = ArgumentParser() +parser.configure() + +args = parser.parse_args() + +output_folder = os.path.abspath(os.path.expanduser(args.output_folder)) + +build_parameters = BuildParameters.from_dict(yaml.safe_load(args.build_parameters_path)) + +parameters_set = ParametersSet(active_parameters=build_parameters.all_parameters) + +if args.platform == 'ios': + parameters_set = parameters_set.update_parameters(build_parameters.ios_parameters) +elif args.platform == 'android': + parameters_set = parameters_set.update_parameters(build_parameters.android_parameters) +else: + raise ValueError("Unknown platform {}".format(args.platform)) + +if args.render == "ios_build_settings": + xcconfigs = map(XCConfig.from_selectors, parameters_set.as_selectors(build_parameters.project_restrictions)) + XCConfigsRenderer("configs_data", xcconfigs).render_json_to_file_in_dir(output_folder) +elif args.render == "team_city_web_parameters": + parameters_set = parameters_set.update_parameters(build_parameters.ci_parameters) + active_parameters = parameters_set.active_parameters + + options_from_parameter = lambda p: [Option(key=value, value=value, enabled=True, default=p.default_value == value) for value in p.values] + + renderers = [ParameterRenderer(parameter.key, options_from_parameter(parameter)) for parameter in active_parameters] + + for r in renderers: + r.render_json_to_file_in_dir(output_folder) +else: + raise ValueError("Unknown render command {}".format(args.render)) + +print("Perameters renderer to {}".format(output_folder)) diff --git a/xcode/config_generator/build_options_helper/ios_build_settings_renderer/__init__.py b/xcode/config_generator/build_options_helper/ios_build_settings_renderer/__init__.py new file mode 100644 index 0000000..b5faf44 --- /dev/null +++ b/xcode/config_generator/build_options_helper/ios_build_settings_renderer/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from .xcconfigs_renderer import XCConfigsRenderer +from .models import XCConfig \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/ios_build_settings_renderer/models.py b/xcode/config_generator/build_options_helper/ios_build_settings_renderer/models.py new file mode 100644 index 0000000..62a5451 --- /dev/null +++ b/xcode/config_generator/build_options_helper/ios_build_settings_renderer/models.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from .raw_models import * +from core.models import Selector + +class XCConfig(XCConfigTuple): + + DISTIBUTION_TYPE_KEY = "DISTRIBUTION_TYPE" + BUILD_TYPE_KEY = "BUILD_TYPE" + + @staticmethod + def from_selectors(selectors): + selectors_dict = XCConfig.__make_dict_from_selectors(selectors) + + distibution_type_value = selectors_dict.get(XCConfig.DISTIBUTION_TYPE_KEY, None) + + is_app_store_config = distibution_type_value.lower() == "AppStore".lower() + build_type_value = selectors_dict.get(XCConfig.BUILD_TYPE_KEY, None) + build_type = distibution_type_value.lower() if is_app_store_config else build_type_value.lower() + + compatability_selectors = map(XCConfig.__modify_selector_if_needed, selectors) + + return XCConfig( + name="".join(map(lambda s: s.value, compatability_selectors)), + account_type=distibution_type_value, + build_type=build_type, + xcconfig_options=map(lambda f: f(selectors_dict), [ + XCConfigOption.swift_active_compilation_conditions, + XCConfigOption.debug_information_format, + XCConfigOption.validate_product, + XCConfigOption.enable_testability, + XCConfigOption.code_sign_identity, + XCConfigOption.gcc_optimization_level, + XCConfigOption.swift_optimization_level, + XCConfigOption.swift_compilation_mode + ]) + ) + + @staticmethod + def __make_dict_from_selectors(selectors): + # compatibility mode + return { s.key : (XCConfig.__account_type_from_distribution_type(s.value) if s.key == XCConfig.DISTIBUTION_TYPE_KEY else s.value) for s in selectors } + + # normal mode + # return { s.key : s.value for s in selectors } + + @staticmethod + def __modify_selector_if_needed(selector): + # compatibility mode + if selector.key == XCConfig.DISTIBUTION_TYPE_KEY: + return Selector(key=selector.key, value=XCConfig.__account_type_from_distribution_type(selector.value)) + else: + return selector + + # normal mode + # return selector + + @staticmethod + def __account_type_from_distribution_type(distibution_type): + if distibution_type == "Local": + return "Standard" + elif distibution_type == "Firebase": + return "Enterprise" + elif distibution_type == "Store": + return "AppStore" + + def _asdict(self): + return { + 'name': self.name, + 'account_type': self.account_type, + 'build_type': self.build_type, + 'xcconfig_options': [o._asdict() for o in self.xcconfig_options] + } + + +class XCConfigOption(XCConfigOptionTuple): + @staticmethod + def swift_active_compilation_conditions(selectors_dict): + return XCConfigOption( + key="SWIFT_ACTIVE_COMPILATION_CONDITIONS", + value=" ".join(map(lambda sv: sv.upper(), selectors_dict.values())) + ) + + @staticmethod + def debug_information_format(selectors_dict): + return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("DEBUG_INFORMATION_FORMAT", "dwarf", "dwarf-with-dsym", selectors_dict) + + @staticmethod + def validate_product(selectors_dict): + return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("VALIDATE_PRODUCT", "NO", "YES", selectors_dict) + + @staticmethod + def enable_testability(selectors_dict): + return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("ENABLE_TESTABILITY", "YES", "NO", selectors_dict) + + @staticmethod + def code_sign_identity(selectors_dict): + return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("CODE_SIGN_IDENTITY", "iPhone Developer", "iPhone Distribution", selectors_dict, "Standard") + + @staticmethod + def gcc_optimization_level(selectors_dict): + return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("GCC_OPTIMIZATION_LEVEL", "0", "s", selectors_dict) + + @staticmethod + def swift_optimization_level(selectors_dict): + return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("SWIFT_OPTIMIZATION_LEVEL", "-Onone", "-O", selectors_dict) + + @staticmethod + def swift_compilation_mode(selectors_dict): + return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("SWIFT_COMPILATION_MODE", "singlefile", "wholemodule", selectors_dict) + + @staticmethod + def __from_key_and_value_based_on_value_in_selectors(key, value_if_contains, otherwise_value, + selectors_dict, expected_value="Debug"): + return XCConfigOption( + key=key, + value=value_if_contains if expected_value.upper() in map(lambda sv: sv.upper(), selectors_dict.values()) else otherwise_value + ) diff --git a/xcode/config_generator/build_options_helper/ios_build_settings_renderer/raw_models.py b/xcode/config_generator/build_options_helper/ios_build_settings_renderer/raw_models.py new file mode 100644 index 0000000..fe922f2 --- /dev/null +++ b/xcode/config_generator/build_options_helper/ios_build_settings_renderer/raw_models.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from collections import namedtuple + +XCConfigOptionTuple = namedtuple('XCConfigOptionTuple', [ + 'key', + 'value' +]) + +XCConfigTuple = namedtuple('XCConfigTuple', [ + 'name', + 'account_type', + 'build_type', + 'xcconfig_options' +]) \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/ios_build_settings_renderer/xcconfigs_renderer.py b/xcode/config_generator/build_options_helper/ios_build_settings_renderer/xcconfigs_renderer.py new file mode 100644 index 0000000..28c4927 --- /dev/null +++ b/xcode/config_generator/build_options_helper/ios_build_settings_renderer/xcconfigs_renderer.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +import json +import os + +class XCConfigsRenderer: + def __init__(self, name, xcconfigs): + self.name = name + self.xcconfig_dicts = [xcconfig._asdict() for xcconfig in xcconfigs] + + def render_to_json(self): + return json.dumps(self.xcconfig_dicts, indent=4) + + def render_json_to_file_in_dir(self, dir_path): + file_name = "{}.json".format(self.name) + file_path = os.path.join(dir_path, file_name) + return json.dump(self.xcconfig_dicts, open(file_path, 'w'), indent=4) diff --git a/xcode/config_generator/build_options_helper/requirements.pip b/xcode/config_generator/build_options_helper/requirements.pip new file mode 100644 index 0000000..dbfc709 --- /dev/null +++ b/xcode/config_generator/build_options_helper/requirements.pip @@ -0,0 +1 @@ +PyYAML \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/test_data/build_parameters.yaml b/xcode/config_generator/build_options_helper/test_data/build_parameters.yaml new file mode 100644 index 0000000..013d09a --- /dev/null +++ b/xcode/config_generator/build_options_helper/test_data/build_parameters.yaml @@ -0,0 +1,97 @@ +all_parameters: + - key: DISTRIBUTION_TYPE + values: [Firebase, Store, Local] + default_value: Firebase + + - key: OBFUSCATE + values: [Obfuscate, NoObfuscate] + default_value: Obfuscate + + - key: SERVER_TYPE + values: [Mock, Touchin, Customer] + default_value: Mock + + - key: SERVER_ENVIRONMENT + values: [Dev, Test, Stage, Prod] + default_value: Test + + - key: SSL_PINNING + values: [WithSSLPinning, WithoutSSLPinning] + default_value: WithoutSSLPinning + + - key: TEST_PANEL + values: [WithTestPanel, WithoutTestPanel] + default_value: WithoutTestPanel + + - key: BUILD_TYPE + values: [Debug, Release] + default_value: Release + +project_restrictions: + # Mock -> Dev|Stage + - when: + - key: SERVER_TYPE + value: Mock + set: + - key: SERVER_ENVIRONMENT + values: [Dev, Stage] + default_value: Dev + + # Touchin -> Dev|Test|Stage + - when: + - key: SERVER_TYPE + value: Touchin + set: + - key: SERVER_ENVIRONMENT + values: [Dev, Test, Stage] + default_value: Test + + # Customer -> Prod + - when: + - key: SERVER_TYPE + value: Customer + set: + - key: SERVER_ENVIRONMENT + values: [Prod] + + # Store -> ObfuscateWithSSLPinningWithoutTestPanelReleaseCustomerProd + - when: + - key: DISTRIBUTION_TYPE + value: Store + set: + - key: OBFUSCATE + values: [Obfuscate] + - key: SSL_PINNING + values: [WithSSLPinning] + - key: TEST_PANEL + values: [WithoutTestPanel] + - key: BUILD_TYPE + values: [Release] + - key: SERVER_TYPE + values: [Customer] + - key: SERVER_ENVIRONMENT + values: [Prod] + + # Firebase -> Release + - when: + - key: DISTRIBUTION_TYPE + value: Firebase + set: + - key: BUILD_TYPE + values: [Release] + +ci_parameters: + - key: DISTRIBUTION_TYPE + values: [Firebase, Store] + default_value: Firebase + +ios_parameters: + # Not available + - key: OBFUSCATE + values: [] + + # Not available + - key: TEST_PANEL + values: [] + +android_parameters: [] diff --git a/xcode/config_generator/build_options_helper/web_parameters_renderer/__init__.py b/xcode/config_generator/build_options_helper/web_parameters_renderer/__init__.py new file mode 100644 index 0000000..e449d47 --- /dev/null +++ b/xcode/config_generator/build_options_helper/web_parameters_renderer/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from .parameter_renderer import ParameterRenderer +from .models import Option \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/web_parameters_renderer/models.py b/xcode/config_generator/build_options_helper/web_parameters_renderer/models.py new file mode 100644 index 0000000..0ad3103 --- /dev/null +++ b/xcode/config_generator/build_options_helper/web_parameters_renderer/models.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from .raw_models import * + +class Option(OptionTuple): + def _asdict(self): + original_dict = super(Option, self)._asdict() + # remove records with None values + return {k: v for k, v in original_dict.items() if v is not None} + + diff --git a/xcode/config_generator/build_options_helper/web_parameters_renderer/parameter_renderer.py b/xcode/config_generator/build_options_helper/web_parameters_renderer/parameter_renderer.py new file mode 100644 index 0000000..189e38f --- /dev/null +++ b/xcode/config_generator/build_options_helper/web_parameters_renderer/parameter_renderer.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +import json +import os + +class ParameterRenderer: + def __init__(self, name, options): + self.name = name + self.options_dict = {"options": [option._asdict() for option in options]} + + def render_to_json(self): + return json.dumps(self.options_dict, indent=4) + + def render_json_to_file_in_dir(self, dir_path): + file_name = "{}.json".format(self.name) + file_path = os.path.join(dir_path, file_name) + return json.dump(self.options_dict, open(file_path, 'w'), indent=4) + diff --git a/xcode/config_generator/build_options_helper/web_parameters_renderer/raw_models.py b/xcode/config_generator/build_options_helper/web_parameters_renderer/raw_models.py new file mode 100644 index 0000000..3d973cb --- /dev/null +++ b/xcode/config_generator/build_options_helper/web_parameters_renderer/raw_models.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from collections import namedtuple + +OptionTuple = namedtuple('OptionTuple', [ + 'key', + 'value', + 'enabled', + 'default' +]) \ No newline at end of file diff --git a/xcode/config_generator/custom_settings.json b/xcode/config_generator/custom_settings.json deleted file mode 100644 index a190324..0000000 --- a/xcode/config_generator/custom_settings.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "targets": [ - { - "YOUR_TARGET_NAME": { - "Standard": { - "PROVISIONING_PROFILE_SPECIFIER": "", - "PRODUCT_BUNDLE_IDENTIFIER": "", - "CODE_SIGN_ENTITLEMENTS": "" - }, - - "Enterprise": { - "PROVISIONING_PROFILE_SPECIFIER": "", - "PRODUCT_BUNDLE_IDENTIFIER": "", - "CODE_SIGN_ENTITLEMENTS": "" - }, - - "AppStore": { - "DEVELOPMENT_TEAM": "", - "PRODUCT_BUNDLE_IDENTIFIER": "", - "CODE_SIGN_ENTITLEMENTS": "" - } - } - } - ] -} diff --git a/xcode/config_generator/example_settings.yaml b/xcode/config_generator/example_settings.yaml new file mode 100644 index 0000000..608981a --- /dev/null +++ b/xcode/config_generator/example_settings.yaml @@ -0,0 +1,27 @@ +targets: + TestProject: + development: + PRODUCT_BUNDLE_IDENTIFIER: "ru.touchin.testproject" + PROVISIONING_PROFILE_SPECIFIER: "TestProjectDev" + CODE_SIGN_ENTITLEMENTS: "TestProject/Standard.entitlements" + enterprise: + PRODUCT_BUNDLE_IDENTIFIER: "com.touchin.testproject" + PROVISIONING_PROFILE_SPECIFIER: "TestProjectEnterprise" + CODE_SIGN_ENTITLEMENTS: "TestProject/Enterprise.entitlements" + appstore: + PRODUCT_BUNDLE_IDENTIFIER: "ru.customer.domain" + PROVISIONING_PROFILE_SPECIFIER: "TestProjectAppStore" + CODE_SIGN_ENTITLEMENTS: "TestProject/Production.entitlements" + +types: + development: + apple_id: "apple@touchin.ru" + team_id: "**********" + itc_team_id: "**********" + enterprise: + apple_id: "enterpriseapple@touchin.ru" + team_id: "**********" + appstore: + apple_id: "apple@touchin.ru" + team_id: "**********" + itc_team_id: "**********" \ No newline at end of file diff --git a/xcode/config_generator/gen_configurations.py b/xcode/config_generator/gen_configurations.py deleted file mode 100644 index 22845ed..0000000 --- a/xcode/config_generator/gen_configurations.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from itertools import chain -import json - -distribution_options = ["Enterprise", "Standard"] -server_type_options = ["Mock", "Touchin", "Customer"] -server_environment_options = ["Dev", "Test", "Stage", "Prod"] -ssl_pinning_options = ["WithSSLPinning", "WithoutSSLPinning"] -build_type_options = ["Debug", "Release"] - -all_options = [ - distribution_options, - server_type_options, - server_environment_options, - ssl_pinning_options, - build_type_options -] - -def combine_string_with_options(all_options, string="", applied_options=[]): - if len(all_options) == 0: - yield string, applied_options - return - - for current_option in chain.from_iterable(all_options[:1]): - for result_tuple in combine_string_with_options(all_options[1:], string + current_option, applied_options + [current_option]): - yield result_tuple - - yield ("AppStoreRelease", ['AppStore', 'Customer', 'Prod', 'WithSSLPinning', 'Release']) - -def make_config_dict(args): - config_name, applied_options = args - - if "Enterprise" in applied_options: - account_type = "Enterprise" - elif "Standard" in applied_options: - account_type = "Standard" - else: - account_type = "AppStore" - - if "Debug" in applied_options: - build_type = "debug" - elif "AppStore" in applied_options: - build_type = "appstore" - else: - build_type = "release" - - return { - "name": config_name, - "build_type": build_type, - "account_type": account_type, - "xcconfig_options": [ - { - "key": "SWIFT_ACTIVE_COMPILATION_CONDITIONS", - "value": " ".join(map(lambda option: option.upper(), applied_options)) - }, - { - "key": "DEBUG_INFORMATION_FORMAT", - "value": "dwarf" if "Debug" in applied_options else "dwarf-with-dsym" - }, - { - "key": "VALIDATE_PRODUCT", - "value": "NO" if "Debug" in applied_options else "YES" - }, - { - "key": "ENABLE_TESTABILITY", - "value": "YES" if "Debug" in applied_options else "NO" - }, - { - "key": "CODE_SIGN_IDENTITY", - "value": "iPhone Developer" if account_type == "Standard" else "iPhone Distribution" - }, - { - "key": "GCC_OPTIMIZATION_LEVEL", - "value": "0" if "Debug" in applied_options else "s" - }, - { - "key": "SWIFT_OPTIMIZATION_LEVEL", - "value": "-Onone" if "Debug" in applied_options else "-O" - }, - { - "key": "SWIFT_COMPILATION_MODE", - "value": "singlefile" if "Debug" in applied_options else "wholemodule" - } - ] - } - - -config_dicts = map(make_config_dict, combine_string_with_options(all_options)) - -print(json.dumps({"configurations": config_dicts}, indent=4)) diff --git a/xcode/config_generator/render_xcconfigs.rb b/xcode/config_generator/render_xcconfigs.rb index dd041d8..197c382 100755 --- a/xcode/config_generator/render_xcconfigs.rb +++ b/xcode/config_generator/render_xcconfigs.rb @@ -4,7 +4,7 @@ require 'yaml' # Usage: render_xcconfigs.rb # -# Result: Adds .xcconfig files to $configs_folder_name directory. +# Result: Adds .xcconfig files to $configs_folder_name directory. # Files are only being added and changed, not removed! # It is recommended to remove old .xcconfig files before running this script. @@ -21,14 +21,15 @@ end # Input files paths configurations_file_path = ARGV[0] temp_configs_data_file_path = "configs_data.json".in_current_dir -generator_path = "gen_configurations.py".in_current_dir +generator_path = "build_options_helper/helper.py".in_current_dir template_path = "target_xcconfig.mustache".in_current_dir +build_parameters_path = ARGV[1] || "build_parameters.yaml".in_current_dir # Create config directory if needed Dir.mkdir($configs_folder_name) unless Dir.exist?($configs_folder_name) # Call python script and generate configs to config file -system("python #{generator_path} > #{temp_configs_data_file_path}") +system("python #{generator_path} -bp #{build_parameters_path} -o . -r ios_build_settings -p ios") # Open settings, configurations and template files target_xcconfig_tempate = File.read(template_path) @@ -53,7 +54,7 @@ def distribution_type_of(account_type) when "AppStore" "appstore" else - raise "Error: Unsupported distribution type #{account_type}" + raise "Error: Unsupported distribution type #{account_type}" end end @@ -77,16 +78,16 @@ end def generate_google_service_info_plist_path(google_service_info_plist_key, target_name, distribution_type) google_service_info_plist_path = target_name + "/Resources/" - + path_suffix = case distribution_type when "development" "Standard-GoogleService-Info.plist" when "enterprise" "Enterprise-GoogleService-Info.plist" - else + else "AppStore-GoogleService-Info.plist" end - + return config_option(google_service_info_plist_key, google_service_info_plist_path + path_suffix) end @@ -110,7 +111,7 @@ def generate_missing_properties(target_name, properties, distribution_type) unless properties.key?(provisioning_key) result.append(generate_provisioning_profile(provisioning_key, bundle_id, distribution_type)) end - + unless properties.key?(google_service_info_plist_key) result.append(generate_google_service_info_plist_path(google_service_info_plist_key, target_name, distribution_type)) end @@ -122,11 +123,11 @@ end targets.each do |target_name, target| # Need open everytime, because script make some changes only for this target - configs = JSON.load(File.open(temp_configs_data_file_path))["configurations"] + configs = JSON.load(File.open(temp_configs_data_file_path)) # Run through all configs configs.each do |config| - + # Take default values distribution_type = distribution_type_of(config["account_type"]) properties = target[distribution_type] From 8711d20e721618ad1a76305d8c5896b5eddced33 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Mon, 15 Jun 2020 13:05:06 +0300 Subject: [PATCH 2/2] Replace build_options_helper with submodule --- .gitmodules | 3 + xcode/config_generator/build_options_helper | 1 + .../build_options_helper/.gitignore | 129 ----------- .../build_options_helper/LICENSE | 201 ------------------ .../build_options_helper/README.md | 2 - .../build_options_helper/argument_parser.py | 25 --- .../build_options_helper/core/__init__.py | 3 - .../core/models/__init__.py | 9 - .../core/models/build_parameters.py | 27 --- .../core/models/parameter.py | 25 --- .../core/models/parameters_set.py | 77 ------- .../core/models/restriction.py | 24 --- .../core/models/selector.py | 23 -- .../build_options_helper/helper.py | 51 ----- .../ios_build_settings_renderer/__init__.py | 6 - .../ios_build_settings_renderer/models.py | 120 ----------- .../ios_build_settings_renderer/raw_models.py | 17 -- .../xcconfigs_renderer.py | 19 -- .../build_options_helper/requirements.pip | 1 - .../test_data/build_parameters.yaml | 97 --------- .../web_parameters_renderer/__init__.py | 6 - .../web_parameters_renderer/models.py | 13 -- .../parameter_renderer.py | 20 -- .../web_parameters_renderer/raw_models.py | 12 -- 24 files changed, 4 insertions(+), 907 deletions(-) create mode 100644 .gitmodules create mode 160000 xcode/config_generator/build_options_helper delete mode 100644 xcode/config_generator/build_options_helper/.gitignore delete mode 100644 xcode/config_generator/build_options_helper/LICENSE delete mode 100644 xcode/config_generator/build_options_helper/README.md delete mode 100644 xcode/config_generator/build_options_helper/argument_parser.py delete mode 100644 xcode/config_generator/build_options_helper/core/__init__.py delete mode 100644 xcode/config_generator/build_options_helper/core/models/__init__.py delete mode 100644 xcode/config_generator/build_options_helper/core/models/build_parameters.py delete mode 100644 xcode/config_generator/build_options_helper/core/models/parameter.py delete mode 100644 xcode/config_generator/build_options_helper/core/models/parameters_set.py delete mode 100644 xcode/config_generator/build_options_helper/core/models/restriction.py delete mode 100644 xcode/config_generator/build_options_helper/core/models/selector.py delete mode 100755 xcode/config_generator/build_options_helper/helper.py delete mode 100644 xcode/config_generator/build_options_helper/ios_build_settings_renderer/__init__.py delete mode 100644 xcode/config_generator/build_options_helper/ios_build_settings_renderer/models.py delete mode 100644 xcode/config_generator/build_options_helper/ios_build_settings_renderer/raw_models.py delete mode 100644 xcode/config_generator/build_options_helper/ios_build_settings_renderer/xcconfigs_renderer.py delete mode 100644 xcode/config_generator/build_options_helper/requirements.pip delete mode 100644 xcode/config_generator/build_options_helper/test_data/build_parameters.yaml delete mode 100644 xcode/config_generator/build_options_helper/web_parameters_renderer/__init__.py delete mode 100644 xcode/config_generator/build_options_helper/web_parameters_renderer/models.py delete mode 100644 xcode/config_generator/build_options_helper/web_parameters_renderer/parameter_renderer.py delete mode 100644 xcode/config_generator/build_options_helper/web_parameters_renderer/raw_models.py diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..48fee14 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "build_options_helper"] + path = xcode/config_generator/build_options_helper + url = https://github.com/petropavel13/build_options_helper diff --git a/xcode/config_generator/build_options_helper b/xcode/config_generator/build_options_helper new file mode 160000 index 0000000..957fb64 --- /dev/null +++ b/xcode/config_generator/build_options_helper @@ -0,0 +1 @@ +Subproject commit 957fb642a4348923377a625b521d1812620384ba diff --git a/xcode/config_generator/build_options_helper/.gitignore b/xcode/config_generator/build_options_helper/.gitignore deleted file mode 100644 index b6e4761..0000000 --- a/xcode/config_generator/build_options_helper/.gitignore +++ /dev/null @@ -1,129 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -pip-wheel-metadata/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -.python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ diff --git a/xcode/config_generator/build_options_helper/LICENSE b/xcode/config_generator/build_options_helper/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/xcode/config_generator/build_options_helper/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/xcode/config_generator/build_options_helper/README.md b/xcode/config_generator/build_options_helper/README.md deleted file mode 100644 index 78a5670..0000000 --- a/xcode/config_generator/build_options_helper/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# build_options_helper -An utility to work with build options diff --git a/xcode/config_generator/build_options_helper/argument_parser.py b/xcode/config_generator/build_options_helper/argument_parser.py deleted file mode 100644 index d56499f..0000000 --- a/xcode/config_generator/build_options_helper/argument_parser.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -import argparse -import os -import tempfile - -class writeable_dir(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - prospective_dir = values - - if not os.path.isdir(prospective_dir): - raise argparse.ArgumentTypeError("writeable_dir:{0} is not a valid path".format(prospective_dir)) - if os.access(prospective_dir, os.W_OK): - setattr(namespace, self.dest, prospective_dir) - else: - raise argparse.ArgumentTypeError("writeable_dir:{0} is not a writeable dir".format(prospective_dir)) - -class ArgumentParser(argparse.ArgumentParser): - def configure(self): - self.add_argument('--build-parameters-path', '-bp', default="build_parameters.yaml", type=open, required=True) - self.add_argument('--output-folder', '-o', action=writeable_dir, default=tempfile.mkdtemp(), required=True) - self.add_argument('--render', '-r', choices=['ios_build_settings', 'team_city_web_parameters'], type=str, required=True) - self.add_argument('--platform', '-p', choices=['ios', 'android'], type=str, required=True) \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/core/__init__.py b/xcode/config_generator/build_options_helper/core/__init__.py deleted file mode 100644 index 85f54f0..0000000 --- a/xcode/config_generator/build_options_helper/core/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/core/models/__init__.py b/xcode/config_generator/build_options_helper/core/models/__init__.py deleted file mode 100644 index 28ba362..0000000 --- a/xcode/config_generator/build_options_helper/core/models/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from .selector import Selector -from .restriction import Restriction -from .parameter import Parameter -from .build_parameters import BuildParameters -from .parameters_set import ParametersSet diff --git a/xcode/config_generator/build_options_helper/core/models/build_parameters.py b/xcode/config_generator/build_options_helper/core/models/build_parameters.py deleted file mode 100644 index 128ee8f..0000000 --- a/xcode/config_generator/build_options_helper/core/models/build_parameters.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from collections import namedtuple - -from .restriction import Restriction -from .parameter import Parameter - -BuildParametersTuple = namedtuple('BuildParametersTuple', [ - 'all_parameters', - 'project_restrictions', - 'ci_parameters', - 'ios_parameters', - 'android_parameters', -]) - -class BuildParameters(BuildParametersTuple): - @staticmethod - def from_dict(dict_obj): - return BuildParameters( - all_parameters=list(map(Parameter.from_dict, dict_obj["all_parameters"])), - project_restrictions=list(map(Restriction.from_dict, dict_obj["project_restrictions"])), - ci_parameters=list(map(Parameter.from_dict, dict_obj["ci_parameters"])), - ios_parameters=list(map(Parameter.from_dict, dict_obj["ios_parameters"])), - android_parameters=list(map(Parameter.from_dict, dict_obj["android_parameters"])) - ) \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/core/models/parameter.py b/xcode/config_generator/build_options_helper/core/models/parameter.py deleted file mode 100644 index 38e780d..0000000 --- a/xcode/config_generator/build_options_helper/core/models/parameter.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from collections import namedtuple - -from .selector import Selector - -ParameterTuple = namedtuple('ParameterTuple', [ - 'key', - 'values', - 'default_value', -]) - -class Parameter(ParameterTuple): - @staticmethod - def from_dict(dict_obj): - return Parameter( - key=dict_obj["key"], - values=dict_obj["values"], - default_value=dict_obj.get("default_value") - ) - - def values_selectors(self): - return [Selector(key=self.key, value=value) for value in self.values] \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/core/models/parameters_set.py b/xcode/config_generator/build_options_helper/core/models/parameters_set.py deleted file mode 100644 index 034023d..0000000 --- a/xcode/config_generator/build_options_helper/core/models/parameters_set.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from collections import namedtuple - -from .selector import Selector - -ParametersSetTuple = namedtuple('ParametersSetTuple', [ - 'active_parameters', -]) - -class ParametersSet(ParametersSetTuple): - def filter_using_restrictions_and_selectors(self, restrictions, selectors): - new_parameters = ParametersSet.__filter_parameters_using_restrictions_and_selectors(self.active_parameters, restrictions, selectors) - - return ParametersSet(active_parameters=new_parameters) - - def update_parameters(self, parameters): - parameters_dict = { p.key : p for p in parameters } - parameters_dict_keys = parameters_dict.keys() - - # update & keep ordering - new_active_parameters = [parameters_dict[p.key] if p.key in parameters_dict_keys else p for p in self.active_parameters] - - return ParametersSet(active_parameters=new_active_parameters) - - @staticmethod - def __filter_parameters_using_restrictions_and_selectors(parameters, restrictions, selectors): - active_restrictions = filter(lambda r: r.is_active_for_selectors(selectors), restrictions) - - parameters_keys = list(map(lambda p: p.key, parameters)) - - parameters_from_restrictions = { parameter.key : parameter for restriction in active_restrictions for parameter in restriction.set if parameter.key in parameters_keys } - - # replace with restriction parameters and keep original ordering - return [parameters_from_restrictions.get(p.key, p) for p in parameters] - - @staticmethod - def __difference_for_parameters(parameters, active_parameters): - parameters_keys = list(map(lambda p: p.key, parameters)) - - return list(filter(lambda p: p.key not in parameters_keys, active_parameters)) - - def as_selectors(self, project_restrictions): - non_empty_active_parameters = list(filter(lambda p: len(p.values) > 0, self.active_parameters)) - - if len(non_empty_active_parameters) > 0: - return list(ParametersSet.__as_selectors_recursive([], non_empty_active_parameters[0], non_empty_active_parameters[1:], non_empty_active_parameters, project_restrictions)) - else: - return [] - - @staticmethod - def __as_selectors_recursive(head_selectors, current_parameter, tail_parameters, all_parameters, project_restrictions): - if len(tail_parameters) == 0: - for parameter_value in current_parameter.values: - current_selector = Selector(key=current_parameter.key, value=parameter_value) - new_head_selectors = head_selectors + [current_selector] - - all_parameters_filtered = ParametersSet.__filter_parameters_using_restrictions_and_selectors(all_parameters, project_restrictions, new_head_selectors) - - parameters_selectors = { selector for parameter in all_parameters_filtered for selector in parameter.values_selectors() } - - if set(new_head_selectors).issubset(parameters_selectors): - yield new_head_selectors - - return - - for current_parameter_value in current_parameter.values: - current_selector = Selector(key=current_parameter.key, value=current_parameter_value) - new_head_selectors = head_selectors + [current_selector] - - new_tail_parameters = ParametersSet.__filter_parameters_using_restrictions_and_selectors(tail_parameters[1:], project_restrictions, new_head_selectors) - - for selectors in ParametersSet.__as_selectors_recursive(new_head_selectors, tail_parameters[0], new_tail_parameters, all_parameters, project_restrictions): - yield selectors - diff --git a/xcode/config_generator/build_options_helper/core/models/restriction.py b/xcode/config_generator/build_options_helper/core/models/restriction.py deleted file mode 100644 index b0f12de..0000000 --- a/xcode/config_generator/build_options_helper/core/models/restriction.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from collections import namedtuple - -from .selector import Selector -from .parameter import Parameter - -RestrictionTuple = namedtuple('RestrictionTuple', [ - 'when', - 'set', -]) - -class Restriction(RestrictionTuple): - @staticmethod - def from_dict(dict_obj): - return Restriction( - when=frozenset(map(Selector.from_dict, dict_obj["when"])), - set=list(map(Parameter.from_dict, dict_obj["set"])), - ) - - def is_active_for_selectors(self, selectors): - return not frozenset(selectors).isdisjoint(self.when) \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/core/models/selector.py b/xcode/config_generator/build_options_helper/core/models/selector.py deleted file mode 100644 index fcf5a8f..0000000 --- a/xcode/config_generator/build_options_helper/core/models/selector.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from collections import namedtuple - -SelectorTuple = namedtuple('SelectorTuple', [ - 'key', - 'value', -]) - -class Selector(SelectorTuple): - @staticmethod - def from_dict(dict_obj): - return Selector(**dict_obj) - - def __eq__(self, obj): - return isinstance(obj, Selector) and \ - obj.key == self.key and \ - obj.value == self.value - - def __hash__(self): - return hash((self.key, self.value)) \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/helper.py b/xcode/config_generator/build_options_helper/helper.py deleted file mode 100755 index f33b1c9..0000000 --- a/xcode/config_generator/build_options_helper/helper.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from argument_parser import ArgumentParser - -import yaml - -from web_parameters_renderer import ParameterRenderer, Option -from ios_build_settings_renderer import XCConfigsRenderer, XCConfig - -from core.models import BuildParameters, ParametersSet - -import os - -parser = ArgumentParser() -parser.configure() - -args = parser.parse_args() - -output_folder = os.path.abspath(os.path.expanduser(args.output_folder)) - -build_parameters = BuildParameters.from_dict(yaml.safe_load(args.build_parameters_path)) - -parameters_set = ParametersSet(active_parameters=build_parameters.all_parameters) - -if args.platform == 'ios': - parameters_set = parameters_set.update_parameters(build_parameters.ios_parameters) -elif args.platform == 'android': - parameters_set = parameters_set.update_parameters(build_parameters.android_parameters) -else: - raise ValueError("Unknown platform {}".format(args.platform)) - -if args.render == "ios_build_settings": - xcconfigs = map(XCConfig.from_selectors, parameters_set.as_selectors(build_parameters.project_restrictions)) - XCConfigsRenderer("configs_data", xcconfigs).render_json_to_file_in_dir(output_folder) -elif args.render == "team_city_web_parameters": - parameters_set = parameters_set.update_parameters(build_parameters.ci_parameters) - active_parameters = parameters_set.active_parameters - - options_from_parameter = lambda p: [Option(key=value, value=value, enabled=True, default=p.default_value == value) for value in p.values] - - renderers = [ParameterRenderer(parameter.key, options_from_parameter(parameter)) for parameter in active_parameters] - - for r in renderers: - r.render_json_to_file_in_dir(output_folder) -else: - raise ValueError("Unknown render command {}".format(args.render)) - -print("Perameters renderer to {}".format(output_folder)) diff --git a/xcode/config_generator/build_options_helper/ios_build_settings_renderer/__init__.py b/xcode/config_generator/build_options_helper/ios_build_settings_renderer/__init__.py deleted file mode 100644 index b5faf44..0000000 --- a/xcode/config_generator/build_options_helper/ios_build_settings_renderer/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from .xcconfigs_renderer import XCConfigsRenderer -from .models import XCConfig \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/ios_build_settings_renderer/models.py b/xcode/config_generator/build_options_helper/ios_build_settings_renderer/models.py deleted file mode 100644 index 62a5451..0000000 --- a/xcode/config_generator/build_options_helper/ios_build_settings_renderer/models.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from .raw_models import * -from core.models import Selector - -class XCConfig(XCConfigTuple): - - DISTIBUTION_TYPE_KEY = "DISTRIBUTION_TYPE" - BUILD_TYPE_KEY = "BUILD_TYPE" - - @staticmethod - def from_selectors(selectors): - selectors_dict = XCConfig.__make_dict_from_selectors(selectors) - - distibution_type_value = selectors_dict.get(XCConfig.DISTIBUTION_TYPE_KEY, None) - - is_app_store_config = distibution_type_value.lower() == "AppStore".lower() - build_type_value = selectors_dict.get(XCConfig.BUILD_TYPE_KEY, None) - build_type = distibution_type_value.lower() if is_app_store_config else build_type_value.lower() - - compatability_selectors = map(XCConfig.__modify_selector_if_needed, selectors) - - return XCConfig( - name="".join(map(lambda s: s.value, compatability_selectors)), - account_type=distibution_type_value, - build_type=build_type, - xcconfig_options=map(lambda f: f(selectors_dict), [ - XCConfigOption.swift_active_compilation_conditions, - XCConfigOption.debug_information_format, - XCConfigOption.validate_product, - XCConfigOption.enable_testability, - XCConfigOption.code_sign_identity, - XCConfigOption.gcc_optimization_level, - XCConfigOption.swift_optimization_level, - XCConfigOption.swift_compilation_mode - ]) - ) - - @staticmethod - def __make_dict_from_selectors(selectors): - # compatibility mode - return { s.key : (XCConfig.__account_type_from_distribution_type(s.value) if s.key == XCConfig.DISTIBUTION_TYPE_KEY else s.value) for s in selectors } - - # normal mode - # return { s.key : s.value for s in selectors } - - @staticmethod - def __modify_selector_if_needed(selector): - # compatibility mode - if selector.key == XCConfig.DISTIBUTION_TYPE_KEY: - return Selector(key=selector.key, value=XCConfig.__account_type_from_distribution_type(selector.value)) - else: - return selector - - # normal mode - # return selector - - @staticmethod - def __account_type_from_distribution_type(distibution_type): - if distibution_type == "Local": - return "Standard" - elif distibution_type == "Firebase": - return "Enterprise" - elif distibution_type == "Store": - return "AppStore" - - def _asdict(self): - return { - 'name': self.name, - 'account_type': self.account_type, - 'build_type': self.build_type, - 'xcconfig_options': [o._asdict() for o in self.xcconfig_options] - } - - -class XCConfigOption(XCConfigOptionTuple): - @staticmethod - def swift_active_compilation_conditions(selectors_dict): - return XCConfigOption( - key="SWIFT_ACTIVE_COMPILATION_CONDITIONS", - value=" ".join(map(lambda sv: sv.upper(), selectors_dict.values())) - ) - - @staticmethod - def debug_information_format(selectors_dict): - return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("DEBUG_INFORMATION_FORMAT", "dwarf", "dwarf-with-dsym", selectors_dict) - - @staticmethod - def validate_product(selectors_dict): - return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("VALIDATE_PRODUCT", "NO", "YES", selectors_dict) - - @staticmethod - def enable_testability(selectors_dict): - return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("ENABLE_TESTABILITY", "YES", "NO", selectors_dict) - - @staticmethod - def code_sign_identity(selectors_dict): - return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("CODE_SIGN_IDENTITY", "iPhone Developer", "iPhone Distribution", selectors_dict, "Standard") - - @staticmethod - def gcc_optimization_level(selectors_dict): - return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("GCC_OPTIMIZATION_LEVEL", "0", "s", selectors_dict) - - @staticmethod - def swift_optimization_level(selectors_dict): - return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("SWIFT_OPTIMIZATION_LEVEL", "-Onone", "-O", selectors_dict) - - @staticmethod - def swift_compilation_mode(selectors_dict): - return XCConfigOption.__from_key_and_value_based_on_value_in_selectors("SWIFT_COMPILATION_MODE", "singlefile", "wholemodule", selectors_dict) - - @staticmethod - def __from_key_and_value_based_on_value_in_selectors(key, value_if_contains, otherwise_value, - selectors_dict, expected_value="Debug"): - return XCConfigOption( - key=key, - value=value_if_contains if expected_value.upper() in map(lambda sv: sv.upper(), selectors_dict.values()) else otherwise_value - ) diff --git a/xcode/config_generator/build_options_helper/ios_build_settings_renderer/raw_models.py b/xcode/config_generator/build_options_helper/ios_build_settings_renderer/raw_models.py deleted file mode 100644 index fe922f2..0000000 --- a/xcode/config_generator/build_options_helper/ios_build_settings_renderer/raw_models.py +++ /dev/null @@ -1,17 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from collections import namedtuple - -XCConfigOptionTuple = namedtuple('XCConfigOptionTuple', [ - 'key', - 'value' -]) - -XCConfigTuple = namedtuple('XCConfigTuple', [ - 'name', - 'account_type', - 'build_type', - 'xcconfig_options' -]) \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/ios_build_settings_renderer/xcconfigs_renderer.py b/xcode/config_generator/build_options_helper/ios_build_settings_renderer/xcconfigs_renderer.py deleted file mode 100644 index 28c4927..0000000 --- a/xcode/config_generator/build_options_helper/ios_build_settings_renderer/xcconfigs_renderer.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -import json -import os - -class XCConfigsRenderer: - def __init__(self, name, xcconfigs): - self.name = name - self.xcconfig_dicts = [xcconfig._asdict() for xcconfig in xcconfigs] - - def render_to_json(self): - return json.dumps(self.xcconfig_dicts, indent=4) - - def render_json_to_file_in_dir(self, dir_path): - file_name = "{}.json".format(self.name) - file_path = os.path.join(dir_path, file_name) - return json.dump(self.xcconfig_dicts, open(file_path, 'w'), indent=4) diff --git a/xcode/config_generator/build_options_helper/requirements.pip b/xcode/config_generator/build_options_helper/requirements.pip deleted file mode 100644 index dbfc709..0000000 --- a/xcode/config_generator/build_options_helper/requirements.pip +++ /dev/null @@ -1 +0,0 @@ -PyYAML \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/test_data/build_parameters.yaml b/xcode/config_generator/build_options_helper/test_data/build_parameters.yaml deleted file mode 100644 index 013d09a..0000000 --- a/xcode/config_generator/build_options_helper/test_data/build_parameters.yaml +++ /dev/null @@ -1,97 +0,0 @@ -all_parameters: - - key: DISTRIBUTION_TYPE - values: [Firebase, Store, Local] - default_value: Firebase - - - key: OBFUSCATE - values: [Obfuscate, NoObfuscate] - default_value: Obfuscate - - - key: SERVER_TYPE - values: [Mock, Touchin, Customer] - default_value: Mock - - - key: SERVER_ENVIRONMENT - values: [Dev, Test, Stage, Prod] - default_value: Test - - - key: SSL_PINNING - values: [WithSSLPinning, WithoutSSLPinning] - default_value: WithoutSSLPinning - - - key: TEST_PANEL - values: [WithTestPanel, WithoutTestPanel] - default_value: WithoutTestPanel - - - key: BUILD_TYPE - values: [Debug, Release] - default_value: Release - -project_restrictions: - # Mock -> Dev|Stage - - when: - - key: SERVER_TYPE - value: Mock - set: - - key: SERVER_ENVIRONMENT - values: [Dev, Stage] - default_value: Dev - - # Touchin -> Dev|Test|Stage - - when: - - key: SERVER_TYPE - value: Touchin - set: - - key: SERVER_ENVIRONMENT - values: [Dev, Test, Stage] - default_value: Test - - # Customer -> Prod - - when: - - key: SERVER_TYPE - value: Customer - set: - - key: SERVER_ENVIRONMENT - values: [Prod] - - # Store -> ObfuscateWithSSLPinningWithoutTestPanelReleaseCustomerProd - - when: - - key: DISTRIBUTION_TYPE - value: Store - set: - - key: OBFUSCATE - values: [Obfuscate] - - key: SSL_PINNING - values: [WithSSLPinning] - - key: TEST_PANEL - values: [WithoutTestPanel] - - key: BUILD_TYPE - values: [Release] - - key: SERVER_TYPE - values: [Customer] - - key: SERVER_ENVIRONMENT - values: [Prod] - - # Firebase -> Release - - when: - - key: DISTRIBUTION_TYPE - value: Firebase - set: - - key: BUILD_TYPE - values: [Release] - -ci_parameters: - - key: DISTRIBUTION_TYPE - values: [Firebase, Store] - default_value: Firebase - -ios_parameters: - # Not available - - key: OBFUSCATE - values: [] - - # Not available - - key: TEST_PANEL - values: [] - -android_parameters: [] diff --git a/xcode/config_generator/build_options_helper/web_parameters_renderer/__init__.py b/xcode/config_generator/build_options_helper/web_parameters_renderer/__init__.py deleted file mode 100644 index e449d47..0000000 --- a/xcode/config_generator/build_options_helper/web_parameters_renderer/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from .parameter_renderer import ParameterRenderer -from .models import Option \ No newline at end of file diff --git a/xcode/config_generator/build_options_helper/web_parameters_renderer/models.py b/xcode/config_generator/build_options_helper/web_parameters_renderer/models.py deleted file mode 100644 index 0ad3103..0000000 --- a/xcode/config_generator/build_options_helper/web_parameters_renderer/models.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from .raw_models import * - -class Option(OptionTuple): - def _asdict(self): - original_dict = super(Option, self)._asdict() - # remove records with None values - return {k: v for k, v in original_dict.items() if v is not None} - - diff --git a/xcode/config_generator/build_options_helper/web_parameters_renderer/parameter_renderer.py b/xcode/config_generator/build_options_helper/web_parameters_renderer/parameter_renderer.py deleted file mode 100644 index 189e38f..0000000 --- a/xcode/config_generator/build_options_helper/web_parameters_renderer/parameter_renderer.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -import json -import os - -class ParameterRenderer: - def __init__(self, name, options): - self.name = name - self.options_dict = {"options": [option._asdict() for option in options]} - - def render_to_json(self): - return json.dumps(self.options_dict, indent=4) - - def render_json_to_file_in_dir(self, dir_path): - file_name = "{}.json".format(self.name) - file_path = os.path.join(dir_path, file_name) - return json.dump(self.options_dict, open(file_path, 'w'), indent=4) - diff --git a/xcode/config_generator/build_options_helper/web_parameters_renderer/raw_models.py b/xcode/config_generator/build_options_helper/web_parameters_renderer/raw_models.py deleted file mode 100644 index 3d973cb..0000000 --- a/xcode/config_generator/build_options_helper/web_parameters_renderer/raw_models.py +++ /dev/null @@ -1,12 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals # python 2/3 support - -from collections import namedtuple - -OptionTuple = namedtuple('OptionTuple', [ - 'key', - 'value', - 'enabled', - 'default' -]) \ No newline at end of file