-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Generate meta.yaml dependencies #45
Changes from all commits
5df4e2a
cf0d6a1
5c8f778
79b13e4
5b9aa8c
1196647
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -11,6 +11,7 @@ | |||||||||
cli_name, | ||||||||||
default_channels, | ||||||||||
default_conda_dir, | ||||||||||
default_conda_meta_dir, | ||||||||||
default_pyproject_dir, | ||||||||||
default_requirements_dir, | ||||||||||
) | ||||||||||
|
@@ -55,6 +56,8 @@ def dedupe(dependencies): | |||||||||
""" | ||||||||||
deduped = sorted({dep for dep in dependencies if not isinstance(dep, dict)}) | ||||||||||
dict_deps = defaultdict(list) | ||||||||||
# The purpose of the outer loop is to support nested dependency lists such as the | ||||||||||
# `pip:` list. If multiple are present, they must be internally deduped as well. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unrelated? |
||||||||||
for dep in filter(lambda dep: isinstance(dep, dict), dependencies): | ||||||||||
for key, values in dep.items(): | ||||||||||
dict_deps[key].extend(values) | ||||||||||
|
@@ -83,6 +86,10 @@ def grid(gridspec): | |||||||||
Iterable[dict] | ||||||||||
Each yielded value is a dictionary containing one of the unique | ||||||||||
combinations of parameter values from `gridspec`. | ||||||||||
|
||||||||||
Notes | ||||||||||
----- | ||||||||||
An empty `gridspec` dict will result in an empty dict as the single yielded value. | ||||||||||
Comment on lines
+89
to
+92
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unrelated? |
||||||||||
""" | ||||||||||
for values in itertools.product(*gridspec.values()): | ||||||||||
yield dict(zip(gridspec.keys(), values)) | ||||||||||
|
@@ -131,6 +138,12 @@ def make_dependency_file( | |||||||||
"dependencies": dependencies, | ||||||||||
} | ||||||||||
) | ||||||||||
elif file_type == str(OutputTypes.CONDA_META): | ||||||||||
file_contents += yaml.dump( | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we assume that the header will be valid for all generated file types? |
||||||||||
{ | ||||||||||
"dependencies": dependencies, | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "dependencies" section of a conda-meta file is called "requirements". What am I missing here? |
||||||||||
} | ||||||||||
) | ||||||||||
elif file_type == str(OutputTypes.REQUIREMENTS): | ||||||||||
file_contents += "\n".join(dependencies) + "\n" | ||||||||||
elif file_type == str(OutputTypes.PYPROJECT): | ||||||||||
|
@@ -208,7 +221,7 @@ def get_requested_output_types(output): | |||||||||
return output | ||||||||||
|
||||||||||
|
||||||||||
def get_filename(file_type, file_key, matrix_combo): | ||||||||||
def get_filename(file_type, file_key, matrix_combo, extras=None): | ||||||||||
"""Get the name of the file to which to write a generated dependency set. | ||||||||||
|
||||||||||
The file name will be composed of the following components, each determined | ||||||||||
|
@@ -229,6 +242,8 @@ def get_filename(file_type, file_key, matrix_combo): | |||||||||
matrix_combo : dict | ||||||||||
A mapping of key-value pairs corresponding to the | ||||||||||
[files.$FILENAME.matrix] entry in dependencies.yaml. | ||||||||||
extras : dict | ||||||||||
Any extra information provided for generating this filename. | ||||||||||
|
||||||||||
Returns | ||||||||||
------- | ||||||||||
|
@@ -240,6 +255,18 @@ def get_filename(file_type, file_key, matrix_combo): | |||||||||
file_name_prefix = file_key | ||||||||||
if file_type == str(OutputTypes.CONDA): | ||||||||||
file_ext = ".yaml" | ||||||||||
elif file_type == str(OutputTypes.CONDA_META): | ||||||||||
file_ext = ".yaml" | ||||||||||
file_name_prefix = "_".join( | ||||||||||
filter( | ||||||||||
None, | ||||||||||
[ | ||||||||||
"meta_dependencies", | ||||||||||
extras.get("output", ""), | ||||||||||
extras.get("section", ""), | ||||||||||
Comment on lines
+265
to
+266
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Since you are filtering on |
||||||||||
], | ||||||||||
) | ||||||||||
) | ||||||||||
elif file_type == str(OutputTypes.REQUIREMENTS): | ||||||||||
file_ext = ".txt" | ||||||||||
file_type_prefix = "requirements" | ||||||||||
|
@@ -282,6 +309,8 @@ def get_output_dir(file_type, config_file_path, file_config): | |||||||||
path = [os.path.dirname(config_file_path)] | ||||||||||
if file_type == str(OutputTypes.CONDA): | ||||||||||
path.append(file_config.get("conda_dir", default_conda_dir)) | ||||||||||
elif file_type == str(OutputTypes.CONDA_META): | ||||||||||
path.append(file_config.get("conda_meta_dir", default_conda_meta_dir)) | ||||||||||
elif file_type == str(OutputTypes.REQUIREMENTS): | ||||||||||
path.append(file_config.get("requirements_dir", default_requirements_dir)) | ||||||||||
elif file_type == str(OutputTypes.PYPROJECT): | ||||||||||
|
@@ -425,7 +454,7 @@ def make_dependency_files(parsed_config, config_file_path, to_stdout): | |||||||||
) | ||||||||||
|
||||||||||
# Dedupe deps and print / write to filesystem | ||||||||||
full_file_name = get_filename(file_type, file_key, matrix_combo) | ||||||||||
full_file_name = get_filename(file_type, file_key, matrix_combo, extras) | ||||||||||
deduped_deps = dedupe(dependencies) | ||||||||||
|
||||||||||
output_dir = ( | ||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
"matrix": {"$ref": "#/$defs/matrix"}, | ||
"requirements_dir": {"type": "string"}, | ||
"conda_dir": {"type": "string"}, | ||
"conda_meta_dir": {"type": "string"}, | ||
"pyproject_dir": {"type": "string"} | ||
}, | ||
"additionalProperties": false, | ||
|
@@ -118,7 +119,7 @@ | |
"items": {"$ref": "#/$defs/matrix-matcher"} | ||
}, | ||
"output-types": { | ||
"enum": ["conda", "requirements", "pyproject"] | ||
"enum": ["conda", "conda_meta", "requirements", "pyproject"] | ||
}, | ||
"output-types-array": { | ||
"type": "array", | ||
|
@@ -162,22 +163,16 @@ | |
"extras": { | ||
"type": "object", | ||
"properties": { | ||
"section": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does the keyword "section" originate from the conda docs? I am wondering whether it would make sense to better namespace our "extras", something like "conda-meta-section" instead of just "section". |
||
"type": "string", | ||
"enum": ["build", "host", "run"] | ||
}, | ||
"table": { | ||
"type": "string", | ||
"enum": ["build-system", "project", "project.optional-dependencies"] | ||
}, | ||
"key": {"type": "string"} | ||
}, | ||
"if": { | ||
"properties": { "table": { "const": "project.optional-dependencies" } } | ||
}, | ||
"then": { | ||
"required": ["key"] | ||
}, | ||
"else": { | ||
"not": { | ||
"required": ["key"] | ||
} | ||
Comment on lines
-171
to
-180
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was having trouble getting this conditional to behave correctly. According to the official JSON Schema docs it should have been sufficient to add a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CC @csadorf if you have thoughts here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So when you simply added a |
||
"key": {"type": "string"}, | ||
"additionalProperties": false | ||
}, | ||
"additionalProperties": false | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why to use a trailing backslash here, but not for the other dirs?