def add_project_to_archive(z, project, prefix=''): source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) prefix += re.sub(r'[^\w]+', '_', project.name).strip('_').lower() for source in source_files: src_dir = 'src' if project.project_type == 'native': if source.target == 'worker': src_dir = 'worker_src' elif project.app_modern_multi_js and source.file_name.endswith('.js'): src_dir = 'src/js' z.writestr('%s/%s/%s' % (prefix, src_dir, source.file_name), source.get_contents()) for resource in resources: res_path = 'resources' for variant in resource.variants.all(): z.writestr('%s/%s/%s' % (prefix, res_path, variant.path), variant.get_contents()) manifest = generate_manifest(project, resources) z.writestr('%s/appinfo.json' % prefix, manifest) if project.project_type == 'native': # This file is always the same, but needed to build. z.writestr('%s/wscript' % prefix, generate_wscript_file(project, for_export=True)) z.writestr('%s/jshintrc' % prefix, generate_jshint_file(project))
def assemble_project(project, base_dir, build_result=None): """ Copy all files necessary to build a project into a directory. """ resources = project.resources.all() if project.is_standard_project_type: # Write out the sources, resources, and wscript and jshint file assemble_source_files(project, base_dir) if project.project_type != 'rocky': assemble_resource_directories(project, base_dir) assemble_resources(base_dir, project.resources_path, resources) with open(os.path.join(base_dir, 'wscript'), 'w') as wscript: wscript.write(generate_wscript_file(project)) with open(os.path.join(base_dir, 'pebble-jshintrc'), 'w') as jshint: jshint.write(generate_jshint_file(project)) elif project.project_type == 'simplyjs': # SimplyJS is a particularly special case assemble_simplyjs_sources(project, base_dir, build_result) elif project.project_type == 'pebblejs': # PebbleJS projects have to import the entire pebblejs library, including its wscript assemble_resource_directories(project, base_dir) shutil.rmtree(base_dir) shutil.copytree(settings.PEBBLEJS_ROOT, base_dir) assemble_resources(base_dir, project.resources_path, resources, type_restrictions=('png', 'bitmap')) assemble_source_files(project, base_dir) # All projects have a manifest manifest_filename = manifest_name_for_project(project) manifest_dict = generate_manifest_dict(project, resources) with open(os.path.join(base_dir, manifest_filename), 'w') as f: f.write(json.dumps(manifest_dict))
def add_project_to_archive(z, project, prefix=''): source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) prefix += re.sub(r'[^\w]+', '_', project.name).strip('_').lower() for source in source_files: src_dir = 'src' if project.project_type == 'native': if source.target == 'worker': src_dir = 'worker_src' elif project.app_modern_multi_js and source.file_name.endswith( '.js'): src_dir = 'src/js' z.writestr('%s/%s/%s' % (prefix, src_dir, source.file_name), source.get_contents()) for resource in resources: res_path = 'resources' for variant in resource.variants.all(): z.writestr('%s/%s/%s' % (prefix, res_path, variant.path), variant.get_contents()) manifest = generate_manifest(project, resources) manifest_name = manifest_name_for_project(project) z.writestr('%s/%s' % (prefix, manifest_name), manifest) if project.project_type == 'native': # This file is always the same, but needed to build. z.writestr('%s/wscript' % prefix, generate_wscript_file(project, for_export=True)) z.writestr('%s/jshintrc' % prefix, generate_jshint_file(project))
def add_project_to_archive(z, project, prefix=''): source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) prefix += re.sub(r'[^\w]+', '_', project.name).strip('_').lower() for source in source_files: src_dir = 'worker_src' if source.target == 'worker' else 'src' z.writestr('%s/%s/%s' % (prefix, src_dir, source.file_name), source.get_contents()) for resource in resources: res_path = 'resources' z.writestr('%s/%s/%s' % (prefix, res_path, resource.path), resource.get_contents()) manifest = generate_manifest(project, resources) z.writestr('%s/appinfo.json' % prefix, manifest) if project.project_type == 'native': # This file is always the same, but needed to build. z.writestr('%s/wscript' % prefix, generate_wscript_file(project, for_export=True)) z.writestr('%s/jshintrc' % prefix, generate_jshint_file(project))
def add_project_to_archive(z, project, prefix=''): source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) prefix += re.sub(r'[^\w]+', '_', project.name).strip('_').lower() for source in source_files: path = os.path.join(prefix, source.project_path) z.writestr(path, source.get_contents()) for resource in resources: for variant in resource.variants.all(): z.writestr('%s/%s/%s' % (prefix, project.resources_path, variant.path), variant.get_contents()) manifest = generate_manifest(project, resources) manifest_name = manifest_name_for_project(project) z.writestr('%s/%s' % (prefix, manifest_name), manifest) if project.is_standard_project_type: # This file is always the same, but needed to build. z.writestr('%s/wscript' % prefix, generate_wscript_file(project, for_export=True)) z.writestr('%s/jshintrc' % prefix, generate_jshint_file(project))
def add_project_to_archive(z, project, prefix=""): source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) prefix += re.sub(r"[^\w]+", "_", project.name).strip("_").lower() for source in source_files: src_dir = "worker_src" if source.target == "worker" else "src" z.writestr("%s/%s/%s" % (prefix, src_dir, source.file_name), source.get_contents()) for resource in resources: res_path = "resources" for variant in resource.variants.all(): z.writestr("%s/%s/%s" % (prefix, res_path, variant.path), variant.get_contents()) manifest = generate_manifest(project, resources) z.writestr("%s/appinfo.json" % prefix, manifest) if project.project_type == "native": # This file is always the same, but needed to build. z.writestr("%s/wscript" % prefix, generate_wscript_file(project, for_export=True)) z.writestr("%s/jshintrc" % prefix, generate_jshint_file(project))
def add_project_to_archive(z, project, prefix='', suffix=''): source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) prefix += re.sub(r'[^\w]+', '_', project.name).strip('_').lower() prefix += suffix for source in source_files: path = os.path.join(prefix, source.project_path) z.writestr(path, source.get_contents()) for resource in resources: for variant in resource.variants.all(): z.writestr('%s/%s/%s' % (prefix, project.resources_path, variant.path), variant.get_contents()) manifest = generate_manifest(project, resources) manifest_name = manifest_name_for_project(project) z.writestr('%s/%s' % (prefix, manifest_name), manifest) if project.is_standard_project_type: # This file is always the same, but needed to build. z.writestr('%s/wscript' % prefix, generate_wscript_file(project, for_export=True)) z.writestr('%s/jshintrc' % prefix, generate_jshint_file(project))
def add_project_to_archive(z, project, prefix=''): source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) prefix += re.sub(r'[^\w]+', '_', project.name).strip('_').lower() for source in source_files: z.writestr('%s/src/%s' % (prefix, source.file_name), source.get_contents()) for resource in resources: res_path = 'resources/src' if project.sdk_version == '1' else 'resources' z.writestr('%s/%s/%s' % (prefix, res_path, resource.path), resource.get_contents()) if project.sdk_version == '1': resource_map = generate_resource_map(project, resources) z.writestr('%s/resources/src/resource_map.json' % prefix, resource_map) else: manifest = generate_v2_manifest(project, resources) z.writestr('%s/appinfo.json' % prefix, manifest) # This file is always the same, but needed to build. z.writestr('%s/wscript' % prefix, generate_wscript_file(project, for_export=True)) z.writestr('%s/jshintrc' % prefix, generate_jshint_file(project))
def run_compile(build_result): build_result = BuildResult.objects.get(pk=build_result) project = build_result.project source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) # Assemble the project somewhere base_dir = tempfile.mkdtemp(dir=os.path.join(settings.CHROOT_ROOT, 'tmp') if settings.CHROOT_ROOT else None) try: # Resources resource_root = 'resources' os.makedirs(os.path.join(base_dir, resource_root, 'images')) os.makedirs(os.path.join(base_dir, resource_root, 'fonts')) os.makedirs(os.path.join(base_dir, resource_root, 'data')) if project.project_type == 'native': # Source code create_source_files(project, base_dir) manifest_dict = generate_manifest_dict(project, resources) open(os.path.join(base_dir, 'appinfo.json'), 'w').write(json.dumps(manifest_dict)) for f in resources: target_dir = os.path.abspath( os.path.join(base_dir, resource_root, ResourceFile.DIR_MAP[f.kind])) abs_target = os.path.abspath( os.path.join(target_dir, f.file_name)) f.copy_all_variants_to_dir(target_dir) # Reconstitute the SDK open(os.path.join(base_dir, 'wscript'), 'w').write(generate_wscript_file(project)) open(os.path.join(base_dir, 'pebble-jshintrc'), 'w').write(generate_jshint_file(project)) elif project.project_type == 'simplyjs': shutil.rmtree(base_dir) shutil.copytree(settings.SIMPLYJS_ROOT, base_dir) manifest_dict = generate_simplyjs_manifest_dict(project) js = '\n\n'.join(x.get_contents() for x in source_files if x.file_name.endswith('.js')) escaped_js = json.dumps(js) build_result.save_simplyjs(js) open(os.path.join(base_dir, 'appinfo.json'), 'w').write(json.dumps(manifest_dict)) open(os.path.join(base_dir, 'src', 'js', 'zzz_userscript.js'), 'w').write(""" (function() { simply.mainScriptSource = %s; })(); """ % escaped_js) elif project.project_type == 'pebblejs': shutil.rmtree(base_dir) shutil.copytree(settings.PEBBLEJS_ROOT, base_dir) manifest_dict = generate_pebblejs_manifest_dict(project, resources) create_source_files(project, base_dir) for f in resources: if f.kind != 'png': continue target_dir = os.path.abspath( os.path.join(base_dir, resource_root, ResourceFile.DIR_MAP[f.kind])) abs_target = os.path.abspath( os.path.join(target_dir, f.file_name)) if not abs_target.startswith(target_dir): raise Exception("Suspicious filename: %s" % f.file_name) f.copy_to_path(ResourceVariant.VARIANT_DEFAULT, abs_target) open(os.path.join(base_dir, 'appinfo.json'), 'w').write(json.dumps(manifest_dict)) # Build the thing cwd = os.getcwd() success = False output = 'Failed to get output' build_start_time = now() try: os.chdir(base_dir) if project.sdk_version == '2': tool = settings.SDK2_PEBBLE_TOOL elif project.sdk_version == '3': tool = settings.SDK3_PEBBLE_TOOL else: raise Exception("invalid sdk version.") output = subprocess.check_output([tool, "build"], stderr=subprocess.STDOUT, preexec_fn=_set_resource_limits) except subprocess.CalledProcessError as e: output = e.output print output success = False except Exception as e: success = False output = str(e) else: success = True temp_file = os.path.join(base_dir, 'build', '%s.pbw' % os.path.basename(base_dir)) if not os.path.exists(temp_file): success = False print "Success was a lie." finally: build_end_time = now() os.chdir(cwd) if success: # Try reading file sizes out of it first. try: s = os.stat(temp_file) build_result.total_size = s.st_size # Now peek into the zip to see the component parts with zipfile.ZipFile(temp_file, 'r') as z: store_size_info(build_result, 'aplite', z) store_size_info(build_result, 'basalt', z) except Exception as e: print "Couldn't extract filesizes: %s" % e # Try pulling out debug information. if project.sdk_version == '2': save_debug_info( base_dir, build_result, BuildResult.DEBUG_APP, 'aplite', os.path.join(base_dir, 'build', 'pebble-app.elf')) save_debug_info( base_dir, build_result, BuildResult.DEBUG_WORKER, 'aplite', os.path.join(base_dir, 'build', 'pebble-worker.elf')) else: save_debug_info( base_dir, build_result, BuildResult.DEBUG_APP, 'aplite', os.path.join(base_dir, 'build', 'aplite/pebble-app.elf')) save_debug_info( base_dir, build_result, BuildResult.DEBUG_WORKER, 'aplite', os.path.join(base_dir, 'build', 'aplite/pebble-worker.elf')) save_debug_info( base_dir, build_result, BuildResult.DEBUG_APP, 'basalt', os.path.join(base_dir, 'build', 'basalt/pebble-app.elf')) save_debug_info( base_dir, build_result, BuildResult.DEBUG_WORKER, 'basalt', os.path.join(base_dir, 'build', 'basalt/pebble-worker.elf')) build_result.save_pbw(temp_file) build_result.save_build_log(output) build_result.state = BuildResult.STATE_SUCCEEDED if success else BuildResult.STATE_FAILED build_result.finished = now() build_result.save() data = { 'data': { 'cloudpebble': { 'build_id': build_result.id, 'job_run_time': (build_result.finished - build_result.started).total_seconds(), }, 'build_time': (build_end_time - build_start_time).total_seconds(), } } event_name = 'app_build_succeeded' if success else 'app_build_failed' send_keen_event(['cloudpebble', 'sdk'], event_name, data, project=project) except Exception as e: print "Build failed due to internal error: %s" % e traceback.print_exc() build_result.state = BuildResult.STATE_FAILED build_result.finished = now() try: build_result.save_build_log("Something broke:\n%s" % e) except: pass build_result.save() finally: # shutil.rmtree(base_dir) print base_dir
def run_compile(build_result): build_result = BuildResult.objects.get(pk=build_result) project = build_result.project source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) # Assemble the project somewhere base_dir = tempfile.mkdtemp(dir=os.path.join(settings.CHROOT_ROOT, 'tmp') if settings.CHROOT_ROOT else None) try: # Resources resource_root = 'resources' os.makedirs(os.path.join(base_dir, resource_root, 'images')) os.makedirs(os.path.join(base_dir, resource_root, 'fonts')) os.makedirs(os.path.join(base_dir, resource_root, 'data')) if project.project_type == 'native': # Source code src_dir = os.path.join(base_dir, 'src') os.mkdir(src_dir) create_source_files(source_files, src_dir) manifest_dict = generate_v2_manifest_dict(project, resources) open(os.path.join(base_dir, 'appinfo.json'), 'w').write(json.dumps(manifest_dict)) for f in resources: target_dir = os.path.abspath(os.path.join(base_dir, resource_root, ResourceFile.DIR_MAP[f.kind])) abs_target = os.path.abspath(os.path.join(target_dir, f.file_name)) if not abs_target.startswith(target_dir): raise Exception("Suspicious filename: %s" % f.file_name) f.copy_to_path(abs_target) # Reconstitute the SDK open(os.path.join(base_dir, 'wscript'), 'w').write(generate_wscript_file(project)) open(os.path.join(base_dir, 'pebble-jshintrc'), 'w').write(generate_jshint_file(project)) elif project.project_type == 'simplyjs': shutil.rmtree(base_dir) shutil.copytree(settings.SIMPLYJS_ROOT, base_dir) manifest_dict = generate_simplyjs_manifest_dict(project) js = '\n\n'.join(x.get_contents() for x in source_files if x.file_name.endswith('.js')) escaped_js = json.dumps(js) build_result.save_simplyjs(js) open(os.path.join(base_dir, 'appinfo.json'), 'w').write(json.dumps(manifest_dict)) open(os.path.join(base_dir, 'src', 'js', 'zzz_userscript.js'), 'w').write(""" (function() { simply.mainScriptSource = %s; })(); """ % escaped_js) elif project.project_type == 'pebblejs': shutil.rmtree(base_dir) shutil.copytree(settings.PEBBLEJS_ROOT, base_dir) manifest_dict = generate_pebblejs_manifest_dict(project, resources) create_source_files(source_files, os.path.join(base_dir, 'src', 'js')) for f in resources: if f.kind != 'png': continue target_dir = os.path.abspath(os.path.join(base_dir, resource_root, ResourceFile.DIR_MAP[f.kind])) abs_target = os.path.abspath(os.path.join(target_dir, f.file_name)) if not abs_target.startswith(target_dir): raise Exception("Suspicious filename: %s" % f.file_name) f.copy_to_path(abs_target) open(os.path.join(base_dir, 'appinfo.json'), 'w').write(json.dumps(manifest_dict)) # Build the thing cwd = os.getcwd() success = False output = 'Failed to get output' build_start_time = now() try: os.chdir(base_dir) output = subprocess.check_output([settings.PEBBLE_TOOL, "build"], stderr=subprocess.STDOUT, preexec_fn=_set_resource_limits) except subprocess.CalledProcessError as e: output = e.output print output success = False else: success = True temp_file = os.path.join(base_dir, 'build', '%s.pbw' % os.path.basename(base_dir)) if not os.path.exists(temp_file): success = False print "Success was a lie." finally: build_end_time = now() os.chdir(cwd) if success: # Try reading file sizes out of it first. try: s = os.stat(temp_file) build_result.total_size = s.st_size # Now peek into the zip to see the component parts with zipfile.ZipFile(temp_file, 'r') as z: build_result.binary_size = z.getinfo('pebble-app.bin').file_size build_result.resource_size = z.getinfo('app_resources.pbpack').file_size except Exception as e: print "Couldn't extract filesizes: %s" % e # Try pulling out debug information. elf_file = os.path.join(base_dir, 'build', 'pebble-app.elf') if os.path.exists(elf_file): try: debug_info = apptools.addr2lines.create_coalesced_group(elf_file) except: print traceback.format_exc() else: build_result.save_debug_info(debug_info) build_result.save_pbw(temp_file) build_result.save_build_log(output) build_result.state = BuildResult.STATE_SUCCEEDED if success else BuildResult.STATE_FAILED build_result.finished = now() build_result.save() data = { 'data': { 'cloudpebble': { 'build_id': build_result.id, 'job_run_time': (build_result.finished - build_result.started).total_seconds(), }, 'build_time': (build_end_time - build_start_time).total_seconds(), } } event_name = 'app_build_succeeded' if success else 'app_build_failed' send_keen_event(['cloudpebble', 'sdk'], event_name, data, project=project) except Exception as e: print "Build failed due to internal error: %s" % e traceback.print_exc() build_result.state = BuildResult.STATE_FAILED build_result.finished = now() try: build_result.save_build_log("Something broke:\n%s" % e) except: pass build_result.save() finally: shutil.rmtree(base_dir)
def run_compile(build_result): build_result = BuildResult.objects.get(pk=build_result) project = build_result.project source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) if project.sdk_version == '1': build_result.state = BuildResult.STATE_FAILED build_result.finished = now() build_result.save() return # Assemble the project somewhere base_dir = tempfile.mkdtemp(dir=os.path.join(settings.CHROOT_ROOT, 'tmp') if settings.CHROOT_ROOT else None) try: if project.project_type == 'native': # Source code src_dir = os.path.join(base_dir, 'src') os.mkdir(src_dir) create_source_files(source_files, src_dir) # Resources resource_root = 'resources' os.makedirs(os.path.join(base_dir, resource_root, 'images')) os.makedirs(os.path.join(base_dir, resource_root, 'fonts')) os.makedirs(os.path.join(base_dir, resource_root, 'data')) manifest_dict = generate_v2_manifest_dict(project, resources) open(os.path.join(base_dir, 'appinfo.json'), 'w').write(json.dumps(manifest_dict)) for f in resources: target_dir = os.path.abspath( os.path.join(base_dir, resource_root, ResourceFile.DIR_MAP[f.kind])) abs_target = os.path.abspath( os.path.join(target_dir, f.file_name)) if not abs_target.startswith(target_dir): raise Exception("Suspicious filename: %s" % f.file_name) f.copy_to_path(abs_target) # Reconstitute the SDK open(os.path.join(base_dir, 'wscript'), 'w').write(generate_wscript_file(project)) open(os.path.join(base_dir, 'pebble-jshintrc'), 'w').write(generate_jshint_file(project)) elif project.project_type == 'simplyjs': os.rmdir(base_dir) shutil.copytree(settings.SIMPLYJS_ROOT, base_dir) manifest_dict = generate_simplyjs_manifest_dict(project) js = '\n\n'.join(x.get_contents() for x in source_files if x.file_name.endswith('.js')) escaped_js = json.dumps(js) build_result.save_simplyjs(js) open(os.path.join(base_dir, 'appinfo.json'), 'w').write(json.dumps(manifest_dict)) open(os.path.join(base_dir, 'src', 'js', 'zzz_userscript.js'), 'w').write(""" (function() { simply.mainScriptSource = %s; })(); """ % escaped_js) elif project.project_type == 'pebblejs': os.rmdir(base_dir) shutil.copytree(settings.PEBBLEJS_ROOT, base_dir) manifest_dict = generate_pebblejs_manifest_dict(project) create_source_files(source_files, os.path.join(base_dir, 'src', 'js')) open(os.path.join(base_dir, 'appinfo.json'), 'w').write(json.dumps(manifest_dict)) # Build the thing cwd = os.getcwd() success = False output = 'Failed to get output' try: if settings.CHROOT_JAIL is not None: output = subprocess.check_output([ settings.CHROOT_JAIL, project.sdk_version, base_dir[len(settings.CHROOT_ROOT):] ], stderr=subprocess.STDOUT) else: os.chdir(base_dir) output = subprocess.check_output( [settings.PEBBLE_TOOL, "build"], stderr=subprocess.STDOUT, preexec_fn=_set_resource_limits) except subprocess.CalledProcessError as e: output = e.output print output success = False else: success = True temp_file = os.path.join(base_dir, 'build', '%s.pbw' % os.path.basename(base_dir)) if not os.path.exists(temp_file): success = False print "Success was a lie." finally: os.chdir(cwd) if success: # Try reading file sizes out of it first. try: s = os.stat(temp_file) build_result.total_size = s.st_size # Now peek into the zip to see the component parts with zipfile.ZipFile(temp_file, 'r') as z: build_result.binary_size = z.getinfo( 'pebble-app.bin').file_size build_result.resource_size = z.getinfo( 'app_resources.pbpack').file_size except Exception as e: print "Couldn't extract filesizes: %s" % e # Try pulling out debug information. elf_file = os.path.join(base_dir, 'build', 'pebble-app.elf') if os.path.exists(elf_file): try: debug_info = apptools.addr2lines.create_coalesced_group( elf_file) except: print traceback.format_exc() else: build_result.save_debug_info(debug_info) build_result.save_pbw(temp_file) send_keen_event( ['cloudpebble', 'sdk'], 'app_build_succeeded', data={'data': { 'cloudpebble_build_id': build_result.id }}, project=project) else: send_keen_event( ['cloudpebble', 'sdk'], 'app_build_failed', data={'data': { 'cloudpebble_build_id': build_result.id }}, project=project) build_result.save_build_log(output) build_result.state = BuildResult.STATE_SUCCEEDED if success else BuildResult.STATE_FAILED build_result.finished = now() build_result.save() except Exception as e: print "Build failed due to internal error: %s" % e traceback.print_exc() build_result.state = BuildResult.STATE_FAILED build_result.finished = now() try: build_result.save_build_log("Something broke:\n%s" % e) except: pass build_result.save() finally: shutil.rmtree(base_dir)
def run_compile(build_result): build_result = BuildResult.objects.get(pk=build_result) project = build_result.project source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) # Assemble the project somewhere base_dir = tempfile.mkdtemp(dir=os.path.join(settings.CHROOT_ROOT, 'tmp') if settings.CHROOT_ROOT else None) try: # Resources resource_root = 'resources' os.makedirs(os.path.join(base_dir, resource_root, 'images')) os.makedirs(os.path.join(base_dir, resource_root, 'fonts')) os.makedirs(os.path.join(base_dir, resource_root, 'data')) if project.project_type == 'native': # Source code create_source_files(project, base_dir) manifest_dict = generate_manifest_dict(project, resources) open(os.path.join(base_dir, 'appinfo.json'), 'w').write(json.dumps(manifest_dict)) for f in resources: target_dir = os.path.abspath(os.path.join(base_dir, resource_root, ResourceFile.DIR_MAP[f.kind])) abs_target = os.path.abspath(os.path.join(target_dir, f.file_name)) f.copy_all_variants_to_dir(target_dir) # Reconstitute the SDK open(os.path.join(base_dir, 'wscript'), 'w').write(generate_wscript_file(project)) open(os.path.join(base_dir, 'pebble-jshintrc'), 'w').write(generate_jshint_file(project)) elif project.project_type == 'simplyjs': shutil.rmtree(base_dir) shutil.copytree(settings.SIMPLYJS_ROOT, base_dir) manifest_dict = generate_simplyjs_manifest_dict(project) js = '\n\n'.join(x.get_contents() for x in source_files if x.file_name.endswith('.js')) escaped_js = json.dumps(js) build_result.save_simplyjs(js) open(os.path.join(base_dir, 'appinfo.json'), 'w').write(json.dumps(manifest_dict)) open(os.path.join(base_dir, 'src', 'js', 'zzz_userscript.js'), 'w').write(""" (function() { simply.mainScriptSource = %s; })(); """ % escaped_js) elif project.project_type == 'pebblejs': shutil.rmtree(base_dir) shutil.copytree(settings.PEBBLEJS_ROOT, base_dir) manifest_dict = generate_pebblejs_manifest_dict(project, resources) create_source_files(project, base_dir) for f in resources: if f.kind not in ('png', 'bitmap'): continue target_dir = os.path.abspath(os.path.join(base_dir, resource_root, ResourceFile.DIR_MAP[f.kind])) abs_target = os.path.abspath(os.path.join(target_dir, f.file_name)) if not abs_target.startswith(target_dir): raise Exception("Suspicious filename: %s" % f.file_name) f.get_default_variant().copy_to_path(abs_target) open(os.path.join(base_dir, 'appinfo.json'), 'w').write(json.dumps(manifest_dict)) # Build the thing cwd = os.getcwd() success = False output = 'Failed to get output' build_start_time = now() try: os.chdir(base_dir) if project.sdk_version == '2': environ = os.environ environ['PATH'] = '{}:{}'.format(settings.ARM_CS_TOOLS, environ['PATH']) command = [settings.SDK2_PEBBLE_WAF, "configure", "build"] elif project.sdk_version == '3': environ = os.environ.copy() environ['PATH'] = '{}:{}'.format(settings.ARM_CS_TOOLS, environ['PATH']) command = [settings.SDK3_PEBBLE_WAF, "configure", "build"] else: raise Exception("invalid sdk version.") output = subprocess.check_output(command, stderr=subprocess.STDOUT, preexec_fn=_set_resource_limits, env=environ) except subprocess.CalledProcessError as e: output = e.output print output success = False except Exception as e: success = False output = str(e) else: success = True temp_file = os.path.join(base_dir, 'build', '%s.pbw' % os.path.basename(base_dir)) if not os.path.exists(temp_file): success = False print "Success was a lie." finally: build_end_time = now() os.chdir(cwd) if success: # Try reading file sizes out of it first. try: s = os.stat(temp_file) build_result.total_size = s.st_size # Now peek into the zip to see the component parts with zipfile.ZipFile(temp_file, 'r') as z: store_size_info(project, build_result, 'aplite', z) store_size_info(project, build_result, 'basalt', z) store_size_info(project, build_result, 'chalk', z) except Exception as e: print "Couldn't extract filesizes: %s" % e # Try pulling out debug information. if project.sdk_version == '2': save_debug_info(base_dir, build_result, BuildResult.DEBUG_APP, 'aplite', os.path.join(base_dir, 'build', 'pebble-app.elf')) save_debug_info(base_dir, build_result, BuildResult.DEBUG_WORKER, 'aplite', os.path.join(base_dir, 'build', 'pebble-worker.elf')) else: save_debug_info(base_dir, build_result, BuildResult.DEBUG_APP, 'aplite', os.path.join(base_dir, 'build', 'aplite/pebble-app.elf')) save_debug_info(base_dir, build_result, BuildResult.DEBUG_WORKER, 'aplite', os.path.join(base_dir, 'build', 'aplite/pebble-worker.elf')) save_debug_info(base_dir, build_result, BuildResult.DEBUG_APP, 'basalt', os.path.join(base_dir, 'build', 'basalt/pebble-app.elf')) save_debug_info(base_dir, build_result, BuildResult.DEBUG_WORKER, 'basalt', os.path.join(base_dir, 'build', 'basalt/pebble-worker.elf')) save_debug_info(base_dir, build_result, BuildResult.DEBUG_APP, 'chalk', os.path.join(base_dir, 'build', 'chalk/pebble-app.elf')) save_debug_info(base_dir, build_result, BuildResult.DEBUG_WORKER, 'chalk', os.path.join(base_dir, 'build', 'chalk/pebble-worker.elf')) build_result.save_pbw(temp_file) build_result.save_build_log(output) build_result.state = BuildResult.STATE_SUCCEEDED if success else BuildResult.STATE_FAILED build_result.finished = now() build_result.save() data = { 'data': { 'cloudpebble': { 'build_id': build_result.id, 'job_run_time': (build_result.finished - build_result.started).total_seconds(), }, 'build_time': (build_end_time - build_start_time).total_seconds(), } } event_name = 'app_build_succeeded' if success else 'app_build_failed' send_keen_event(['cloudpebble', 'sdk'], event_name, data, project=project) except Exception as e: print "Build failed due to internal error: %s" % e traceback.print_exc() build_result.state = BuildResult.STATE_FAILED build_result.finished = now() try: build_result.save_build_log("Something broke:\n%s" % e) except: pass build_result.save() finally: # shutil.rmtree(base_dir) print base_dir
def run_compile(build_result): build_result = BuildResult.objects.get(pk=build_result) project = build_result.project source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) # Assemble the project somewhere base_dir = tempfile.mkdtemp(dir=os.path.join(settings.CHROOT_ROOT, "tmp") if settings.CHROOT_ROOT else None) try: # Resources resource_root = "resources" os.makedirs(os.path.join(base_dir, resource_root, "images")) os.makedirs(os.path.join(base_dir, resource_root, "fonts")) os.makedirs(os.path.join(base_dir, resource_root, "data")) if project.project_type == "native": # Source code create_source_files(project, base_dir) manifest_dict = generate_manifest_dict(project, resources) open(os.path.join(base_dir, "appinfo.json"), "w").write(json.dumps(manifest_dict)) for f in resources: target_dir = os.path.abspath(os.path.join(base_dir, resource_root, ResourceFile.DIR_MAP[f.kind])) abs_target = os.path.abspath(os.path.join(target_dir, f.file_name)) f.copy_all_variants_to_dir(target_dir) # Reconstitute the SDK open(os.path.join(base_dir, "wscript"), "w").write(generate_wscript_file(project)) open(os.path.join(base_dir, "pebble-jshintrc"), "w").write(generate_jshint_file(project)) elif project.project_type == "simplyjs": shutil.rmtree(base_dir) shutil.copytree(settings.SIMPLYJS_ROOT, base_dir) manifest_dict = generate_simplyjs_manifest_dict(project) js = "\n\n".join(x.get_contents() for x in source_files if x.file_name.endswith(".js")) escaped_js = json.dumps(js) build_result.save_simplyjs(js) open(os.path.join(base_dir, "appinfo.json"), "w").write(json.dumps(manifest_dict)) open(os.path.join(base_dir, "src", "js", "zzz_userscript.js"), "w").write( """ (function() { simply.mainScriptSource = %s; })(); """ % escaped_js ) elif project.project_type == "pebblejs": shutil.rmtree(base_dir) shutil.copytree(settings.PEBBLEJS_ROOT, base_dir) manifest_dict = generate_pebblejs_manifest_dict(project, resources) create_source_files(project, base_dir) for f in resources: if f.kind != "png": continue target_dir = os.path.abspath(os.path.join(base_dir, resource_root, ResourceFile.DIR_MAP[f.kind])) abs_target = os.path.abspath(os.path.join(target_dir, f.file_name)) if not abs_target.startswith(target_dir): raise Exception("Suspicious filename: %s" % f.file_name) f.copy_to_path(ResourceVariant.VARIANT_DEFAULT, abs_target) open(os.path.join(base_dir, "appinfo.json"), "w").write(json.dumps(manifest_dict)) # Build the thing cwd = os.getcwd() success = False output = "Failed to get output" build_start_time = now() try: os.chdir(base_dir) if project.sdk_version == "2": tool = settings.SDK2_PEBBLE_TOOL elif project.sdk_version == "3": tool = settings.SDK3_PEBBLE_TOOL else: raise Exception("invalid sdk version.") output = subprocess.check_output([tool, "build"], stderr=subprocess.STDOUT, preexec_fn=_set_resource_limits) except subprocess.CalledProcessError as e: output = e.output print output success = False except Exception as e: success = False output = str(e) else: success = True temp_file = os.path.join(base_dir, "build", "%s.pbw" % os.path.basename(base_dir)) if not os.path.exists(temp_file): success = False print "Success was a lie." finally: build_end_time = now() os.chdir(cwd) if success: # Try reading file sizes out of it first. try: s = os.stat(temp_file) build_result.total_size = s.st_size # Now peek into the zip to see the component parts with zipfile.ZipFile(temp_file, "r") as z: store_size_info(build_result, "aplite", z) store_size_info(build_result, "basalt", z) except Exception as e: print "Couldn't extract filesizes: %s" % e # Try pulling out debug information. if project.sdk_version == "2": save_debug_info( base_dir, build_result, BuildResult.DEBUG_APP, "aplite", os.path.join(base_dir, "build", "pebble-app.elf"), ) save_debug_info( base_dir, build_result, BuildResult.DEBUG_WORKER, "aplite", os.path.join(base_dir, "build", "pebble-worker.elf"), ) else: save_debug_info( base_dir, build_result, BuildResult.DEBUG_APP, "aplite", os.path.join(base_dir, "build", "aplite/pebble-app.elf"), ) save_debug_info( base_dir, build_result, BuildResult.DEBUG_WORKER, "aplite", os.path.join(base_dir, "build", "aplite/pebble-worker.elf"), ) save_debug_info( base_dir, build_result, BuildResult.DEBUG_APP, "basalt", os.path.join(base_dir, "build", "basalt/pebble-app.elf"), ) save_debug_info( base_dir, build_result, BuildResult.DEBUG_WORKER, "basalt", os.path.join(base_dir, "build", "basalt/pebble-worker.elf"), ) build_result.save_pbw(temp_file) build_result.save_build_log(output) build_result.state = BuildResult.STATE_SUCCEEDED if success else BuildResult.STATE_FAILED build_result.finished = now() build_result.save() data = { "data": { "cloudpebble": { "build_id": build_result.id, "job_run_time": (build_result.finished - build_result.started).total_seconds(), }, "build_time": (build_end_time - build_start_time).total_seconds(), } } event_name = "app_build_succeeded" if success else "app_build_failed" send_keen_event(["cloudpebble", "sdk"], event_name, data, project=project) except Exception as e: print "Build failed due to internal error: %s" % e traceback.print_exc() build_result.state = BuildResult.STATE_FAILED build_result.finished = now() try: build_result.save_build_log("Something broke:\n%s" % e) except: pass build_result.save() finally: # shutil.rmtree(base_dir) print base_dir
def run_compile(build_result): build_result = BuildResult.objects.get(pk=build_result) project = build_result.project source_files = SourceFile.objects.filter(project=project) resources = ResourceFile.objects.filter(project=project) # Assemble the project somewhere base_dir = tempfile.mkdtemp(dir=os.path.join(settings.CHROOT_ROOT, 'tmp') if settings.CHROOT_ROOT else None) manifest_filename = manifest_name_for_project(project) try: # Resources resource_root = 'resources' os.makedirs(os.path.join(base_dir, resource_root, 'images')) os.makedirs(os.path.join(base_dir, resource_root, 'fonts')) os.makedirs(os.path.join(base_dir, resource_root, 'data')) if project.project_type == 'native': # Source code create_source_files(project, base_dir) manifest_dict = generate_manifest_dict(project, resources) open(os.path.join(base_dir, manifest_filename), 'w').write(json.dumps(manifest_dict)) for f in resources: target_dir = os.path.abspath( os.path.join(base_dir, resource_root, ResourceFile.DIR_MAP[f.kind])) abs_target = os.path.abspath( os.path.join(target_dir, f.file_name)) f.copy_all_variants_to_dir(target_dir) # Reconstitute the SDK open(os.path.join(base_dir, 'wscript'), 'w').write(generate_wscript_file(project)) open(os.path.join(base_dir, 'pebble-jshintrc'), 'w').write(generate_jshint_file(project)) elif project.project_type == 'simplyjs': shutil.rmtree(base_dir) shutil.copytree(settings.SIMPLYJS_ROOT, base_dir) manifest_dict = generate_simplyjs_manifest_dict(project) js = '\n\n'.join(x.get_contents() for x in source_files if x.file_name.endswith('.js')) escaped_js = json.dumps(js) build_result.save_simplyjs(js) open(os.path.join(base_dir, manifest_filename), 'w').write(json.dumps(manifest_dict)) open(os.path.join(base_dir, 'src', 'js', 'zzz_userscript.js'), 'w').write(""" (function() { simply.mainScriptSource = %s; })(); """ % escaped_js) elif project.project_type == 'pebblejs': shutil.rmtree(base_dir) shutil.copytree(settings.PEBBLEJS_ROOT, base_dir) manifest_dict = generate_pebblejs_manifest_dict(project, resources) create_source_files(project, base_dir) for f in resources: if f.kind not in ('png', 'bitmap'): continue target_dir = os.path.abspath( os.path.join(base_dir, resource_root, ResourceFile.DIR_MAP[f.kind])) abs_target = os.path.abspath( os.path.join(target_dir, f.file_name)) if not abs_target.startswith(target_dir): raise Exception("Suspicious filename: %s" % f.file_name) f.get_default_variant().copy_to_path(abs_target) open(os.path.join(base_dir, manifest_filename), 'w').write(json.dumps(manifest_dict)) # Build the thing cwd = os.getcwd() success = False output = '' build_start_time = now() try: os.chdir(base_dir) # Install dependencies if there are any dependencies = project.get_dependencies() if dependencies: # Checking for path-based dependencies is performed by the database so in theory we shouldn't need to do # it here but we will do it anyway just to be extra safe. for version in dependencies.values(): validate_dependency_version(version) npm_command = [ settings.NPM_BINARY, "install", "--ignore-scripts" ] output = subprocess.check_output( npm_command, stderr=subprocess.STDOUT, preexec_fn=_set_resource_limits) subprocess.check_output([settings.NPM_BINARY, "dedupe"], stderr=subprocess.STDOUT, preexec_fn=_set_resource_limits) if project.sdk_version == '2': environ = os.environ.copy() environ['PATH'] = '{}:{}'.format(settings.ARM_CS_TOOLS, environ['PATH']) command = [settings.SDK2_PEBBLE_WAF, "configure", "build"] elif project.sdk_version == '3': environ = os.environ.copy() environ['PATH'] = '{}:{}'.format(settings.ARM_CS_TOOLS, environ['PATH']) command = [settings.SDK3_PEBBLE_WAF, "configure", "build"] else: raise Exception("invalid sdk version.") output += subprocess.check_output(command, stderr=subprocess.STDOUT, preexec_fn=_set_resource_limits, env=environ) except subprocess.CalledProcessError as e: output = e.output logger.warning("Build command failed with error:\n%s\n", output) success = False except Exception as e: logger.exception("Unexpected exception during build") success = False output = str(e) else: success = True temp_file = os.path.join(base_dir, 'build', '%s.pbw' % os.path.basename(base_dir)) if not os.path.exists(temp_file): success = False logger.warning("Success was a lie.") finally: build_end_time = now() os.chdir(cwd) if success: # Try reading file sizes out of it first. try: s = os.stat(temp_file) build_result.total_size = s.st_size # Now peek into the zip to see the component parts with zipfile.ZipFile(temp_file, 'r') as z: store_size_info(project, build_result, 'aplite', z) store_size_info(project, build_result, 'basalt', z) store_size_info(project, build_result, 'chalk', z) except Exception as e: logger.warning("Couldn't extract filesizes: %s", e) # Try pulling out debug information. if project.sdk_version == '2': save_debug_info( base_dir, build_result, BuildResult.DEBUG_APP, 'aplite', os.path.join(base_dir, 'build', 'pebble-app.elf')) save_debug_info( base_dir, build_result, BuildResult.DEBUG_WORKER, 'aplite', os.path.join(base_dir, 'build', 'pebble-worker.elf')) else: save_debug_info( base_dir, build_result, BuildResult.DEBUG_APP, 'aplite', os.path.join(base_dir, 'build', 'aplite/pebble-app.elf')) save_debug_info( base_dir, build_result, BuildResult.DEBUG_WORKER, 'aplite', os.path.join(base_dir, 'build', 'aplite/pebble-worker.elf')) save_debug_info( base_dir, build_result, BuildResult.DEBUG_APP, 'basalt', os.path.join(base_dir, 'build', 'basalt/pebble-app.elf')) save_debug_info( base_dir, build_result, BuildResult.DEBUG_WORKER, 'basalt', os.path.join(base_dir, 'build', 'basalt/pebble-worker.elf')) save_debug_info( base_dir, build_result, BuildResult.DEBUG_APP, 'chalk', os.path.join(base_dir, 'build', 'chalk/pebble-app.elf')) save_debug_info( base_dir, build_result, BuildResult.DEBUG_WORKER, 'chalk', os.path.join(base_dir, 'build', 'chalk/pebble-worker.elf')) build_result.save_pbw(temp_file) build_result.save_build_log(output or 'Failed to get output') build_result.state = BuildResult.STATE_SUCCEEDED if success else BuildResult.STATE_FAILED build_result.finished = now() build_result.save() data = { 'data': { 'cloudpebble': { 'build_id': build_result.id, 'job_run_time': (build_result.finished - build_result.started).total_seconds(), }, 'build_time': (build_end_time - build_start_time).total_seconds(), } } event_name = 'app_build_succeeded' if success else 'app_build_failed' send_td_event(event_name, data, project=project) except Exception as e: logger.exception("Build failed due to internal error: %s", e) build_result.state = BuildResult.STATE_FAILED build_result.finished = now() try: build_result.save_build_log("Something broke:\n%s" % e) except: pass build_result.save() finally: shutil.rmtree(base_dir)