Add new subcommand to lint artifact contents - #2471
Conversation
We detected some problems in the contents of your artifacts! This usually has to do with the location of some files. Please adjust your build scripts so the files mentioned below are placed in the correct paths. ~/.local/conda/pkgs/cmake-4.2.2-h8cb302d_0.conda
~/.local/conda/pkgs/cyrus-sasl-2.1.28-ha1cbb27_0.conda
~/.local/conda/pkgs/font-ttf-ubuntu-0.83-h77eed37_3.conda
~/.local/conda/pkgs/git-2.52.0-pl5321h8012a55_1.conda
~/.local/conda/pkgs/jsonpointer-3.0.0-pyhcf101f3_3.conda
~/.local/conda/pkgs/pint-0.25.2-pyhcf101f3_0.conda
~/.local/conda/pkgs/progressbar2-4.5.0-pyhd8ed1ab_1.conda
~/.local/conda/pkgs/pyopengl-3.1.10-pyh534df25_2.conda
~/.local/conda/pkgs/qt-main-5.15.15-h4427410_7.conda
~/.local/conda/pkgs/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
~/.local/conda/pkgs/zarr-3.1.5-pyhcf101f3_0.conda
|
| ] | ||
| ) | ||
| if noarch_python: | ||
| allowed.append(r"site-packages/.*") |
There was a problem hiding this comment.
| allowed.append(r"site-packages/.*") | |
| allowed.append(r"site-packages/.*") | |
| allowed.append(r"python-scripts/.*") |
| allowed.append(r"site-packages/.*") | ||
| if index.get("name") in ("conda", "mamba"): | ||
| allowed.append(r"condabin/.*") | ||
| allowed.append(r"shell/.*") |
There was a problem hiding this comment.
This should probably be disallowed. Not sure why it's in the top-level in the first place.
There was a problem hiding this comment.
This may take a bit to solve in conda. I can open an issue but I doubt it can be done in time for the March release. Added a comment for now.
| if for_windows: | ||
| allowed.extend( | ||
| [ | ||
| r"Scripts/.*", |
There was a problem hiding this comment.
This should be for python packages only.
| allowed.extend( | ||
| [ | ||
| r"Scripts/.*", | ||
| r"Library/.*", |
There was a problem hiding this comment.
subfolders here should be checked s well.
| [ | ||
| r"Scripts/.*", | ||
| r"Library/.*", | ||
| r"Lib/.*", |
Co-authored-by: isuruf <isuruf@users.noreply.github.com>
| elif for_windows: | ||
| python_pkg_path_pattern = r"Lib/site-packages/{package_name}/.*" | ||
| else: | ||
| python_pkg_path_pattern = r"lib/python\d\.\d+/site-packages/{package_name}/.*" |
There was a problem hiding this comment.
We also need "maybe a t" here for the free threaded builds, don't we?
| python_pkg_path_pattern = r"lib/python\d\.\d+/site-packages/{package_name}/.*" | |
| python_pkg_path_pattern = r"lib/python\d\.\d+t?/site-packages/{package_name}/.*" |
|
I grabbed a sqlite dump of SELECT DISTINCT
CASE
WHEN instr(path, '/') > 0 THEN substr(path, 1, instr(path, '/') - 1)
ELSE NULL
END AS top_level_dir
FROM PathToArtifactIds;Which resulted in these top-level directories... |
|
nice! |
|
These are the top-level SELECT DISTINCT
substr(path, 9, instr(substr(path, 9), '/') - 1) AS library_subdir
FROM PathToArtifactIds
WHERE path LIKE 'Library/%/%'; |
|
And this big boi we can also find all the package names that have files which start with a given component: SELECT DISTINCT
(
SELECT group_concat(J.value, '-')
FROM json_each('["' || replace(substr(A.artifact, instr(substr(A.artifact, 4), '/') + 4), '-', '","') || '"]') AS J
WHERE J.key < (json_array_length('["' || replace(substr(A.artifact, instr(substr(A.artifact, 4), '/') + 4), '-', '","') || '"]') - 2)
) AS package_name
FROM PathToArtifactIds_fts F
JOIN PathToArtifactIds P ON F.rowid = P.rowid
JOIN json_each('[' || P.artifact_ids || ']') AS A_IDS
JOIN Artifacts A ON A.id = A_IDS.value
-- Replace the placeholders below
WHERE PathToArtifactIds_fts MATCH 'path : REPLACE-THIS'
AND P.path LIKE 'REPLACE-THIS/%';So, for |
Co-authored-by: pb01ka <gaganpb08singh@gmail.com> Co-authored-by: jaimergp <jaimergp@users.noreply.github.com>
|
pre-commit.ci autofix |
for more information, see https://pre-commit.ci
pb01ka
left a comment
There was a problem hiding this comment.
The difference between the two linter subcommands is in how they render the final message: RecipeLint leaves messages as raw plain text, while ArtifactLint formats them in Markdown (emoji, code fences). Assuming the message content can be unified, the rendering should be decoupled from the data logic.
Current state:
lint_artifact.main()
check_path_patterns()-> raw dicts (errors, warnings)format_errors_warnings()-> Markdown strings baked into lints/hintsArtifactLint.__call__just joins and prints them
Proposed state:
lint_artifact.main()
check_path_patterns()-> raw dicts (errors, warnings)- returns raw dicts directly, no formatting inside the library
ArtifactLint.__call__
- calls
main()to get raw dicts - calls
markdown_formatter(errors, warnings)-> Markdown strings - prints them
RecipeLint.__call__
- calls
main()to get raw dicts - prints them without formatting (since no formatting is required as of now for this class)
Concrete change: main() returns (errors: dict, warnings: dict) instead of (lints: list[str], hints: list[str]), and format_errors_warnings() moves to the CLI layer (or a separate renderers.py). This keeps lint_artifact as pure data logic and lets any caller (including RecipeLint.__call__) render the output however it needs (plain text, Markdown, JSON, etc.). Since this is a new module with no existing dependents, now is the right time to make this change (post merging of this PR or within this PR). I think this internal change can be kept backwards compatible for the end users.
Checklist
newsentrypython conda_smithy/schema.py)Closes Quansight-Labs/conda-ecosystem-sta-mgmt#114