Esempio n. 1
0
def test_empty_recipe(tmpdir):
    r = Recipe('recipes/sina', 'recipes/')
    with pytest.raises(EmptyRecipe):
        r.load_from_string("")
    with open(op.join(tmpdir, 'meta.yaml'), "w"):
        pass
    with pytest.raises(EmptyRecipe):
        Recipe.from_file(str(tmpdir), str(tmpdir))
    res = Recipe.from_file(str(tmpdir), str(tmpdir), return_exceptions=True)
    assert isinstance(res, EmptyRecipe)
Esempio n. 2
0
 def _run(contents, expect_pass=True):
     """
     Build the recipe and run the lint function on the rendered recipe
     """
     r = Recipes(contents, from_string=True)
     r.write_recipes()
     assert len(r.recipe_dirs) == 1
     name = list(r.recipe_dirs.keys())[0]
     recipe = Recipe.from_file(r.basedir, r.recipe_dirs[name])
     metas = []
     for platform in ["linux", "osx"]:
         config = utils.load_conda_build_config(platform=platform, trim_skip=False)
         metas.extend(utils.load_all_meta(r.recipe_dirs[name], config=config, finalize=False))
     if expect_pass:
         assert func(recipe, metas) is None, "lint did not pass"
     else:
         assert func(recipe, metas) is not None, "lint did not fail"
 def _run(contents, expect_pass=True):
     """
     Build the recipe and run the lint function on the rendered recipe
     """
     r = Recipes(contents, from_string=True)
     r.write_recipes()
     assert len(r.recipe_dirs) == 1
     name = list(r.recipe_dirs.keys())[0]
     recipe = Recipe.from_file(r.basedir, r.recipe_dirs[name])
     metas = []
     for platform in ["linux", "osx"]:
         config = utils.load_conda_build_config(platform=platform,
                                                trim_skip=False)
         metas.extend(
             utils.load_all_meta(r.recipe_dirs[name],
                                 config=config,
                                 finalize=False))
     if expect_pass:
         assert func(recipe, metas) is None, "lint did not pass"
     else:
         assert func(recipe, metas) is not None, "lint did not fail"
Esempio n. 4
0
def generate_readme(recipe_basedir, output_dir, folder, repodata, renderer):
    """Generates README.rst for the recipe in folder

    Args:
      folder: Toplevel folder name in recipes directory
      repodata: RepoData object
      renderer: Renderer object

    Returns:
      List of template_options for each concurrent version for
      which meta.yaml files exist in the recipe folder and its
      subfolders
    """
    output_file = op.join(output_dir, folder, 'README.rst')

    # Select meta yaml
    meta_fname = op.join(recipe_basedir, folder, 'meta.yaml')
    if not op.exists(meta_fname):
        for item in os.listdir(op.join(recipe_basedir, folder)):
            dname = op.join(recipe_basedir, folder, item)
            if op.isdir(dname):
                fname = op.join(dname, 'meta.yaml')
                if op.exists(fname):
                    meta_fname = fname
                    break
        else:
            logger.error("No 'meta.yaml' found in %s", folder)
            return []
    meta_relpath = meta_fname[len(recipe_basedir) + 1:]

    # Read the meta.yaml file(s)
    try:
        recipe = Recipe.from_file(recipe_basedir, meta_fname)
    except RecipeError as e:
        logger.error("Unable to process %s: %s", meta_fname, e)
        return []

    # Format the README
    packages = []
    for package in sorted(list(set(recipe.package_names))):
        versions_in_channel = set(
            repodata.get_package_data(['version', 'build_number'],
                                      channels='bioconda',
                                      name=package))
        sorted_versions = sorted(versions_in_channel,
                                 key=lambda x: (VersionOrder(x[0]), x[1]),
                                 reverse=True)

        if sorted_versions:
            depends = [
                depstring.split(' ', 1) if ' ' in depstring else
                (depstring, '') for depstring in repodata.get_package_data(
                    'depends',
                    name=package,
                    version=sorted_versions[0][0],
                    build_number=sorted_versions[0][1],
                )[0]
            ]
        else:
            depends = []

        packages.append({
            'name':
            package,
            'versions': ['-'.join(str(w) for w in v) for v in sorted_versions],
            'depends':
            depends,
        })

    template_options = {
        'name': recipe.name,
        'about': recipe.get('about', None),
        'extra': recipe.get('extra', None),
        'recipe': recipe,
        'packages': packages,
    }

    renderer.render_to_file(output_file, 'readme.rst_t', template_options)
    return [output_file]
Esempio n. 5
0
def generate_readme(recipe_basedir, output_dir, folder, repodata, renderer):
    """Generates README.rst for the recipe in folder

    Args:
      folder: Toplevel folder name in recipes directory
      repodata: RepoData object
      renderer: Renderer object

    Returns:
      List of template_options for each concurrent version for
      which meta.yaml files exist in the recipe folder and its
      subfolders
    """
    output_file = op.join(output_dir, folder, 'README.rst')

    # Select meta yaml
    meta_fname = op.join(recipe_basedir, folder, 'meta.yaml')
    if not op.exists(meta_fname):
        for item in os.listdir(op.join(recipe_basedir, folder)):
            dname = op.join(recipe_basedir, folder, item)
            if op.isdir(dname):
                fname = op.join(dname, 'meta.yaml')
                if op.exists(fname):
                    meta_fname = fname
                    break
        else:
            logger.error("No 'meta.yaml' found in %s", folder)
            return []
    meta_relpath = meta_fname[len(recipe_basedir)+1:]

    # Read the meta.yaml file(s)
    try:
        recipe = Recipe.from_file(recipe_basedir, meta_fname)
    except RecipeError as e:
        logger.error("Unable to process %s: %s", meta_fname, e)
        return []

    # Format the README
    packages = []
    for package in sorted(list(set(recipe.package_names))):
        versions_in_channel = set(repodata.get_package_data(['version', 'build_number'],
                                                            channels='bioconda', name=package))
        sorted_versions = sorted(versions_in_channel,
                                 key=lambda x: (VersionOrder(x[0]), x[1]),
                                 reverse=True)

        if sorted_versions:
            depends = [
                depstring.split(' ', 1) if ' ' in depstring else (depstring, '')
                for depstring in
                repodata.get_package_data('depends', name=package,
                                          version=sorted_versions[0][0],
                                          build_number=sorted_versions[0][1],
                )[0]
            ]
        else:
            depends = []

        packages.append({
            'name': package,
            'versions': ['-'.join(str(w) for w in v) for v in sorted_versions],
            'depends' : depends,
        })

    template_options = {
        'name': recipe.name,
        'about': recipe.get('about'),
        'extra': recipe.get('extra'),
        'recipe': recipe,
        'packages': packages,
    }

    renderer.render_to_file(output_file, 'readme.rst_t', template_options)
    return [output_file]
Esempio n. 6
0
def create_recipe(bioconda_recipe_path, recipe_path, strategy):
    # Load meta.yaml file and instantiate Recipe object
    temp_folder_name = hashlib.md5(recipe_path.encode("utf-8")).hexdigest()
    recipes_pkg_path = os.path.join(bioconda_recipe_path, "recipes",
                                    temp_folder_name)
    try:
        os.mkdir(recipes_pkg_path)
        copytree(recipe_path, recipes_pkg_path)
        bioconda_recipe = bioconda_utils_Recipe.from_file(
            bioconda_recipe_path, recipes_pkg_path)
    finally:
        rmtree(recipes_pkg_path)
    name = bioconda_recipe.get("package/name")
    version = bioconda_recipe.get("package/version")
    recipe = Recipe(name, version, recipe_path, strategy)

    # Parse values from file to Recipe object
    try:
        recipe.add_source_url(bioconda_recipe.get("source/url"))
    except KeyError:
        sys.exit(
            "No source url was found in the given meta.yaml file, please add a source url"
        )
    recipe.add_build_number(bioconda_recipe.get("build/number", "0"))
    try:
        recipe.add_checksum_sha256(bioconda_recipe.get("source/sha256"))
    except KeyError:
        recipe.add_checksum_md5(
            bioconda_recipe.get(
                "source/md5",
                calculate_md5_checksum(bioconda_recipe.get("source/url"))))
    build_requirements = bioconda_recipe.get("requirements/build", [])
    for requirement in build_requirements:
        recipe.add_requirement(requirement, "build")
    host_requirements = bioconda_recipe.get("requirements/host", [])
    for requirement in host_requirements:
        recipe.add_requirement(requirement, "host", host_only=True)
    run_requirements = bioconda_recipe.get("requirements/run", [])
    for requirement in run_requirements:
        recipe.add_requirement(requirement, "run")
    try:
        recipe.add_test_commands(bioconda_recipe.get("test/commands"))
    except KeyError:
        pass
    try:
        recipe.add_test_files_with_list(bioconda_recipe.get("test/files"))
    except KeyError:
        pass
    try:
        recipe.add_patches_with_list(bioconda_recipe.get("source/patches"),
                                     recipe_path)
    except KeyError:
        pass
    # Conda will not accept the compiler dependency given by bioconda
    try:
        build_requirements = recipe.recipe_dict["requirements"]["build"]
        if "compiler_c" in build_requirements:
            recipe.recipe_dict["requirements"]["build"].remove("compiler_c")
            recipe.recipe_dict["requirements"]["build"].append(
                "{{compiler('c')}}")
        if "compiler_cxx" in build_requirements:
            recipe.recipe_dict["requirements"]["build"].remove("compiler_cxx")
            recipe.recipe_dict["requirements"]["build"].append(
                "{{compiler('cxx')}}")
    except KeyError:
        if strategy == "cmake":
            recipe.add_requirement("{{ compiler('c') }}", "build")
            recipe.add_requirement("cmake", "build")
            recipe.add_requirement("make", "build")
        elif strategy == "autoconf":
            recipe.add_requirement("make", "build")
            recipe.add_requirement("autoconf", "build")
            recipe.add_requirement("automake", "build")
            recipe.add_requirement("{{ compiler('c') }}", "build")
    if strategy.startswith("python"):
        try:
            host_environment = recipe.recipe_dict["requirements"]["host"]
            if not any(
                    map(lambda req: req.startswith("python"),
                        host_environment)):
                if strategy == "python2":
                    recipe.add_requirement("python =2.7", "host")
                else:
                    recipe.add_requirement("python >=3", "host")
        except KeyError:
            if strategy == "python2":
                recipe.add_requirement("python =2.7", "host")
            else:
                recipe.add_requirement("python >=3", "host")
    try:
        recipe.script = bioconda_recipe.get("build/script")
    except KeyError:
        pass
    try:
        recipe.add_command_imports(bioconda_recipe.get("test/imports"))
    except KeyError:
        pass
    try:
        recipe.add_entry_point(bioconda_recipe.get("build/entry_points"))
    except KeyError:
        pass
    try:
        recipe.add_noarch(bioconda_recipe.get("build/noarch"))
    except KeyError:
        pass
    try:
        recipe.add_test_requires(bioconda_recipe.get("test/requires"))
    except KeyError:
        pass
    recipe.increment_build_number()
    return recipe
Esempio n. 7
0
def test_file_not_found():
    with pytest.raises(MissingMetaYaml):
        Recipe.from_file('/', '/doesnotexist')
    res = Recipe.from_file('/', '/doesnotexist', return_exceptions=True)
    assert isinstance(res, MissingMetaYaml)
Esempio n. 8
0
def test_stub():
    r = Recipe('recipes/sina', 'recipes/')
    assert r.path == 'recipes/sina/meta.yaml'
    assert r.relpath == 'sina/meta.yaml'
    assert r.reldir == 'sina'
    assert str(r) == 'sina'
Esempio n. 9
0
def recipe(recipe_dir, recipes_folder):
    yield Recipe.from_file(recipes_folder, recipe_dir)
Esempio n. 10
0
def generate_readme(folder, repodata, renderer):
    """Generates README.rst for the recipe in folder

    Args:
      folder: Toplevel folder name in recipes directory
      repodata: RepoData object
      renderer: Renderer object

    Returns:
      List of template_options for each concurrent version for
      which meta.yaml files exist in the recipe folder and its
      subfolders
    """
    # Subfolders correspond to different versions
    versions = []
    for sf in os.listdir(op.join(RECIPE_DIR, folder)):
        if not op.isdir(op.join(RECIPE_DIR, folder, sf)):
            # Not a folder
            continue
        try:
            LooseVersion(sf)
        except ValueError:
            logger.error("'{}' does not look like a proper version!"
                         "".format(sf))
            continue
        versions.append(sf)

    # Read the meta.yaml file(s)
    try:
        recipe = op.join(RECIPE_DIR, folder, "meta.yaml")
        if op.exists(recipe):
            metadata = MetaData(recipe)
            if metadata.version() not in versions:
                versions.insert(0, metadata.version())
        else:
            if versions:
                recipe = op.join(RECIPE_DIR, folder, versions[0], "meta.yaml")
                metadata = MetaData(recipe)
            else:
                # ignore non-recipe folders
                return []
    except UnableToParse as e:
        logger.error("Failed to parse recipe {}".format(recipe))
        raise e

    ## Get all versions and build numbers for data package
    # Select meta yaml
    meta_fname = op.join(RECIPE_DIR, folder, 'meta.yaml')
    if not op.exists(meta_fname):
        for item in os.listdir(op.join(RECIPE_DIR, folder)):
            dname = op.join(RECIPE_DIR, folder, item)
            if op.isdir(dname):
                fname = op.join(dname, 'meta.yaml')
                if op.exists(fname):
                    meta_fname = fname
                    break
        else:
            logger.error("No 'meta.yaml' found in %s", folder)
            return []
    meta_relpath = meta_fname[len(RECIPE_DIR)+1:]

    # Read the meta.yaml file(s)
    try:
        recipe_object = Recipe.from_file(RECIPE_DIR, meta_fname)
    except RecipeError as e:
        logger.error("Unable to process %s: %s", meta_fname, e)
        return []

    # Format the README
    for package in sorted(list(set(recipe_object.package_names))):
        versions_in_channel = set(repodata.get_package_data(['version', 'build_number'],
                                                            channels='ggd-genomics', name=package))
        sorted_versions = sorted(versions_in_channel,
                                 key=lambda x: (VersionOrder(x[0]), x[1]),
                                 reverse=False)
        if sorted_versions:
            depends = [
                depstring.split(' ', 1) if ' ' in depstring else (depstring, '')
                for depstring in
                repodata.get_package_data('depends', name=package,
                                          version=sorted_versions[0][0],
                                          build_number=sorted_versions[0][1],
                )[0]
            ]
        else:
            depends = []



    # Format the README
    name = metadata.name()
    versions_in_channel = repodata.get_versions(name)

    template_options = {
        'name': name,
        'about': (metadata.get_section('about') or {}),
        'species': (metadata.get_section('about')["identifiers"]["species"] if "species" in metadata.get_section('about')["identifiers"] else {}),
        'genome_build': (metadata.get_section('about')["identifiers"]["genome-build"] if "genome-build" in metadata.get_section('about')["identifiers"] else {}),
        'ggd_channel': (metadata.get_section('about')["tags"]["ggd-channel"] if "ggd-channel" in metadata.get_section('about')["tags"] else "genomics"),
        'extra': (metadata.get_section('extra') or {}),
        'versions': ["-".join(str(w) for w in v) for v in sorted_versions],
        'gh_recipes': 'https://github.com/gogetdata/ggd-recipes/tree/master/recipes/',
        'recipe_path': op.dirname(op.relpath(metadata.meta_path, RECIPE_DIR)),
        'Package': '<a href="recipes/{0}/README.html">{0}</a>'.format(name)
    }

    renderer.render_to_file(
        op.join(OUTPUT_DIR, name, 'README.rst'),
        'readme.rst_t',
        template_options)

    recipes = []
    latest_version = "-".join(str(w) for w in sorted_versions[-1])
    for version, version_info in sorted(versions_in_channel.items()):
        t = template_options.copy()
        if 'noarch' in version_info:
            t.update({
                'Linux': '<i class="fa fa-linux"></i>' if 'linux' in version_info else '<i class="fa fa-dot-circle-o"></i>',
                'OSX': '<i class="fa fa-apple"></i>' if 'osx' in version_info else '<i class="fa fa-dot-circle-o"></i>',
                'NOARCH': '<i class="fa fa-desktop"></i>' if 'noarch' in version_info else '',
                'Version': latest_version ## The latest version
                #'Version': version
            })
        else:
            t.update({
                'Linux': '<i class="fa fa-linux"></i>' if 'linux' in version_info else '',
                'OSX': '<i class="fa fa-apple"></i>' if 'osx' in version_info else '',
                'NOARCH': '<i class="fa fa-desktop"></i>' if 'noarch' in version_info else '',
                'Version': latest_version ## The latest version
                #'Version': version
            })
        recipes.append(t)
    return recipes