conda_recipe_manager.parser.recipe_parser_deps
- Description:
Provides an editing-capable variant of the RecipeReaderDeps class.
Classes
|
Extension of the RecipeParser and RecipeReaderDeps classes to enables advanced dependency management abilities. |
- class conda_recipe_manager.parser.recipe_parser_deps.RecipeParserDeps(content: str)[source]
Bases:
RecipeParser
,RecipeReaderDeps
Extension of the RecipeParser and RecipeReaderDeps classes to enables advanced dependency management abilities.
Beware of "The Diamond Problem". This class extends the capabilities of the RecipeParser class with the dependency tooling found in RecipeReaderDeps.
- add_comment(path: str, comment: str) None
Adds a comment to an existing path. If a comment exists, replaces the existing comment. If a selector exists, comment is appended after the selector component of the comment.
- Parameters:
path -- Target path to add a comment to
comment -- Comment to add
- Raises:
KeyError -- If the path provided is not found
ValueError -- If the comment provided is a selector, the empty string, or consists of only whitespace characters
- add_dependency(dep: Dependency, dep_mode: DependencyConflictMode = DependencyConflictMode.REPLACE, sel_mode: SelectorConflictMode = SelectorConflictMode.REPLACE) bool [source]
Convenience function that adds a dependency to a recipe file. The path attribute is used to locate which section and output is being used, but the index position is not guaranteed, unless EXACT_POSITION mode is used.
This function will add new dependency sections (run, host, etc) but it will not add any additional missing infrastructure (like requirements or an outputs section).
- Parameters:
dep -- Dependency to add.
dep_mode -- (Optional) Indicates how duplicate dependencies should be handled. Defaults to replacing the existing dependency. Duplicates match by name only.
sel_mode -- (Optional) Indicates how an existing selector should be handled. Defaults to replacing the existing selector.
- Returns:
The result of the underlying patch command, indicating that a change occurred.
- add_selector(path: str, selector: str | SelectorParser, mode: SelectorConflictMode = SelectorConflictMode.REPLACE) None
Given a path, add a selector (include the surrounding brackets) to the line denoted by path.
- Parameters:
path -- Path to add a selector to
selector -- Selector statement to add
mode -- (Optional) Indicates how to handle a conflict if a selector already exists at this path.
- Raises:
KeyError -- If the path provided is not found
ValueError -- If the selector provided is malformed
- static append_to_path(base_path: str, ext_path: str) str
Convenience function meant to be paired with get_package_paths() to generate extended paths. This handles issues that arise when concatenating paths that do or do not include a trailing/leading / character. Most notably, the root path / inherently contains a trailing /.
- Parameters:
base_path -- Base path, provided by get_package_paths()
ext_path -- Path to append to the end of the base_path
- Returns:
A normalized path constructed by the two provided paths.
- calc_sha256() str
Generates a SHA-256 hash of recipe's contents. This hash is the same as if the current recipe state was written to a file. NOTE: This may not be the same as the original recipe file as the parser will auto-format text.
- Returns:
SHA-256 hash of the current recipe state.
- contains_selector(selector: str) bool
Determines if a selector expression is present in this recipe.
- Parameters:
selector -- Selector to check for.
- Returns:
True if a selector is found in this recipe. False otherwise.
- contains_selector_at_path(path: str) bool
Given a path, determine if a selector exists on that line.
- Parameters:
path -- Target path
- Returns:
True if the selector exists at that path. False otherwise.
- contains_value(path: str) bool
Determines if a value (via a path) is contained in this recipe. This also allows the caller to determine if a path exists.
- Parameters:
path -- JSON patch (RFC 6902)-style path to a value.
- Returns:
True if the path exists. False otherwise.
- contains_variable(var: str) bool
Determines if a variable is set in this recipe.
- Parameters:
var -- Variable to check for.
- Returns:
True if a variable name is found in this recipe. False otherwise.
- del_variable(var: str) None
Remove a variable from the project. If one is not found, no changes are made.
- Parameters:
var -- Variable to delete
- diff() str
Returns a git-like-styled diff of the current recipe state with original state of the recipe. Useful for debugging and providing users with some feedback.
- Returns:
User-friendly displayable string that represents notifications made to the recipe.
- find_value(value: str | int | float | bool | None) list[str]
Given a value, find all the paths that contain that value.
NOTE: This only supports searching for "primitive" values, i.e. you cannot search for collections.
- Parameters:
value -- Value to find in the recipe.
- Raises:
ValueError -- If the value provided is not a primitive type.
- Returns:
List of paths where the value can be found.
- get_all_dependencies() dict[str, list[Dependency]]
Get a parsed representation of all the dependencies found in the recipe.
- Raises:
KeyError -- If a package in the recipe does not have a name
ValueError -- If a recipe contains a package with duplicate names
- Returns:
A structured representation of the dependencies.
- get_comments_table() dict[str, str]
Returns a dictionary containing the location of every comment mapped to the value of the comment. .. note:
- Selectors are not considered to be comments. - Lines containing only comments are currently not addressable by our pathing scheme, so they are omitted. For our current purposes (of upgrading the recipe format) this should be fine. Non-addressable values should be less likely to be removed from patch operations.
- Returns:
Dictionary of paths where comments can be found mapped to the comment found.
- get_dependency_paths() list[str]
Convenience function that returns a list of all dependency lines in a recipe.
- Returns:
A list of all paths in a recipe file that point to dependencies.
- get_package_names_to_path() dict[str, str]
Get a map containing all the packages (artifacts) named in a recipe to their paths in the recipe structure.
- Raises:
KeyError -- If a package in the recipe does not have a name
ValueError -- If a recipe contains a package with duplicate names
- Returns:
Mapping of package name to path where that package is found
- get_package_paths() list[str]
Convenience function that returns the locations of all "outputs" in the /outputs directory AND the root/ top-level of the recipe file. Combined with a call to get_value() with a default value and a for loop, this should easily allow the calling code to handle editing/examining configurations found in:
"Simple" (non-multi-output) recipe files
Multi-output recipe files
- Recipes that have both top-level and multi-output sections. An example can be found here:
https://github.com/AnacondaRecipes/curl-feedstock/blob/master/recipe/meta.yaml
- get_recipe_name() str | None
Convenience function that retrieves the "name" of a recipe file. This can be used as an identifier, but it is not guaranteed to be unique. In V0 recipes and single-output V1 recipes, this is known as the "package name".
In V1 recipe files, the name must be included to pass the schema check that should be enforced by any build system.
- Returns:
The name associated with the recipe file. In the unlikely event that no name is found, None is returned instead.
- get_schema_version() SchemaVersion
Returns which version of the schema this recipe uses. Useful for preventing illegal operations. :returns: Schema Version of the recipe file.
- get_selector_at_path(path: str, default: str | ~conda_recipe_manager.types.SentinelType = <conda_recipe_manager.types.SentinelType object>) str
Given a path, return the selector that exists on that line.
- Parameters:
path -- Target path
default -- (Optional) Default value to use if no selector is found.
- Raises:
KeyError -- If a selector is not found on the provided path AND no default has been specified.
ValueError -- If the default selector provided is malformed
- Returns:
Selector on the path provided
- get_selector_paths(selector: str) list[str]
Given a selector (including the surrounding brackets), provide a list of paths in the parse tree that use that selector.
Selector paths will be ordered by the line they appear on in the file.
- Parameters:
selector -- Selector of interest.
- Returns:
A list of all known paths that use a particular selector
- get_value(path: str, default: dict[str, dict[str, JsonType] | list[JsonType] | str | int | float | bool | None] | list[dict[str, JsonType] | list[JsonType] | str | int | float | bool | None] | str | int | float | bool | None | ~conda_recipe_manager.types.SentinelType = <conda_recipe_manager.types.SentinelType object>, sub_vars: bool = False) dict[str, JsonType] | list[JsonType] | str | int | float | bool | None
Retrieves a value at a given path. If the value is not found, return a specified default value or throw. TODO Refactor: This function could leverage render_to_object() to simplify/de-dupe the logic.
- Parameters:
path -- JSON patch (RFC 6902)-style path to a value.
default -- (Optional) If the value is not found, return this value instead.
sub_vars -- (Optional) If set to True and the value contains a Jinja template variable, the Jinja value will be "rendered". Any variables that can't be resolved will be escaped with ${{ }}.
- Raises:
KeyError -- If the value is not found AND no default is specified
- Returns:
If found, the value in the recipe at that path. Otherwise, the caller-specified default value.
- get_variable(var: str, default: dict[str, dict[str, JsonType] | list[JsonType] | str | int | float | bool | None] | list[dict[str, JsonType] | list[JsonType] | str | int | float | bool | None] | str | int | float | bool | None | ~conda_recipe_manager.types.SentinelType = <conda_recipe_manager.types.SentinelType object>) dict[str, JsonType] | list[JsonType] | str | int | float | bool | None
Returns the value of a variable set in the recipe. If specified, a default value will be returned if the variable name is not found.
- Parameters:
var -- Variable of interest check for.
default -- (Optional) If the value is not found, return this value instead.
- Raises:
KeyError -- If the value is not found AND no default is specified
- Returns:
The value (or specified default value if not found) of the variable name provided.
- get_variable_references(var: str) list[str]
Returns a list of paths that use particular variables.
- Parameters:
var -- Variable of interest
- Returns:
List of paths that use a variable, sorted by first appearance.
- has_unsupported_statements() bool
Runs a series of checks against the original recipe file.
- Returns:
True if the recipe has statements we do not currently support. False otherwise.
- is_modified() bool
Indicates if the object has been modified.
- Returns:
True if the object instance has been modified. False otherwise.
- is_multi_output() bool
Indicates if a recipe is a "multiple output" recipe.
- Returns:
True if the recipe produces multiple outputs. False otherwise.
- list_selectors() list[str]
Returns selectors found in the recipe, sorted by first appearance.
- Returns:
List of selectors found in the recipe.
- list_value_paths() list[str]
Provides a list of all known terminal paths. This can be used by the caller to perform search operations.
- Returns:
List of all terminal paths in the parse tree.
- list_variables() list[str]
Returns variables found in the recipe, sorted by first appearance.
- Returns:
List of variables found in the recipe.
- patch(patch: dict[str, dict[str, dict[str, JsonType] | list[JsonType] | str | int | float | bool | None] | list[dict[str, JsonType] | list[JsonType] | str | int | float | bool | None] | str | int | float | bool | None]) bool
Given a JSON-patch object, perform a patch operation.
- Modifications from RFC 6902
We're using a Jinja-formatted YAML file, not JSON
To modify comments, specify the path AND comment
- Parameters:
patch -- JSON-patch payload to operate with.
- Raises:
JsonPatchValidationException -- If the JSON-patch payload does not conform to our schema/spec.
- Returns:
If the calling code attempts to perform the test operation, this indicates the return value of the test request. In other words, if value matches the target variable, return True. False otherwise. For all other operations, this indicates if the operation was successful.
- static pre_process_remove_hash_type(content: str) str
There is a common-enough-to-be-annoying pattern used in some recipe files where the /source/sha256 key is stored as a variable. For example: {{ hash_type }}: <hash>
This variable-as-a-key mechanism is not supported by the parser and causes issues for other tooling. This function, if run before parsing the recipe file, will remove and fix this pattern.
- Parameters:
content -- Recipe file contents to pre-process
- Returns:
Pre-processed recipe file contents, devoid of hash_type key/variable usage.
- remove_dependency(dep: Dependency) bool [source]
Convenience function that removes a dependency from a recipe file. No exceptions are thrown if the dependency does not exist.
- Parameters:
dep -- Dependency to remove
- Returns:
The result of the underlying patch command, indicating that a change occurred.
- remove_selector(path: str) str | None
Given a path, remove a selector to the line denoted by path. - If a selector does not exist, nothing happens. - If a comment exists after the selector, keep it, discard the selector.
- Parameters:
path -- Path to add a selector to
- Raises:
KeyError -- If the path provided is not found
- Returns:
If found, the selector removed (includes surrounding brackets). Otherwise, returns None
- render() str
Takes the current state of the parse tree and returns the recipe file as a string.
- Returns:
String representation of the recipe file
- render_to_object(replace_variables: bool = False) dict[str, JsonType] | list[JsonType] | str | int | float | bool | None
Takes the underlying state of the parse tree and produces a Pythonic object/dictionary representation. Analogous to json.load().
- Parameters:
replace_variables -- (Optional) If set to True, this replaces all variable substitutions with their set values.
- Returns:
Pythonic data object representation of the recipe.
- search(regex: str | Pattern[str], include_comment: bool = False) list[str]
Given a regex string, return the list of paths that match the regex. NOTE: This function only searches against primitive values. All variables and selectors can be fully provided by using their respective list_*() functions.
- Parameters:
regex -- Regular expression to match with
include_comment -- (Optional) If set to True, this function will execute the regular expression on values WITH their comments provided. For example: 42 # This is a comment
- Returns:
Returns a list of paths where the matched value was found.
- search_and_patch(regex: str | Pattern[str], patch: dict[str, dict[str, dict[str, JsonType] | list[JsonType] | str | int | float | bool | None] | list[dict[str, JsonType] | list[JsonType] | str | int | float | bool | None] | str | int | float | bool | None], include_comment: bool = False) bool
Given a regex string and a JSON patch, apply the patch to any values that match the search expression.
- Parameters:
regex -- Regular expression to match with
patch -- JSON patch to perform. NOTE: The path field will be replaced with the path(s) found, so it does not need to be provided.
include_comment -- (Optional) If set to True, this function will execute the regular expression on values WITH their comments provided. For example: 42 # This is a comment
- Returns:
Returns a list of paths where the matched value was found.
- set_variable(var: str, value: dict[str, JsonType] | list[JsonType] | str | int | float | bool | None) None
Adds or changes an existing Jinja variable.
- Parameters:
var -- Variable to modify
value -- Value to set