uberpoet/genproj.py (118 lines of code) (raw):
# Copyright (c) 2018 Uber Technologies, Inc.
#
# 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.
from __future__ import absolute_import
import argparse
import json
import logging
import sys
import time
from os.path import join
from . import blazeprojectgen, commandlineutil, cpprojectgen
from .moduletree import ModuleGenType
class GenProjCommandLine(object):
@staticmethod
def make_args(args):
"""Parses command line arguments"""
arg_desc = 'Generate a fake test project with many modules'
parser = argparse.ArgumentParser(description=arg_desc)
parser.add_argument('-o', '--output_directory', required=True, help='Where the mock project should be output.')
parser.add_argument(
'-pgt',
'--project_generator_type',
choices=['buck', 'bazel', 'cocoapods'],
default='buck',
required=False,
help='The project generator type to use. Supported types are Buck, Bazel and CocoaPods. Default is `buck`')
parser.add_argument(
'-bmp',
'--blaze_module_path',
help='The root of the Buck or Bazel dependency path of the generated code. Only used if Buck or Bazel '
'generator type is used.')
parser.add_argument(
'-gt',
'--gen_type',
required=True,
choices=ModuleGenType.enum_list(),
help='What kind of mock app generation you want. See layer_types.md for a description of graph types.')
parser.add_argument(
'-wmo',
'--use_wmo',
default=False,
help='Whether or not to use whole module optimization when building swift modules.')
parser.add_argument(
'-udl',
'--use_dynamic_linking',
default=False,
help='Whether or not to generate a project in which the modules are dynamically linked. By default all '
'projects use static linking. This option is currently used only by the CocoaPods generator.')
parser.add_argument(
'--print_dependency_graph',
default=False,
help='If true, prints out the dependency edge list and exits instead of generating an application.')
# CocoaPods specific options
parser.add_argument(
'--cocoapods_use_deterministic_uuids',
default=True,
help='Whether to use deterministic uuids within the CocoaPods generated project. Defaults to `true`.')
parser.add_argument(
'--cocoapods_generate_multiple_pod_projects',
default=False,
help='Whether to generate multiple pods projects. Defaults to `false`.')
commandlineutil.AppGenerationConfig.add_app_gen_options(parser)
args = parser.parse_args(args)
commandlineutil.AppGenerationConfig.validate_app_gen_options(args)
return args
def main(self, args=None):
if args is None:
args = sys.argv[1:]
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(funcName)s: %(message)s')
start = time.time()
args = self.make_args(args)
graph_config = commandlineutil.AppGenerationConfig()
graph_config.pull_from_args(args)
app_node, node_list = commandlineutil.gen_graph(args.gen_type, graph_config)
if args.print_dependency_graph:
print_nodes(node_list)
exit(0)
commandlineutil.del_old_output_dir(args.output_directory)
gen = project_generator_for_arg(args)
logging.info("Project Generator type: %s", args.project_generator_type)
logging.info("Generation type: %s", args.gen_type)
logging.info("Creating a {} module count mock app in {}".format(len(node_list), args.output_directory))
logging.info("Example command to generate Xcode workspace: $ {}".format(gen.example_command()))
gen.gen_app(app_node, node_list, graph_config.swift_lines_of_code, graph_config.objc_lines_of_code,
graph_config.loc_json_file_path)
fin = time.time()
logging.info("Done in %f s", fin - start)
project_info = {
"generator_type": args.project_generator_type,
"graph_config": args.gen_type,
"options": {
"use_wmo": bool(args.use_wmo),
"use_dynamic_linking": bool(args.use_dynamic_linking),
"swift_lines_of_code": args.swift_lines_of_code,
"objc_lines_of_code": args.objc_lines_of_code
},
"time_to_generate": fin - start
}
with open(join(args.output_directory, "project_info.json"), "w") as project_info_json_file:
json.dump(project_info, project_info_json_file)
def print_nodes(node_list):
edges = [(node.name, dep.name) for node in node_list for dep in node.deps]
for edge in edges:
print(edge[0], edge[1])
def project_generator_for_arg(args):
if args.project_generator_type == 'buck' or args.project_generator_type == 'bazel':
if not args.blaze_module_path:
raise ValueError("Must supply --blaze_module_path when using the Buck or Bazel generators.")
return blazeprojectgen.BlazeProjectGenerator(
args.output_directory, args.blaze_module_path, use_wmo=args.use_wmo, flavor=args.project_generator_type)
elif args.project_generator_type == 'cocoapods':
return cpprojectgen.CocoaPodsProjectGenerator(
args.output_directory,
use_wmo=args.use_wmo,
use_dynamic_linking=args.use_dynamic_linking,
use_deterministic_uuids=args.cocoapods_use_deterministic_uuids,
generate_multiple_pod_projects=args.cocoapods_generate_multiple_pod_projects)
else:
raise ValueError("Unknown project generator arg: " + str(args.project_generator_type))
def main():
GenProjCommandLine().main()
if __name__ == '__main__':
main()