def copy_recipe(m, config): if config.include_recipe and m.include_recipe() and bool(m.path): recipe_dir = join(config.info_dir, 'recipe') os.makedirs(recipe_dir) for fn in os.listdir(m.path): if fn.startswith('.'): continue src_path = join(m.path, fn) dst_path = join(recipe_dir, fn) copy_into(src_path, dst_path, timeout=config.timeout) # store the rendered meta.yaml file, plus information about where it came from # and what version of conda-build created it original_recipe = os.path.join(m.path, 'meta.yaml') rendered = output_yaml(m) if not open(original_recipe).read() == rendered: with open(join(recipe_dir, "meta.yaml"), 'w') as f: f.write("# This file created by conda-build {}\n".format( __version__)) f.write("# meta.yaml template originally from:\n") f.write("# " + source.get_repository_info(m.path) + "\n") f.write( "# ------------------------------------------------\n\n") f.write(rendered) copy_into(original_recipe, os.path.join(recipe_dir, 'meta.yaml.template'), timeout=config.timeout)
def main(): p = get_render_parser() p.add_argument( '-f', '--file', action="store", help="write YAML to file, given as argument here.\ Overwrites existing files." ) # we do this one separately because we only allow one entry to conda render p.add_argument( 'recipe', action="store", metavar='RECIPE_PATH', choices=RecipeCompleter(), help="Path to recipe directory.", ) # this is here because we have a different default than build p.add_argument( '--verbose', action='store_true', help='Enable verbose output from download tools and progress updates', ) args = p.parse_args() set_language_env_vars(args, p) metadata, _, _ = render_recipe(find_recipe(args.recipe), no_download_source=args.no_source, verbose=args.verbose) if args.output: print(bldpkg_path(metadata)) else: print(output_yaml(metadata, args.file))
def copy_recipe(m, config): if config.include_recipe and m.include_recipe(): recipe_dir = join(config.info_dir, 'recipe') os.makedirs(recipe_dir) if os.path.isdir(m.path): for fn in os.listdir(m.path): if fn.startswith('.'): continue src_path = join(m.path, fn) dst_path = join(recipe_dir, fn) copy_into(src_path, dst_path, timeout=config.timeout) # store the rendered meta.yaml file, plus information about where it came from # and what version of conda-build created it original_recipe = os.path.join(m.path, 'meta.yaml') else: original_recipe = "" rendered = output_yaml(m) if not original_recipe or not open(original_recipe).read() == rendered: with open(join(recipe_dir, "meta.yaml"), 'w') as f: f.write("# This file created by conda-build {}\n".format(__version__)) if original_recipe: f.write("# meta.yaml template originally from:\n") f.write("# " + source.get_repository_info(m.path) + "\n") f.write("# ------------------------------------------------\n\n") f.write(rendered) if original_recipe: copy_into(original_recipe, os.path.join(recipe_dir, 'meta.yaml.template'), timeout=config.timeout)
def execute(args): p, args = parse_args(args) config = Config() set_language_env_vars(args, p, config) with LoggingContext(logging.CRITICAL + 1): metadata, _, _ = render_recipe(args.recipe, no_download_source=args.no_source, config=config) if args.output: print(bldpkg_path(metadata)) else: print(output_yaml(metadata, args.file))
def execute(args): p, args = parse_args(args) config = Config() set_language_env_vars(args, p, config) metadata, _, _ = render_recipe(args.recipe, no_download_source=args.no_source, config=config) if args.output: logging.basicConfig(level=logging.ERROR) silence_loggers(show_warnings_and_errors=False) print(bldpkg_path(metadata)) else: logging.basicConfig(level=logging.INFO) print(output_yaml(metadata, args.file))
def execute(args): p, args = parse_args(args) config = Config() set_language_env_vars(args, p, config) metadata, _, _ = render_recipe(args.recipe, no_download_source=args.no_source, config=config) if args.output: logging.basicConfig(level=logging.ERROR) silence_loggers(show_warnings_and_errors=False) print(bldpkg_path(metadata, config=config)) else: logging.basicConfig(level=logging.INFO) print(output_yaml(metadata, args.file))
def output_yaml(metadata, file_path=None): """Save a rendered recipe in its final form to the path given by file_path""" from conda_build.render import output_yaml return output_yaml(metadata, file_path)
def output_yaml(metadata, file_path=None): from conda_build.render import output_yaml return output_yaml(metadata, file_path)
def create_info_files(m, files, include_recipe=True): ''' Creates the metadata files that will be stored in the built package. :param m: Package metadata :type m: Metadata :param files: Paths to files to include in package :type files: list of str :param include_recipe: Whether or not to include the recipe (True by default) :type include_recipe: bool ''' if not isdir(config.info_dir): os.makedirs(config.info_dir) if include_recipe: recipe_dir = join(config.info_dir, 'recipe') os.makedirs(recipe_dir) for fn in os.listdir(m.path): if fn.startswith('.'): continue src_path = join(m.path, fn) dst_path = join(recipe_dir, fn) if isdir(src_path): shutil.copytree(src_path, dst_path) else: shutil.copy(src_path, dst_path) # store the rendered meta.yaml file, plus information about where it came from # and what version of conda-build created it metayaml = output_yaml(m) with open(join(recipe_dir, "meta.yaml.rendered"), 'w') as f: f.write( "# This file created by conda-build {}\n".format(__version__)) f.write("# meta.yaml template originally from:\n") f.write("# " + source.get_repository_info(m.path) + "\n") f.write("# ------------------------------------------------\n\n") f.write(metayaml) license_file = m.get_value('about/license_file') if license_file: shutil.copyfile(join(source.get_dir(), license_file), join(config.info_dir, 'LICENSE.txt')) readme = m.get_value('about/readme') if readme: src = join(source.get_dir(), readme) if not isfile(src): sys.exit("Error: no readme file: %s" % readme) dst = join(config.info_dir, readme) shutil.copyfile(src, dst) if os.path.split(readme)[1] not in { "README.md", "README.rst", "README" }: print( "WARNING: anaconda.org only recognizes about/readme as README.md and README.rst", file=sys.stderr) # noqa info_index = m.info_index() pin_depends = m.get_value('build/pin_depends') if pin_depends: dists = get_run_dists(m) with open(join(config.info_dir, 'requires'), 'w') as fo: fo.write("""\ # This file as created when building: # # %s.tar.bz2 (on '%s') # # It can be used to create the runtime environment of this package using: # $ conda create --name <env> --file <this file> """ % (m.dist(), cc.subdir)) for dist in sorted(dists + [m.dist()]): fo.write('%s\n' % '='.join(dist.rsplit('-', 2))) if pin_depends == 'strict': info_index['depends'] = [ ' '.join(dist.rsplit('-', 2)) for dist in dists ] # Deal with Python 2 and 3's different json module type reqs mode_dict = {'mode': 'w', 'encoding': 'utf-8'} if PY3 else {'mode': 'wb'} with open(join(config.info_dir, 'index.json'), **mode_dict) as fo: json.dump(info_index, fo, indent=2, sort_keys=True) with open(join(config.info_dir, 'about.json'), 'w') as fo: d = {} for key in ('home', 'dev_url', 'doc_url', 'license_url', 'license', 'summary', 'description', 'license_family'): value = m.get_value('about/%s' % key) if value: d[key] = value json.dump(d, fo, indent=2, sort_keys=True) if on_win: # make sure we use '/' path separators in metadata files = [_f.replace('\\', '/') for _f in files] with open(join(config.info_dir, 'files'), **mode_dict) as fo: if m.get_value('build/noarch_python'): fo.write('\n') else: for f in files: fo.write(f + '\n') files_with_prefix = sorted(have_prefix_files(files)) binary_has_prefix_files = m.binary_has_prefix_files() text_has_prefix_files = m.has_prefix_files() ignore_files = m.ignore_prefix_files() if ignore_files: # do we have a list of files, or just ignore everything? if hasattr(ignore_files, "__iter__"): files_with_prefix = [ f for f in files_with_prefix if f[2] not in ignore_files ] binary_has_prefix_files = [ f for f in binary_has_prefix_files if f[2] not in ignore_files ] # noqa text_has_prefix_files = [ f for f in text_has_prefix_files if f[2] not in ignore_files ] else: files_with_prefix = [] if files_with_prefix and not m.get_value('build/noarch_python'): auto_detect = m.get_value('build/detect_binary_files_with_prefix') if on_win: # Paths on Windows can contain spaces, so we need to quote the # paths. Fortunately they can't contain quotes, so we don't have # to worry about nested quotes. fmt_str = '"%s" %s "%s"\n' else: # Don't do it everywhere because paths on Unix can contain quotes, # and we don't have a good method of escaping, and because older # versions of conda don't support quotes in has_prefix fmt_str = '%s %s %s\n' with open(join(config.info_dir, 'has_prefix'), 'w') as fo: for pfix, mode, fn in files_with_prefix: if (fn in text_has_prefix_files): # register for text replacement, regardless of mode fo.write(fmt_str % (pfix, 'text', fn)) text_has_prefix_files.remove(fn) elif ((mode == 'binary') and (fn in binary_has_prefix_files)): print("Detected hard-coded path in binary file %s" % fn) fo.write(fmt_str % (pfix, mode, fn)) binary_has_prefix_files.remove(fn) elif (auto_detect or (mode == 'text')): print("Detected hard-coded path in %s file %s" % (mode, fn)) fo.write(fmt_str % (pfix, mode, fn)) else: print("Ignored hard-coded path in %s" % fn) # make sure we found all of the files expected errstr = "" for f in text_has_prefix_files: errstr += "Did not detect hard-coded path in %s from has_prefix_files\n" % f for f in binary_has_prefix_files: errstr += "Did not detect hard-coded path in %s from binary_has_prefix_files\n" % f if errstr: raise RuntimeError(errstr) no_link = m.get_value('build/no_link') if no_link: if not isinstance(no_link, list): no_link = [no_link] with open(join(config.info_dir, 'no_link'), 'w') as fo: for f in files: if any(fnmatch.fnmatch(f, p) for p in no_link): fo.write(f + '\n') if m.get_value('source/git_url'): with io.open(join(config.info_dir, 'git'), 'w', encoding='utf-8') as fo: source.git_info(fo) if m.get_value('app/icon'): shutil.copyfile(join(m.path, m.get_value('app/icon')), join(config.info_dir, 'icon.png'))
def create_info_files(m, files, include_recipe=True): ''' Creates the metadata files that will be stored in the built package. :param m: Package metadata :type m: Metadata :param files: Paths to files to include in package :type files: list of str :param include_recipe: Whether or not to include the recipe (True by default) :type include_recipe: bool ''' if not isdir(config.info_dir): os.makedirs(config.info_dir) if include_recipe and m.include_recipe(): recipe_dir = join(config.info_dir, 'recipe') os.makedirs(recipe_dir) for fn in os.listdir(m.path): if fn.startswith('.'): continue src_path = join(m.path, fn) dst_path = join(recipe_dir, fn) if isdir(src_path): shutil.copytree(src_path, dst_path) else: shutil.copy(src_path, dst_path) # store the rendered meta.yaml file, plus information about where it came from # and what version of conda-build created it metayaml = output_yaml(m) with open(join(recipe_dir, "meta.yaml.rendered"), 'w') as f: f.write("# This file created by conda-build {}\n".format(__version__)) f.write("# meta.yaml template originally from:\n") f.write("# " + source.get_repository_info(m.path) + "\n") f.write("# ------------------------------------------------\n\n") f.write(metayaml) license_file = m.get_value('about/license_file') if license_file: shutil.copyfile(join(source.get_dir(), license_file), join(config.info_dir, 'LICENSE.txt')) readme = m.get_value('about/readme') if readme: src = join(source.get_dir(), readme) if not isfile(src): sys.exit("Error: no readme file: %s" % readme) dst = join(config.info_dir, readme) shutil.copyfile(src, dst) if os.path.split(readme)[1] not in {"README.md", "README.rst", "README"}: print("WARNING: anaconda.org only recognizes about/readme as README.md and README.rst", file=sys.stderr) # noqa info_index = m.info_index() pin_depends = m.get_value('build/pin_depends') if pin_depends: dists = get_run_dists(m) with open(join(config.info_dir, 'requires'), 'w') as fo: fo.write("""\ # This file as created when building: # # %s.tar.bz2 (on '%s') # # It can be used to create the runtime environment of this package using: # $ conda create --name <env> --file <this file> """ % (m.dist(), cc.subdir)) for dist in sorted(dists + [m.dist()]): fo.write('%s\n' % '='.join(dist.split('::', 1)[-1].rsplit('-', 2))) if pin_depends == 'strict': info_index['depends'] = [' '.join(dist.split('::', 1)[-1].rsplit('-', 2)) for dist in dists] # Deal with Python 2 and 3's different json module type reqs mode_dict = {'mode': 'w', 'encoding': 'utf-8'} if PY3 else {'mode': 'wb'} with open(join(config.info_dir, 'index.json'), **mode_dict) as fo: json.dump(info_index, fo, indent=2, sort_keys=True) with open(join(config.info_dir, 'about.json'), 'w') as fo: d = {} for key in ('home', 'dev_url', 'doc_url', 'license_url', 'license', 'summary', 'description', 'license_family'): value = m.get_value('about/%s' % key) if value: d[key] = value json.dump(d, fo, indent=2, sort_keys=True) if on_win: # make sure we use '/' path separators in metadata files = [_f.replace('\\', '/') for _f in files] with open(join(config.info_dir, 'files'), **mode_dict) as fo: if m.get_value('build/noarch_python'): fo.write('\n') else: for f in files: fo.write(f + '\n') files_with_prefix = sorted(have_prefix_files(files)) binary_has_prefix_files = m.binary_has_prefix_files() text_has_prefix_files = m.has_prefix_files() ignore_files = m.ignore_prefix_files() if ignore_files: # do we have a list of files, or just ignore everything? if hasattr(ignore_files, "__iter__"): files_with_prefix = [f for f in files_with_prefix if f[2] not in ignore_files] binary_has_prefix_files = [f for f in binary_has_prefix_files if f[2] not in ignore_files] # noqa text_has_prefix_files = [f for f in text_has_prefix_files if f[2] not in ignore_files] else: files_with_prefix = [] if files_with_prefix and not m.get_value('build/noarch_python'): auto_detect = m.get_value('build/detect_binary_files_with_prefix') if on_win: # Paths on Windows can contain spaces, so we need to quote the # paths. Fortunately they can't contain quotes, so we don't have # to worry about nested quotes. fmt_str = '"%s" %s "%s"\n' else: # Don't do it everywhere because paths on Unix can contain quotes, # and we don't have a good method of escaping, and because older # versions of conda don't support quotes in has_prefix fmt_str = '%s %s %s\n' with open(join(config.info_dir, 'has_prefix'), 'w') as fo: for pfix, mode, fn in files_with_prefix: if (fn in text_has_prefix_files): # register for text replacement, regardless of mode fo.write(fmt_str % (pfix, 'text', fn)) text_has_prefix_files.remove(fn) elif ((mode == 'binary') and (fn in binary_has_prefix_files)): print("Detected hard-coded path in binary file %s" % fn) fo.write(fmt_str % (pfix, mode, fn)) binary_has_prefix_files.remove(fn) elif (auto_detect or (mode == 'text')): print("Detected hard-coded path in %s file %s" % (mode, fn)) fo.write(fmt_str % (pfix, mode, fn)) else: print("Ignored hard-coded path in %s" % fn) # make sure we found all of the files expected errstr = "" for f in text_has_prefix_files: errstr += "Did not detect hard-coded path in %s from has_prefix_files\n" % f for f in binary_has_prefix_files: errstr += "Did not detect hard-coded path in %s from binary_has_prefix_files\n" % f if errstr: raise RuntimeError(errstr) no_link = m.get_value('build/no_link') if no_link: if not isinstance(no_link, list): no_link = [no_link] with open(join(config.info_dir, 'no_link'), 'w') as fo: for f in files: if any(fnmatch.fnmatch(f, p) for p in no_link): fo.write(f + '\n') if m.get_value('source/git_url'): with io.open(join(config.info_dir, 'git'), 'w', encoding='utf-8') as fo: source.git_info(fo) if m.get_value('app/icon'): shutil.copyfile(join(m.path, m.get_value('app/icon')), join(config.info_dir, 'icon.png'))