Example #1
0
	def build_modules_info(self, resources_dir, app_bin_dir):
		self.app_modules = []
		(modules, external_child_modules) = bindings.get_all_module_bindings()
		
		compiler = Compiler(self.tiapp, resources_dir, self.java, app_bin_dir, os.path.dirname(app_bin_dir))
		compiler.compile(compile_bytecode=False, info_message=None)
		for module in compiler.modules:
			module_bindings = []
			# TODO: we should also detect module properties
			for method in compiler.module_methods:
				if method.lower().startswith(module+'.') and '.' not in method:
					module_bindings.append(method[len(module)+1:])
			
			module_class = None
			module_apiName = None
			for m in modules.keys():
				if modules[m]['fullAPIName'].lower() == module:
					module_class = m
					module_apiName = modules[m]['fullAPIName']
					break
			
			if module_apiName == None: continue # module wasn't found
			if '.' not in module:
				ext_modules = []
				if module_class in external_child_modules:
					for child_module in external_child_modules[module_class]:
						if child_module['fullAPIName'].lower() in compiler.modules:
							ext_modules.append(child_module)
				self.app_modules.append({
					'api_name': module_apiName,
					'class_name': module_class,
					'bindings': module_bindings,
					'external_child_modules': ext_modules
				})
		
		# discover app modules
		detector = ModuleDetector(self.project_dir)
		missing, detected_modules = detector.find_app_modules(self.tiapp, 'android')
		for missing_module in missing: print '[WARN] Couldn\'t find app module: %s' % missing_module['id']
		
		self.custom_modules = []
		for module in detected_modules:
			if module.jar == None: continue
			module_jar = zipfile.ZipFile(module.jar)
			module_bindings = bindings.get_module_bindings(module_jar)
			if module_bindings is None: continue
			
			for module_class in module_bindings['modules'].keys():
				module_id = module_bindings['proxies'][module_class]['proxyAttrs']['id']
				print '[DEBUG] module_id = %s' % module_id
				if module_id == module.manifest.moduleid:
					print '[DEBUG] appending module: %s' % module_class
					self.custom_modules.append({
						'class_name': module_class,
						'manifest': module.manifest
					})
Example #2
0
    def compileProject(self,
                       xcode=False,
                       devicefamily='ios',
                       iphone_version='iphoneos',
                       silent=False,
                       sdk=None):
        tiapp_xml = os.path.join(self.project_dir, 'tiapp.xml')
        ti = TiAppXML(tiapp_xml)
        if sdk is None:
            sdk_version = os.path.basename(
                os.path.abspath(os.path.join(template_dir, '../')))
        else:
            sdk_version = sdk

        if xcode:
            app_name = os.environ['FULL_PRODUCT_NAME']
            app_dir = os.path.join(os.environ['TARGET_BUILD_DIR'],
                                   os.environ['CONTENTS_FOLDER_PATH'])
        else:
            target = 'Debug'
            if self.deploytype == 'production':
                target = 'Release'
            app_name = self.project_name + '.app'
            app_folder_name = '%s-iphoneos' % target
            app_dir = os.path.abspath(
                os.path.join(self.iphone_dir, 'build', app_folder_name,
                             app_name))

        if not silent:
            print "[INFO] Titanium SDK version: %s" % sdk_version
            print "[INFO] iPhone Device family: %s" % devicefamily
            print "[INFO] iPhone SDK version: %s" % iphone_version

        if self.deploytype != 'export-build':
            main_template_file = os.path.join(template_dir, 'main.m')
            main_template = codecs.open(main_template_file,
                                        encoding='utf-8').read()
            main_template = main_template.replace('__PROJECT_NAME__',
                                                  self.project_name)
            main_template = main_template.replace('__PROJECT_ID__', self.appid)
            main_template = main_template.replace('__DEPLOYTYPE__',
                                                  self.deploytype)
            main_template = main_template.replace('__APP_ID__', self.appid)
            main_template = main_template.replace('__APP_ANALYTICS__',
                                                  ti.properties['analytics'])
            main_template = main_template.replace('__APP_PUBLISHER__',
                                                  ti.properties['publisher'])
            main_template = main_template.replace('__APP_URL__',
                                                  ti.properties['url'])
            main_template = main_template.replace('__APP_NAME__',
                                                  ti.properties['name'])
            main_template = main_template.replace('__APP_VERSION__',
                                                  ti.properties['version'])
            main_template = main_template.replace('__APP_DESCRIPTION__',
                                                  ti.properties['description'])
            main_template = main_template.replace('__APP_COPYRIGHT__',
                                                  ti.properties['copyright'])
            main_template = main_template.replace('__APP_GUID__',
                                                  ti.properties['guid'])
            main_template = main_template.replace('__APP_RESOURCE_DIR__', '')

            main_template_out = os.path.join(self.iphone_dir, 'main.m')
            main_file = codecs.open(main_template_out, 'w+', encoding='utf-8')
            main_file_contents = main_file.read()
            if main_file_contents != main_template:
                main_file.write(main_template)
                main_file.close()

        resources_dir = os.path.join(self.project_dir, 'Resources')
        iphone_resources_dir = os.path.join(resources_dir, 'iphone')
        iphone_platform_dir = os.path.join(self.project_dir, 'platform',
                                           'iphone')

        # copy in any resources in our module like icons
        # NOTE: This means that any JS-only modules in the local project
        # are hashed up and dumped into the export.
        has_modules = False
        missing_modules, modules, module_js = ([], [], [])
        module_js_dir = os.path.join(self.project_dir, 'modules')
        if os.path.exists(module_js_dir):
            for file in os.listdir(module_js_dir):
                if file.endswith('.js'):
                    module_js.append({
                        'from': os.path.join(module_js_dir, file),
                        'to': os.path.join(app_dir, file),
                        'path': 'modules/' + file
                    })

        if self.deploytype != 'export-build':
            # Have to load the module detection here, in order to
            # prevent distributing even MORE stuff in export/transport
            sys.path.append(os.path.join(template_dir, '../module'))
            from module import ModuleDetector

            detector = ModuleDetector(self.project_dir)
            missing_modules, modules = detector.find_app_modules(ti, 'iphone')

            # we have to copy these even in simulator given the path difference
            if os.path.exists(app_dir):
                self.copy_resources([iphone_resources_dir], app_dir, False)

            if os.path.exists(app_dir):
                self.copy_resources([iphone_platform_dir], app_dir, False)

            # generate the includes for all compiled modules
            xcconfig_c = "// this is a generated file - DO NOT EDIT\n\n"

            if len(modules) > 0:
                mods = open(
                    os.path.join(self.classes_dir, 'ApplicationMods.m'), 'w+')
                variables = {}
                mods.write(MODULE_IMPL_HEADER)
                for module in modules:
                    if module.js:
                        # CommonJS module
                        module_js.append({
                            'from':
                            module.js,
                            'path':
                            'modules/' + os.path.basename(module.js)
                        })
                    module_id = module.manifest.moduleid.lower()
                    module_name = module.manifest.name.lower()
                    module_version = module.manifest.version
                    module_guid = ''
                    module_licensekey = ''
                    if module.manifest.has_property('guid'):
                        module_guid = module.manifest.guid
                    if module.manifest.has_property('licensekey'):
                        module_licensekey = module.manifest.licensekey
                    self.modules_metadata.append({
                        'guid':
                        module_guid,
                        'name':
                        module_name,
                        'id':
                        module_id,
                        'dir':
                        module.path,
                        'version':
                        module_version,
                        'licensekey':
                        module_licensekey
                    })
                    xcfile = module.get_resource('module.xcconfig')
                    if os.path.exists(xcfile):
                        xcconfig_contents = parse_xcconfig(
                            xcfile, module_id, variables)
                        xcconfig_c += xcconfig_contents
                    xcfile = os.path.join(self.project_dir, 'modules',
                                          'iphone',
                                          "%s.xcconfig" % module_name)
                    if os.path.exists(xcfile):
                        xcconfig_contents = parse_xcconfig(
                            xcfile, module_id, variables)
                        xcconfig_c += xcconfig_contents
                    mods.write(
                        "	[modules addObject:[NSDictionary dictionaryWithObjectsAndKeys:@\"%s\",@\"name\",@\"%s\",@\"moduleid\",@\"%s\",@\"version\",@\"%s\",@\"guid\",@\"%s\",@\"licensekey\",nil]];\n"
                        % (module_name, module_id, module_version, module_guid,
                           module_licensekey))

                    # Load export symbols from modules...
                    metadata_path = os.path.join(module.path, 'metadata.json')
                    if os.path.exists(metadata_path):
                        self.load_metadata(metadata_path)

                mods.write("	return modules;\n")
                mods.write("}\n")
                mods.write(FOOTER)
                mods.close()

                for (name, values) in variables.iteritems():
                    xcconfig_c += name + '=$(inherited) '
                    for value in values:
                        xcconfig_c += '$(%s) ' % value
                    xcconfig_c += '\n'

                has_modules = True
                xcconfig = os.path.join(self.iphone_dir, "module.xcconfig")
                make_xcc = True
                if os.path.exists(xcconfig):
                    existing_xcc = open(xcconfig).read()
                    # only copy if different so we don't trigger re-compile in xcode
                    make_xcc = existing_xcc != xcconfig_c
                if make_xcc:
                    xcconfig = open(xcconfig, 'w')
                    xcconfig.write(xcconfig_c)
                    xcconfig.close()
        #endif deploytype != 'export-build'
        else:
            # ... And for exported projects, load export symbols from
            # the 'metadata' dir.
            metadata_dir = os.path.join(self.iphone_dir, 'metadata')
            if os.path.isdir(metadata_dir):
                for file in os.listdir(metadata_dir):
                    self.load_metadata(os.path.join(metadata_dir, file))

        if self.deploytype == 'simulator' or self.deploytype == 'export':
            shutil.copy(os.path.join(template_dir, 'Classes', 'defines.h'),
                        os.path.join(self.classes_dir, 'defines.h'))

        if self.deploytype != 'development' or has_modules:

            if os.path.exists(app_dir) and self.deploytype != 'development':
                self.copy_resources([resources_dir], app_dir,
                                    self.deploytype != 'test', module_js)

            if self.deploytype == 'production':
                debugger_plist = os.path.join(app_dir, 'debugger.plist')
                if os.path.exists(debugger_plist):
                    os.remove(debugger_plist)

            if self.deploytype != 'development' and self.deploytype != 'export':
                defines_file = os.path.join(self.classes_dir, 'defines.h')
                defines_header = open(defines_file, 'w+')
                defines_content = "// Warning: this is generated file. Do not modify!\n\n"
                defines_content += "#define TI_VERSION %s\n" % sdk_version
                for sym in self.defines:
                    defines_content += "#define %s\n" % sym

                if defines_content != defines_header.read():
                    defines_header.write(defines_content)
                    defines_header.close()

            # deploy any module image files
            for module in self.modules:
                img_dir = os.path.join(template_dir, 'modules', module.lower(),
                                       'images')
                print "[DEBUG] module image = %s" % img_dir
                if not os.path.exists(img_dir): continue
                dest_img_dir = os.path.join(app_dir, 'modules', module.lower(),
                                            'images')
                if not os.path.exists(dest_img_dir):
                    os.makedirs(dest_img_dir)
                self.copy_resources([img_dir], dest_img_dir, False)

            if self.deploytype != 'development' and os.path.exists(app_dir):
                # optimize PNGs - since we don't include them in the Resources of the xcodeproj
                # the ones we copy in won't get optimized so we need to run it manually
                # we can skip this on the simulator but should do it on device
                dev_path = "/Developer"
                # we need to ask xcode where the root path is
                path = run.run(["/usr/bin/xcode-select", "-print-path"], True,
                               False)
                if path:
                    dev_path = path.strip()
                run.run([
                    "%s/Platforms/iPhoneOS.platform/Developer/usr/bin/iphoneos-optimize"
                    % dev_path, app_dir
                ], False)

                # remove empty directories
                os.chdir(app_dir)
                os.system("find . -type d -empty -delete")

        else:
            print "[INFO] Skipping JS compile, running from simulator"

        if self.deploytype == 'development':
            softlink_for_simulator(self.project_dir, app_dir)
Example #3
0
    def build_modules_info(self,
                           resources_dir,
                           app_bin_dir,
                           include_all_ti_modules=False):
        self.app_modules = []
        (modules, external_child_modules) = bindings.get_all_module_bindings()

        compiler = Compiler(self.tiapp,
                            resources_dir,
                            self.java,
                            app_bin_dir,
                            None,
                            os.path.dirname(app_bin_dir),
                            include_all_modules=include_all_ti_modules)
        compiler.compile(compile_bytecode=False, info_message=None)
        for module in compiler.modules:
            module_bindings = []
            # TODO: we should also detect module properties
            for method in compiler.module_methods:
                if method.lower().startswith(module +
                                             '.') and '.' not in method:
                    module_bindings.append(method[len(module) + 1:])

            module_onAppCreate = None
            module_class = None
            module_apiName = None
            for m in modules.keys():
                if modules[m]['fullAPIName'].lower() == module:
                    module_class = m
                    module_apiName = modules[m]['fullAPIName']
                    if 'onAppCreate' in modules[m]:
                        module_onAppCreate = modules[m]['onAppCreate']
                    break

            if module_apiName == None: continue  # module wasn't found
            ext_modules = []
            if module_class in external_child_modules:
                for child_module in external_child_modules[module_class]:
                    if child_module['fullAPIName'].lower() in compiler.modules:
                        ext_modules.append(child_module)
            self.app_modules.append({
                'api_name': module_apiName,
                'class_name': module_class,
                'bindings': module_bindings,
                'external_child_modules': ext_modules,
                'on_app_create': module_onAppCreate
            })

        # discover app modules
        detector = ModuleDetector(self.project_dir)
        missing, detected_modules = detector.find_app_modules(
            self.tiapp, 'android', self.deploy_type)
        for missing_module in missing:
            print '[WARN] Couldn\'t find app module: %s' % missing_module['id']

        self.custom_modules = []
        for module in detected_modules:
            if module.jar == None: continue
            module_jar = zipfile.ZipFile(module.jar)
            module_bindings = bindings.get_module_bindings(module_jar)
            if module_bindings is None: continue

            for module_class in module_bindings['modules'].keys():
                module_apiName = module_bindings['modules'][module_class][
                    'apiName']
                module_proxy = module_bindings['proxies'][module_class]
                module_id = module_proxy['proxyAttrs']['id']
                module_proxy_class_name = module_proxy['proxyClassName']
                module_onAppCreate = None
                if 'onAppCreate' in module_proxy:
                    module_onAppCreate = module_proxy['onAppCreate']

                print '[DEBUG] module_id = %s' % module_id
                if module_id == module.manifest.moduleid:
                    # make sure that the module was not built before 1.8.0.1
                    try:
                        module_api_version = int(module.manifest.apiversion)
                        if module_api_version < 2:
                            print "[ERROR] The 'apiversion' for '%s' in the module manifest is less than version 2.  The module was likely built against a Titanium SDK pre 1.8.0.1.  Please use a version of the module that has 'apiversion' 2 or greater" % module_id
                            touch_tiapp_xml(
                                os.path.join(self.project_dir, 'tiapp.xml'))
                            sys.exit(1)

                    except (TypeError, ValueError):
                        print "[ERROR] The 'apiversion' for '%s' in the module manifest is not a valid value.  Please use a version of the module that has an 'apiversion' value of 2 or greater set in it's manifest file" % module_id
                        touch_tiapp_xml(
                            os.path.join(self.project_dir, 'tiapp.xml'))
                        sys.exit(1)

                    is_native_js_module = (hasattr(module.manifest, 'commonjs')
                                           and module.manifest.commonjs)
                    print '[DEBUG] appending module: %s' % module_class
                    self.custom_modules.append({
                        'module_id':
                        module_id,
                        'module_apiName':
                        module_apiName,
                        'proxy_name':
                        module_proxy_class_name,
                        'class_name':
                        module_class,
                        'manifest':
                        module.manifest,
                        'on_app_create':
                        module_onAppCreate,
                        'is_native_js_module':
                        is_native_js_module
                    })
                    if is_native_js_module:
                        # Need to look at the app modules used in this external js module
                        metadata_file = os.path.join(module.path,
                                                     "metadata.json")
                        metadata = None
                        try:
                            f = open(metadata_file, "r")
                            metadata = f.read()
                        finally:
                            f.close()

                        if metadata:
                            metadata = simplejson.loads(metadata)
                            if metadata.has_key("exports"):
                                exported_module_ids = metadata["exports"]
                                already_included_module_ids = [
                                    m["api_name"].lower()
                                    for m in self.app_modules
                                ]
                                need_to_add = [
                                    m for m in exported_module_ids
                                    if m not in already_included_module_ids
                                ]
                                if need_to_add:
                                    for to_add in need_to_add:
                                        module_onAppCreate = None
                                        module_class = None
                                        module_apiName = None
                                        for m in modules.keys():
                                            if modules[m]['fullAPIName'].lower(
                                            ) == to_add:
                                                module_class = m
                                                module_apiName = modules[m][
                                                    'fullAPIName']
                                                if 'onAppCreate' in modules[m]:
                                                    module_onAppCreate = modules[
                                                        m]['onAppCreate']
                                                break

                                        if module_apiName == None:
                                            continue  # module wasn't found
                                        ext_modules = []
                                        if module_class in external_child_modules:
                                            for child_module in external_child_modules[
                                                    module_class]:
                                                if child_module[
                                                        'fullAPIName'].lower(
                                                        ) in compiler.modules:
                                                    ext_modules.append(
                                                        child_module)
                                        self.app_modules.append({
                                            'api_name':
                                            module_apiName,
                                            'class_name':
                                            module_class,
                                            'bindings': [],
                                            'external_child_modules':
                                            ext_modules,
                                            'on_app_create':
                                            module_onAppCreate
                                        })
Example #4
0
def main(args):
    if len(args) < 2:
        print "Usage: %s <project_directory> [sdk_verison]" % os.path.basename(
            args[0])
        sys.exit(1)

    # What needs to be done in order to perform a "true" export?
    # ---
    # Wipe the build dir
    # Migrate resources
    # Migrate tiapp.xml (required for scripts)
    # Generate project from template
    # Populate Info.plist
    # Compile/migrate i18n
    # Migrate scripts for compiling JSS files (and i18n)
    # Modify xcodeproj build steps to call the JSS compiler
    # Then... Share and Enjoy.

    project_dir = os.path.abspath(args[1])
    build_dir = os.path.join(project_dir, 'build', 'iphone')
    titanium_local = os.path.join(build_dir, 'titanium')

    if len(args) == 3:
        version = args[2]
        sdk_dir = find_sdk(version)
    else:
        sdk_dir = os.path.abspath(os.path.dirname(template_dir))
        version = os.path.basename(sdk_dir)

    tiappxml = os.path.join(project_dir, 'tiapp.xml')
    tiapp = TiAppXML(tiappxml)

    app_id = tiapp.properties['id']
    app_name = tiapp.properties['name']

    if app_id is None or app_name is None:
        info("Your tiapp.xml is malformed - please specify an app name and id")
        sys.exit(1)

    # Clean build dir (if it exists), error otherwise (no iphone support)
    info("Cleaning build...")
    if os.path.exists(build_dir):
        for f in os.listdir(build_dir):
            path = os.path.join(build_dir, f)
            if os.path.isfile(path):
                os.remove(path)
            else:
                shutil.rmtree(path)
    else:
        info("Your project is not configured to be built for iphone.")
        exit(1)

    # Migrate Resources
    info("Migrating resources...")
    project_resources = os.path.join(project_dir, 'Resources')
    resources_dir = os.path.join(build_dir, 'Resources')

    shutil.copytree(project_resources, resources_dir)

    # Migrate platform/iphone contents into Resources.
    info("Migrating platform/iphone to Resources...")
    project_platform = os.path.join(project_dir, 'platform', 'iphone')

    if os.path.isdir(project_platform):
        contents = os.listdir(project_platform)
        for file in contents:
            path = os.path.join(project_platform, file)
            if os.path.isdir(path):
                shutil.copytree(path, os.path.join(resources_dir, file))
            else:
                shutil.copy(path, os.path.join(resources_dir, file))

    # Migrate tiapp.xml
    info("Migrating tiapp.xml...")
    shutil.copy(tiappxml, build_dir)

    # Generate project stuff from the template
    info("Generating project from Titanium template...")
    project = Projector(app_name, version, template_dir, project_dir, app_id)
    project.create(template_dir, build_dir)

    # Because the debugger.plist is built as part of the required
    # resources, we need to autogen an empty one
    debug_plist = os.path.join(resources_dir, 'debugger.plist')
    force_xcode = write_debugger_plist(None, None, template_dir, debug_plist)

    # Populate Info.plist
    applogo = None
    info("Populating Info.plist...")
    plist_out = os.path.join(build_dir, 'Info.plist')
    create_info_plist(tiapp, template_dir, project_dir, plist_out)
    applogo = tiapp.generate_infoplist(plist_out, app_id, 'iphone',
                                       project_dir, None)

    # Run the compiler to autogenerate .m files
    info("Copying classes, creating generated .m files...")
    compiler = Compiler(project_dir, app_id, app_name, 'export')
    compiler.compileProject(silent=True)

    #... But we still have to nuke the stuff that gets built that we don't want
    # to bundle.
    ios_build = os.path.join(build_dir, 'build')
    if os.path.isdir(ios_build):
        shutil.rmtree(os.path.join(build_dir, 'build'))

    # Install applogo/splash/etc.
    info("Copying icons and splash...")
    install_logo(tiapp, applogo, project_dir, template_dir, resources_dir)
    install_defaults(project_dir, template_dir, resources_dir)

    # Get Modules
    detector = ModuleDetector(project_dir)
    missing_modules, modules = detector.find_app_modules(tiapp, 'iphone')

    if len(missing_modules) != 0:
        for module in missing_modules:
            info("MISSING MODULE: %s ... Project will not build correctly" %
                 module['id'])
        info("Terminating export: Please fix your modules.")
        sys.exit(1)

    module_search_path, module_asset_dirs = locate_modules(
        modules, project_dir, resources_dir, info)

    lib_dir = os.path.join(build_dir, 'lib')
    if not os.path.exists(lib_dir):
        os.makedirs(lib_dir)

    if len(module_search_path) > 0:
        info("Copying modules...")
        for module in module_search_path:
            module_name, module_path = module
            info("\t%s..." % module_name)
            shutil.copy(os.path.join(module_path, module_name), lib_dir)
            module[1] = os.path.join(lib_dir, module_name)

        info("Copying module metadata...")
        metadata_dir = os.path.join(build_dir, 'metadata')
        for module in modules:
            module_metadata = os.path.join(module.path, 'metadata.json')
            if os.path.exists(module_metadata):
                if not os.path.exists(metadata_dir):
                    os.makedirs(metadata_dir)
                target = os.path.join(metadata_dir,
                                      "%s.json" % module.manifest.moduleid)
                shutil.copyfile(module_metadata, target)

        # Note: The module link information has to be added to
        # the xcodeproj after it's created.
        # We also have to mod the module_search_path to reference
        # the local 'lib' directory instead of the original
        # module install location
        info("Linking modules...")
        local_modules = []
        for module in module_search_path:
            name = module[0]
            newpath = os.path.join('lib', name)
            local_modules.append([name, newpath])
        link_modules(local_modules, app_name, build_dir, relative=True)

    # Copy libraries
    info("Copying libraries...")
    iphone_dir = os.path.join(sdk_dir, 'iphone')
    for lib in glob.iglob(os.path.join(iphone_dir, 'lib*')):
        info("\t%s..." % lib)
        shutil.copy(lib, lib_dir)

    # Process i18n files
    info("Processing i18n...")
    locale_compiler = LocaleCompiler(app_name, project_dir, 'ios',
                                     'development', resources_dir)
    locale_compiler.compile()

    # Migrate compile scripts
    info("Copying custom Titanium compiler scripts...")
    shutil.copytree(os.path.join(sdk_dir, 'common'), titanium_local)
    shutil.copy(os.path.join(sdk_dir, 'tiapp.py'), titanium_local)

    iphone_script_dir = os.path.join(titanium_local, 'iphone')
    os.mkdir(iphone_script_dir)
    shutil.copy(os.path.join(sdk_dir, 'iphone', 'compiler.py'),
                iphone_script_dir)
    shutil.copy(os.path.join(sdk_dir, 'iphone', 'tools.py'), iphone_script_dir)
    shutil.copy(os.path.join(sdk_dir, 'iphone', 'run.py'), iphone_script_dir)
    shutil.copy(os.path.join(sdk_dir, 'iphone', 'csspacker.py'),
                iphone_script_dir)
    shutil.copy(os.path.join(sdk_dir, 'iphone', 'jspacker.py'),
                iphone_script_dir)
    shutil.copy(os.path.join(sdk_dir, 'iphone', 'titanium_prep'),
                iphone_script_dir)

    # Add compilation to the build script in project
    info("Modifying pre-compile stage...")
    xcodeproj = os.path.join(build_dir, '%s.xcodeproj' % app_name,
                             'project.pbxproj')
    contents = codecs.open(xcodeproj, 'r', encoding='utf-8').read()

    css_compiler = os.path.join('titanium', 'css', 'csscompiler.py')
    ti_compiler = os.path.join('titanium', 'iphone', 'compiler.py')
    script = """%s . ios Resources
%s . export-build $TARGETED_DEVICE_FAMILY $SDKROOT %s""" % (
        css_compiler, ti_compiler, version)
    contents = fix_xcode_script(contents, "Pre-Compile", script)

    # write our new project
    f = codecs.open(xcodeproj, 'w', encoding='utf-8')
    f.write(contents)
    f.close()

    info("Finished! Share and Enjoy.")
Example #5
0
    def __init__(self,
                 project_dir,
                 appid,
                 name,
                 deploytype,
                 xcode,
                 devicefamily,
                 iphone_version,
                 silent=False):
        self.project_dir = project_dir
        self.project_name = name
        self.appid = appid
        self.iphone_dir = os.path.join(project_dir, 'build', 'iphone')
        self.classes_dir = os.path.join(self.iphone_dir, 'Classes')
        self.modules = []
        self.modules_metadata = []

        # for now, these are required
        self.defines = [
            'USE_TI_ANALYTICS', 'USE_TI_NETWORK', 'USE_TI_PLATFORM',
            'USE_TI_UI'
        ]

        tiapp_xml = os.path.join(project_dir, 'tiapp.xml')
        ti = TiAppXML(tiapp_xml)
        sdk_version = os.path.basename(
            os.path.abspath(os.path.join(template_dir, '../')))
        detector = ModuleDetector(project_dir)
        missing_modules, modules = detector.find_app_modules(ti, 'iphone')

        if xcode:
            app_name = os.environ['FULL_PRODUCT_NAME']
            app_dir = os.path.join(os.environ['TARGET_BUILD_DIR'],
                                   os.environ['CONTENTS_FOLDER_PATH'])
        else:
            target = 'Debug'
            if deploytype == 'install':
                target = 'Release'
            app_name = name + '.app'
            app_folder_name = '%s-iphoneos' % target
            app_dir = os.path.abspath(
                os.path.join(self.iphone_dir, 'build', app_folder_name,
                             app_name))

        main_template_file = os.path.join(template_dir, 'main.m')
        main_template = codecs.open(main_template_file,
                                    encoding='utf-8').read()
        main_template = main_template.replace('__PROJECT_NAME__', name)
        main_template = main_template.replace('__PROJECT_ID__', appid)
        main_template = main_template.replace('__DEPLOYTYPE__', deploytype)
        main_template = main_template.replace('__APP_ID__', appid)
        main_template = main_template.replace('__APP_ANALYTICS__',
                                              ti.properties['analytics'])
        main_template = main_template.replace('__APP_PUBLISHER__',
                                              ti.properties['publisher'])
        main_template = main_template.replace('__APP_URL__',
                                              ti.properties['url'])
        main_template = main_template.replace('__APP_NAME__',
                                              ti.properties['name'])
        main_template = main_template.replace('__APP_VERSION__',
                                              ti.properties['version'])
        main_template = main_template.replace('__APP_DESCRIPTION__',
                                              ti.properties['description'])
        main_template = main_template.replace('__APP_COPYRIGHT__',
                                              ti.properties['copyright'])
        main_template = main_template.replace('__APP_GUID__',
                                              ti.properties['guid'])
        if deploytype == 'development':
            main_template = main_template.replace(
                '__APP_RESOURCE_DIR__',
                os.path.abspath(os.path.join(project_dir, 'Resources')))
        else:
            main_template = main_template.replace('__APP_RESOURCE_DIR__', '')

        if not silent:
            print "[INFO] Titanium SDK version: %s" % sdk_version
            print "[INFO] iPhone Device family: %s" % devicefamily
            print "[INFO] iPhone SDK version: %s" % iphone_version

        main_template_out = os.path.join(self.iphone_dir, 'main.m')
        main_file = codecs.open(main_template_out, 'w+', encoding='utf-8')
        main_file_contents = main_file.read()
        if main_file_contents != main_template:
            main_file.write(main_template)
            main_file.close()

        if deploytype == 'production':
            version = ti.properties['version']
            # we want to make sure in debug mode the version always changes
            version = "%s.%d" % (version, time.time())
            ti.properties['version'] = version

        resources_dir = os.path.join(project_dir, 'Resources')
        iphone_resources_dir = os.path.join(resources_dir, 'iphone')

        # copy in any resources in our module like icons
        project_module_dir = os.path.join(project_dir, 'modules', 'iphone')
        if os.path.exists(project_module_dir):
            self.copy_resources([project_module_dir], app_dir, False)

        # we have to copy these even in simulator given the path difference
        if os.path.exists(app_dir):
            self.copy_resources([iphone_resources_dir], app_dir, False)

        # generate the includes for all compiled modules
        xcconfig_c = "// this is a generated file - DO NOT EDIT\n\n"
        has_modules = False

        if len(modules) > 0:
            mods = open(os.path.join(self.classes_dir, 'ApplicationMods.m'),
                        'w+')
            mods.write(MODULE_IMPL_HEADER)
            for module in modules:
                module_id = module.manifest.moduleid.lower()
                module_name = module.manifest.name.lower()
                module_version = module.manifest.version
                module_guid = ''
                module_licensekey = ''
                if module.manifest.has_property('guid'):
                    module_guid = module.manifest.guid
                if module.manifest.has_property('licensekey'):
                    module_licensekey = module.manifest.licensekey
                self.modules_metadata.append({
                    'guid': module_guid,
                    'name': module_name,
                    'id': module_id,
                    'dir': module.path,
                    'version': module_version,
                    'licensekey': module_licensekey
                })
                xcfile = module.get_resource('module.xcconfig')
                if os.path.exists(xcfile):
                    xcconfig_c += "#include \"%s\"\n" % xcfile
                xcfile = os.path.join(self.project_dir, 'modules', 'iphone',
                                      "%s.xcconfig" % module_name)
                if os.path.exists(xcfile):
                    xcconfig_c += "#include \"%s\"\n" % xcfile
                mods.write(
                    "	[modules addObject:[NSDictionary dictionaryWithObjectsAndKeys:@\"%s\",@\"name\",@\"%s\",@\"moduleid\",@\"%s\",@\"version\",@\"%s\",@\"guid\",@\"%s\",@\"licensekey\",nil]];\n"
                    % (module_name, module_id, module_version, module_guid,
                       module_licensekey))
            mods.write("	return modules;\n")
            mods.write("}\n")
            mods.write(FOOTER)
            mods.close()
            has_modules = True
            xcconfig = os.path.join(self.iphone_dir, "module.xcconfig")
            make_xcc = True
            if os.path.exists(xcconfig):
                existing_xcc = open(xcconfig).read()
                # only copy if different so we don't trigger re-compile in xcode
                make_xcc = existing_xcc != xcconfig_c
            if make_xcc:
                xcconfig = open(xcconfig, 'w')
                xcconfig.write(xcconfig_c)
                xcconfig.close()

        if deploytype == 'simulator':
            shutil.copy(os.path.join(template_dir, 'Classes', 'defines.h'),
                        os.path.join(self.classes_dir, 'defines.h'))

        if deploytype != 'development' or has_modules:

            if os.path.exists(app_dir):
                self.copy_resources([resources_dir], app_dir)

            if deploytype != 'development':
                defines_file = os.path.join(self.classes_dir, 'defines.h')
                defines_header = open(defines_file, 'w+')
                defines_content = "// Warning: this is generated file. Do not modify!\n\n"
                defines_content += "#define TI_VERSION %s\n" % sdk_version
                for sym in self.defines:
                    defines_content += "#define %s 1\n" % sym
                if defines_content != defines_header.read():
                    defines_header.write(defines_content)
                    defines_header.close()

            # deploy any module image files
            for module in self.modules:
                img_dir = os.path.join(template_dir, 'modules', module.lower(),
                                       'images')
                print "[DEBUG] module image = %s" % img_dir
                if not os.path.exists(img_dir): continue
                dest_img_dir = os.path.join(app_dir, 'modules', module.lower(),
                                            'images')
                if not os.path.exists(dest_img_dir):
                    os.makedirs(dest_img_dir)
                self.copy_resources([img_dir], dest_img_dir, False)

            if deploytype != 'development' and os.path.exists(app_dir):
                # optimize PNGs - since we don't include them in the Resources of the xcodeproj
                # the ones we copy in won't get optimized so we need to run it manually
                # we can skip this on the simulator but should do it on device
                dev_path = "/Developer"
                # we need to ask xcode where the root path is
                path = run.run(["/usr/bin/xcode-select", "-print-path"], True,
                               False)
                if path:
                    dev_path = path.strip()
                run.run([
                    "%s/Platforms/iPhoneOS.platform/Developer/usr/bin/iphoneos-optimize"
                    % dev_path, app_dir
                ], False)

                # remove empty directories
                os.chdir(app_dir)
                os.system("find . -type d -empty -delete")

        else:
            print "[INFO] Skipping JS compile, running from simulator"