Skip to content

Commit

Permalink
Starts work on adding recipe upgrade feature (#539)
Browse files Browse the repository at this point in the history
* Starts work on adding recipe upgrade feature

The package that this commit relies on is not currently available in
conda-forge. Viewer discretion is advised.

- First-pass attempt at integrating `conda-recipe-manager` into Grayskull for
  the purposes of generating recipes in the V1 format.

* Forgot to uncomment line in environment file before making draft PR

* Adds missing preprocessor phase

* Fixes ruamel issue with a workaround
  • Loading branch information
schuylermartin45 authored Jul 28, 2024
1 parent a34b757 commit 3b83710
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 4 deletions.
1 change: 1 addition & 0 deletions environment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ dependencies:
- libcblas
- beautifulsoup4
- semver >=3.0.0,<4.0.0
- conda-recipe-manager >=0.2.0
22 changes: 20 additions & 2 deletions grayskull/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@ def init_parser():
help="If sections are specified, grayskull will populate just the sections "
"informed.",
)
cran_parser.add_argument(
"--use-v1-format",
"-u",
default=False,
action="store_true",
dest="use_v1_format",
help="Returns a recipe file in the V1 format, used by rattler-build."
" NOTE: This is experimental.",
)
# create parser for pypi
pypi_parser = subparsers.add_parser("pypi", help="Options to generate PyPI recipes")
pypi_parser.add_argument(
Expand Down Expand Up @@ -244,6 +253,15 @@ def init_parser():
dest="licence_exclude_folders",
help="Exclude folders when searching for licence.",
)
pypi_parser.add_argument(
"--use-v1-format",
"-u",
default=False,
action="store_true",
dest="use_v1_format",
help="Returns a recipe file in the V1 format, used by rattler-build."
" NOTE: This is experimental.",
)

return parser

Expand Down Expand Up @@ -319,7 +337,7 @@ def generate_recipes_from_list(list_pkgs, args):
if args.sections_populate is None or "extra" in args.sections_populate:
add_extra_section(recipe, args.maintainers)

generate_recipe(recipe, config, args.output)
generate_recipe(recipe, config, args.output, args.use_v1_format)
print_msg(
f"\n{Fore.GREEN}#### Recipe generated on "
f"{os.path.realpath(args.output)} for {pkg_name} ####\n\n"
Expand Down Expand Up @@ -365,7 +383,7 @@ def generate_r_recipes_from_list(list_pkgs, args):
if args.sections_populate is None or "extra" in args.sections_populate:
add_extra_section(recipe, args.maintainers)

generate_recipe(recipe, config, args.output)
generate_recipe(recipe, config, args.output, args.use_v1_format)
print_msg(
f"\n{Fore.GREEN}#### Recipe generated on "
f"{os.path.realpath(args.output)} for {pkg_name} ####\n\n"
Expand Down
28 changes: 26 additions & 2 deletions grayskull/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
from glob import glob
from pathlib import Path
from shutil import copyfile
from typing import List, Optional, Union
from typing import Final, List, Optional, Union

from conda_recipe_manager.parser.recipe_parser_convert import RecipeParserConvert
from ruamel.yaml import YAML
from ruamel.yaml.comments import CommentedMap
from souschef.recipe import Recipe
Expand Down Expand Up @@ -194,11 +195,13 @@ def generate_recipe(
recipe: Recipe,
config,
folder_path: Union[str, Path] = ".",
use_v1_format: bool = False,
):
"""Write the recipe in a location. It will create a folder with the
package name and the recipe will be there.
:param folder_path: Path to the folder
:param use_v1_format: If set to True, return a recipe in the V1 format
"""
if recipe["package"]["name"].value.startswith("r-{{"):
pkg_name = f"r-{config.name}"
Expand All @@ -215,18 +218,39 @@ def generate_recipe(
logging.debug(f"Generating recipe on: {recipe_dir}")
if not recipe_dir.is_dir():
recipe_dir.mkdir()
recipe_path = recipe_dir / "meta.yaml"
recipe_path = recipe_dir / "recipe.yaml" if use_v1_format else "meta.yaml"
recipe_folder = recipe_dir
add_new_lines_after_section(recipe.yaml)

clean_yaml(recipe)
recipe.save(recipe_path)
if use_v1_format:
upgrade_v0_recipe_to_v1(recipe_path)
for file_to_recipe in config.files_to_copy:
name = file_to_recipe.split(os.path.sep)[-1]
if os.path.isfile(file_to_recipe):
copyfile(file_to_recipe, os.path.join(recipe_folder, name))


def upgrade_v0_recipe_to_v1(recipe_path: Path) -> None:
"""
Takes a V0 (pre CEP-13) recipe and converts it to a V1 (post CEP-13) recipe file.
Upgraded recipes are saved to the provided file path.
NOTE: As of writing, we need ruamel to dump the text to a file first so we can
get the original recipe file as a string. This is a workaround until we
can get ruamel to dump to a string stream without blowing up on the
JINJA plugin.
:param recipe_path: Path to that contains the original recipe file to modify.
"""
recipe_content: Final[str] = RecipeParserConvert.pre_process_recipe_text(
recipe_path.read_text()
)
recipe_converter = RecipeParserConvert(recipe_content)
v1_content, _, _ = recipe_converter.render_to_v1_recipe_format()
recipe_path.write_text(v1_content, encoding="utf-8")


def add_new_lines_after_section(recipe_yaml: CommentedMap) -> CommentedMap:
for section in recipe_yaml.keys():
if section == "package":
Expand Down

0 comments on commit 3b83710

Please sign in to comment.