rumdl 0.0.56__tar.gz → 0.0.57__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rumdl might be problematic. Click here for more details.
- {rumdl-0.0.56 → rumdl-0.0.57}/Cargo.lock +1 -1
- {rumdl-0.0.56 → rumdl-0.0.57}/Cargo.toml +1 -1
- {rumdl-0.0.56 → rumdl-0.0.57}/PKG-INFO +1 -1
- rumdl-0.0.57/parity_check.py +211 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/config.rs +60 -34
- {rumdl-0.0.56 → rumdl-0.0.57}/src/lib.rs +4 -5
- {rumdl-0.0.56 → rumdl-0.0.57}/src/main.rs +12 -10
- {rumdl-0.0.56 → rumdl-0.0.57}/src/markdownlint_config.rs +1 -5
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/emphasis_style.rs +1 -1
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md003_heading_style.rs +16 -25
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md004_unordered_list_style.rs +52 -63
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md012_no_multiple_blanks.rs +38 -29
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md013_line_length.rs +4 -4
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md025_single_title.rs +26 -19
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md032_blanks_around_lists.rs +22 -9
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md033_no_inline_html.rs +194 -52
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md034_no_bare_urls.rs +116 -143
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md055_table_pipe_style.rs +2 -2
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/mod.rs +0 -3
- {rumdl-0.0.56 → rumdl-0.0.57}/src/utils/document_structure.rs +184 -41
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/advanced_integration_tests.rs +14 -19
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/config_application_tests.rs +6 -6
- rumdl-0.0.57/tests/config_tests.rs +859 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/perf_check.rs +2 -2
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md004_test.rs +12 -6
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md012_test.rs +27 -12
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md013_test.rs +6 -5
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md025_test.rs +4 -3
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md032_test.rs +70 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md033_test.rs +22 -12
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md034_test.rs +203 -53
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/mod.rs +0 -1
- rumdl-0.0.56/docs/md008.md +0 -119
- rumdl-0.0.56/parity_check.py +0 -130
- rumdl-0.0.56/src/rules/md008_ul_style.rs +0 -520
- rumdl-0.0.56/tests/config_tests.rs +0 -472
- rumdl-0.0.56/tests/rules/md008_test.rs +0 -318
- {rumdl-0.0.56 → rumdl-0.0.57}/.rumdl.toml +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/MANIFEST.in +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/Makefile +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/README.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/assets/logo.png +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/benches/range_performance.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/benches/range_utils_benchmark.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/benches/rule_performance.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/RULES.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md001.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md002.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md003.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md004.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md005.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md006.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md007.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md009.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md010.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md011.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md012.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md013.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md014.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md018.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md019.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md020.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md021.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md022.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md023.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md024.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md025.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md026.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md027.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md028.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md029.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md030.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md031.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md032.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md033.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md034.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md035.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md036.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md037.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md038.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md039.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md040.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md041.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md042.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md043.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md044.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md045.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md046.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md047.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md048.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md049.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md050.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md051.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md052.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md053.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md054.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md055.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md056.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md057.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/docs/md058.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/issues/plan-rule-parity-with-markdownlint.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/pyproject.toml +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/python/MANIFEST.in +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/python/PYTHON-README.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/python/rumdl/__init__.py +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/python/rumdl/__main__.py +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/python/rumdl/py.typed +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/rumdl.toml.example +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/init.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/lint_context.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/profiling.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/python.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rule.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/blockquote_utils.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/code_block_utils.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/code_fence_utils.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/front_matter_utils.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/heading_utils.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/list_utils.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md001_heading_increment.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md002_first_heading_h1.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md005_list_indent.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md006_start_bullets.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md007_ul_indent.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md009_trailing_spaces.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md010_no_hard_tabs.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md011_no_reversed_links.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md014_commands_show_output.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md018_no_missing_space_atx.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md019_no_multiple_space_atx.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md020_no_missing_space_closed_atx.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md021_no_multiple_space_closed_atx.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md022_blanks_around_headings.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md023_heading_start_left.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md024_no_duplicate_heading.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md026_no_trailing_punctuation.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md027_multiple_spaces_blockquote.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md028_no_blanks_blockquote.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md029_ordered_list_prefix.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md030_list_marker_space.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md031_blanks_around_fences.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md035_hr_style.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md036_no_emphasis_only_first.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md037_spaces_around_emphasis.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md038_no_space_in_code.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md039_no_space_in_links.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md040_fenced_code_language.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md041_first_line_heading.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md042_no_empty_links.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md043_required_headings.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md044_proper_names.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md045_no_alt_text.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md046_code_block_style.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md047_single_trailing_newline.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md048_code_fence_style.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md049_emphasis_style.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md050_strong_style.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md051_link_fragments.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md052_reference_links_images.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md053_link_image_reference_definitions.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md054_link_image_style.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md056_table_column_count.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md057_existing_relative_links.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/md058_blanks_around_tables.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/rules/strong_style.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/utils/code_block_utils.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/utils/early_returns.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/utils/element_cache.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/utils/markdown_elements.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/utils/mod.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/utils/range_utils.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/src/utils/regex_cache.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/cli_duplication_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/cli_integration_tests.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/commonmark_compliance_tests.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/comprehensive_integration_tests.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/init_command_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/init_tests.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/integration_tests.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/json_output_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/lib.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/markdownlint_cli_integration.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/markdownlint_config_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/md030_edge_cases.md +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/output_format_tests.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/pyproject_config_tests.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md001_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md001_unicode_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md002_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md003_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md005_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md006_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md006_unicode_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md007_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md009_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md010_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md011_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md014_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md018_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md019_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md020_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md021_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md022_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md023_extended_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md023_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md024_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md026_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md027_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md028_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md029_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md030_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md031_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md033_extended_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md035_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md036_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md037_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md038_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md039_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md040_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md041_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md042_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md043_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md044_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md045_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md046_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md047_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md048_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md049_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md050_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md051_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md052_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md053_additional_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md053_proptest.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md053_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md054_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md054_unicode_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md055_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md056_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md057_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/rules/md058_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/utils/blockquote_utils_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/utils/code_block_utils_extended_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/utils/code_block_utils_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/utils/core_utils_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/utils/front_matter_utils_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/utils/line_index_test.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/utils/mod.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/utils_markdown_edge_cases.rs +0 -0
- {rumdl-0.0.56 → rumdl-0.0.57}/tests/utils_tests.rs +0 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import subprocess
|
|
3
|
+
import json
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
PARITY_CORPUS = Path(__file__).parent / "parity_corpus"
|
|
9
|
+
RUMDL_BIN = "cargo run --bin rumdl --"
|
|
10
|
+
MARKDOWNLINT_BIN = "markdownlint"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def run_rumdl(md_file):
|
|
14
|
+
# Use --no-config to ensure no config is loaded (use built-in defaults only)
|
|
15
|
+
cmd = f"{RUMDL_BIN} check '{md_file}' -o json --no-config"
|
|
16
|
+
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
|
17
|
+
if result.returncode != 0 and not result.stdout.strip():
|
|
18
|
+
print(f"[rumdl] Error running on {md_file}: {result.stderr}")
|
|
19
|
+
return []
|
|
20
|
+
try:
|
|
21
|
+
return json.loads(result.stdout)
|
|
22
|
+
except Exception as e:
|
|
23
|
+
print(f"[rumdl] Failed to parse JSON for {md_file}: {e}")
|
|
24
|
+
return []
|
|
25
|
+
|
|
26
|
+
def run_markdownlint(md_file):
|
|
27
|
+
cmd = ["npx", MARKDOWNLINT_BIN, str(md_file), "--json"]
|
|
28
|
+
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
29
|
+
if result.returncode not in (0, 1):
|
|
30
|
+
print(f"[markdownlint] Error running on {md_file}: {result.stderr}")
|
|
31
|
+
return []
|
|
32
|
+
|
|
33
|
+
# markdownlint outputs JSON to stderr when using --json flag
|
|
34
|
+
output = result.stderr.strip() if result.stderr.strip() else result.stdout.strip()
|
|
35
|
+
if output:
|
|
36
|
+
try:
|
|
37
|
+
return json.loads(output)
|
|
38
|
+
except Exception as e:
|
|
39
|
+
print(f"[markdownlint] Failed to parse JSON for {md_file}: {e}")
|
|
40
|
+
print(f"[markdownlint] output for {md_file}:")
|
|
41
|
+
print(output)
|
|
42
|
+
return []
|
|
43
|
+
|
|
44
|
+
def normalize_rumdl(warning, file):
|
|
45
|
+
"""Normalize rumdl warning to common format"""
|
|
46
|
+
return {
|
|
47
|
+
"file": str(file.relative_to(Path.cwd())), # Convert to relative path
|
|
48
|
+
"line": warning.get("line"),
|
|
49
|
+
"column": warning.get("column", 1),
|
|
50
|
+
"rule": warning.get("rule_name"),
|
|
51
|
+
"message": warning.get("message"),
|
|
52
|
+
"fix": warning.get("fix"),
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
def normalize_markdownlint(warning):
|
|
56
|
+
"""Normalize markdownlint warning to common format"""
|
|
57
|
+
file_path = warning.get("fileName")
|
|
58
|
+
# Convert absolute paths to relative if possible
|
|
59
|
+
if file_path and file_path.startswith('/'):
|
|
60
|
+
try:
|
|
61
|
+
file_path = str(Path(file_path).relative_to(Path.cwd()))
|
|
62
|
+
except ValueError:
|
|
63
|
+
# If the path is not relative to cwd, keep it as is
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
"file": file_path,
|
|
68
|
+
"line": warning.get("lineNumber"),
|
|
69
|
+
"column": (warning.get("errorRange") or [1])[0] if warning.get("errorRange") else 1,
|
|
70
|
+
"rule": warning.get("ruleNames", [None])[0],
|
|
71
|
+
"message": warning.get("ruleDescription"),
|
|
72
|
+
"fix": warning.get("fixInfo"),
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
def compare_warnings(rumdl_warnings, markdownlint_warnings):
|
|
76
|
+
# Sort by (line, rule) for comparison - ignore column and message differences
|
|
77
|
+
def key(w):
|
|
78
|
+
return (
|
|
79
|
+
w.get("line", 0),
|
|
80
|
+
w.get("rule", "")
|
|
81
|
+
)
|
|
82
|
+
r_sorted = sorted(rumdl_warnings, key=key)
|
|
83
|
+
m_sorted = sorted(markdownlint_warnings, key=key)
|
|
84
|
+
|
|
85
|
+
# Compare based on file, line, and rule only
|
|
86
|
+
def warning_key(w):
|
|
87
|
+
return (w.get("file"), w.get("line"), w.get("rule"))
|
|
88
|
+
|
|
89
|
+
r_set = set(warning_key(w) for w in r_sorted)
|
|
90
|
+
m_set = set(warning_key(w) for w in m_sorted)
|
|
91
|
+
|
|
92
|
+
only_in_rumdl = r_set - m_set
|
|
93
|
+
only_in_markdownlint = m_set - r_set
|
|
94
|
+
common = r_set & m_set
|
|
95
|
+
|
|
96
|
+
if not only_in_rumdl and not only_in_markdownlint:
|
|
97
|
+
print("All warnings match!")
|
|
98
|
+
return True
|
|
99
|
+
|
|
100
|
+
if only_in_rumdl:
|
|
101
|
+
print(f" Warnings only in rumdl ({len(only_in_rumdl)}):")
|
|
102
|
+
for key in list(only_in_rumdl)[:3]: # Show fewer to reduce noise
|
|
103
|
+
file, line, rule = key
|
|
104
|
+
# Find the actual warning for context
|
|
105
|
+
warning = next((w for w in rumdl_warnings if w.get('file') == file and w.get('line') == line and w.get('rule') == rule), None)
|
|
106
|
+
message = warning.get('message', 'No message') if warning else 'No message'
|
|
107
|
+
print(f" Line {line}: {rule} - {message}")
|
|
108
|
+
if len(only_in_rumdl) > 3:
|
|
109
|
+
print(f" ...and {len(only_in_rumdl) - 3} more.")
|
|
110
|
+
if only_in_markdownlint:
|
|
111
|
+
print(f" Warnings only in markdownlint ({len(only_in_markdownlint)}):")
|
|
112
|
+
for key in list(only_in_markdownlint)[:3]: # Show fewer to reduce noise
|
|
113
|
+
file, line, rule = key
|
|
114
|
+
# Find the actual warning for context
|
|
115
|
+
warning = next((w for w in markdownlint_warnings if w.get('file') == file and w.get('line') == line and w.get('rule') == rule), None)
|
|
116
|
+
message = warning.get('message', 'No message') if warning else 'No message'
|
|
117
|
+
print(f" Line {line}: {rule} - {message}")
|
|
118
|
+
if len(only_in_markdownlint) > 3:
|
|
119
|
+
print(f" ...and {len(only_in_markdownlint) - 3} more.")
|
|
120
|
+
print(f" Common warnings: {len(r_set & m_set)}")
|
|
121
|
+
return False
|
|
122
|
+
|
|
123
|
+
def main():
|
|
124
|
+
md_files = sorted(PARITY_CORPUS.glob("*.md"))
|
|
125
|
+
if not md_files:
|
|
126
|
+
print("No markdown files found in parity_corpus/")
|
|
127
|
+
sys.exit(1)
|
|
128
|
+
|
|
129
|
+
all_passed = True
|
|
130
|
+
total_common = 0
|
|
131
|
+
total_rumdl_only = 0
|
|
132
|
+
total_markdownlint_only = 0
|
|
133
|
+
|
|
134
|
+
for md_file in md_files:
|
|
135
|
+
print(f"\n=== {md_file} ===")
|
|
136
|
+
rumdl_raw = run_rumdl(md_file)
|
|
137
|
+
markdownlint_raw = run_markdownlint(md_file)
|
|
138
|
+
|
|
139
|
+
rumdl_norm = [normalize_rumdl(w, md_file) for w in rumdl_raw]
|
|
140
|
+
markdownlint_norm = [normalize_markdownlint(w) for w in markdownlint_raw]
|
|
141
|
+
|
|
142
|
+
# Filter markdownlint warnings to only include the current file
|
|
143
|
+
file_relative = str(md_file.relative_to(Path.cwd()))
|
|
144
|
+
file_absolute = str(md_file.absolute())
|
|
145
|
+
markdownlint_norm = [w for w in markdownlint_norm if w.get("file") in (file_relative, file_absolute)]
|
|
146
|
+
|
|
147
|
+
# Sort by (line, rule) for comparison - ignore column and message differences
|
|
148
|
+
def key(w):
|
|
149
|
+
return (
|
|
150
|
+
w.get("line", 0),
|
|
151
|
+
w.get("rule", "")
|
|
152
|
+
)
|
|
153
|
+
r_sorted = sorted(rumdl_norm, key=key)
|
|
154
|
+
m_sorted = sorted(markdownlint_norm, key=key)
|
|
155
|
+
|
|
156
|
+
# Compare based on file, line, and rule only
|
|
157
|
+
def warning_key(w):
|
|
158
|
+
return (w.get("file"), w.get("line"), w.get("rule"))
|
|
159
|
+
|
|
160
|
+
r_set = set(warning_key(w) for w in r_sorted)
|
|
161
|
+
m_set = set(warning_key(w) for w in m_sorted)
|
|
162
|
+
|
|
163
|
+
only_in_rumdl = r_set - m_set
|
|
164
|
+
only_in_markdownlint = m_set - r_set
|
|
165
|
+
common = r_set & m_set
|
|
166
|
+
|
|
167
|
+
total_common += len(common)
|
|
168
|
+
total_rumdl_only += len(only_in_rumdl)
|
|
169
|
+
total_markdownlint_only += len(only_in_markdownlint)
|
|
170
|
+
|
|
171
|
+
if not only_in_rumdl and not only_in_markdownlint:
|
|
172
|
+
print("✓ All warnings match!")
|
|
173
|
+
else:
|
|
174
|
+
print("✗ Mismatches found:")
|
|
175
|
+
if only_in_rumdl:
|
|
176
|
+
print(f" Warnings only in rumdl ({len(only_in_rumdl)}):")
|
|
177
|
+
for key in list(only_in_rumdl)[:3]: # Show fewer to reduce noise
|
|
178
|
+
file, line, rule = key
|
|
179
|
+
# Find the actual warning for context
|
|
180
|
+
warning = next((w for w in rumdl_norm if w.get('file') == file and w.get('line') == line and w.get('rule') == rule), None)
|
|
181
|
+
message = warning.get('message', 'No message') if warning else 'No message'
|
|
182
|
+
print(f" Line {line}: {rule} - {message}")
|
|
183
|
+
if len(only_in_rumdl) > 3:
|
|
184
|
+
print(f" ...and {len(only_in_rumdl) - 3} more.")
|
|
185
|
+
if only_in_markdownlint:
|
|
186
|
+
print(f" Warnings only in markdownlint ({len(only_in_markdownlint)}):")
|
|
187
|
+
for key in list(only_in_markdownlint)[:3]: # Show fewer to reduce noise
|
|
188
|
+
file, line, rule = key
|
|
189
|
+
# Find the actual warning for context
|
|
190
|
+
warning = next((w for w in markdownlint_norm if w.get('file') == file and w.get('line') == line and w.get('rule') == rule), None)
|
|
191
|
+
message = warning.get('message', 'No message') if warning else 'No message'
|
|
192
|
+
print(f" Line {line}: {rule} - {message}")
|
|
193
|
+
if len(only_in_markdownlint) > 3:
|
|
194
|
+
print(f" ...and {len(only_in_markdownlint) - 3} more.")
|
|
195
|
+
print(f" Common warnings: {len(common)}")
|
|
196
|
+
all_passed = False
|
|
197
|
+
|
|
198
|
+
print(f"\n=== SUMMARY ===")
|
|
199
|
+
print(f"Total common warnings: {total_common}")
|
|
200
|
+
print(f"Total rumdl-only warnings: {total_rumdl_only}")
|
|
201
|
+
print(f"Total markdownlint-only warnings: {total_markdownlint_only}")
|
|
202
|
+
|
|
203
|
+
if all_passed:
|
|
204
|
+
print("✓ All files match between rumdl and markdownlint!")
|
|
205
|
+
sys.exit(0)
|
|
206
|
+
else:
|
|
207
|
+
print("✗ Some files have mismatches.")
|
|
208
|
+
sys.exit(1)
|
|
209
|
+
|
|
210
|
+
if __name__ == "__main__":
|
|
211
|
+
main()
|
|
@@ -294,8 +294,8 @@ respect-gitignore = true
|
|
|
294
294
|
|
|
295
295
|
fs::write(&config_path, content).unwrap();
|
|
296
296
|
|
|
297
|
-
// Load the config
|
|
298
|
-
let sourced = SourcedConfig::
|
|
297
|
+
// Load the config with skip_auto_discovery to avoid environment config files
|
|
298
|
+
let sourced = SourcedConfig::load_with_discovery(Some(config_path.to_str().unwrap()), None, true).unwrap();
|
|
299
299
|
let config: Config = sourced.into(); // Convert to plain config for assertions
|
|
300
300
|
|
|
301
301
|
// Check global settings
|
|
@@ -304,6 +304,7 @@ respect-gitignore = true
|
|
|
304
304
|
config.global.enable,
|
|
305
305
|
vec!["MD001".to_string(), "MD004".to_string()]
|
|
306
306
|
);
|
|
307
|
+
// Should now contain only the configured pattern since auto-discovery is disabled
|
|
307
308
|
assert_eq!(config.global.include, vec!["docs/*.md".to_string()]);
|
|
308
309
|
assert_eq!(config.global.exclude, vec!["node_modules".to_string()]);
|
|
309
310
|
assert!(config.global.respect_gitignore);
|
|
@@ -327,8 +328,8 @@ respect_gitignore = true
|
|
|
327
328
|
|
|
328
329
|
fs::write(&config_path, content).unwrap();
|
|
329
330
|
|
|
330
|
-
// Load the config
|
|
331
|
-
let sourced = SourcedConfig::
|
|
331
|
+
// Load the config with skip_auto_discovery to avoid environment config files
|
|
332
|
+
let sourced = SourcedConfig::load_with_discovery(Some(config_path.to_str().unwrap()), None, true).unwrap();
|
|
332
333
|
let config: Config = sourced.into(); // Convert to plain config for assertions
|
|
333
334
|
|
|
334
335
|
// Check settings were correctly loaded
|
|
@@ -347,14 +348,15 @@ line_length = 111
|
|
|
347
348
|
line-length = 222
|
|
348
349
|
"#;
|
|
349
350
|
fs::write(&config_path, config_content).unwrap();
|
|
350
|
-
|
|
351
|
+
// Load the config with skip_auto_discovery to avoid environment config files
|
|
352
|
+
let sourced = SourcedConfig::load_with_discovery(Some(config_path.to_str().unwrap()), None, true).unwrap();
|
|
351
353
|
// DEBUG: Print all rule keys and their value keys
|
|
352
|
-
|
|
354
|
+
log::debug!(
|
|
353
355
|
"[DEBUG] All rules loaded: {:?}",
|
|
354
356
|
sourced.rules.keys().collect::<Vec<_>>()
|
|
355
357
|
);
|
|
356
358
|
for (rule, cfg) in &sourced.rules {
|
|
357
|
-
|
|
359
|
+
log::debug!(
|
|
358
360
|
"[DEBUG] Rule '{}' value keys: {:?}",
|
|
359
361
|
rule,
|
|
360
362
|
cfg.values.keys().collect::<Vec<_>>()
|
|
@@ -364,7 +366,7 @@ line-length = 222
|
|
|
364
366
|
.rules
|
|
365
367
|
.get("MD013")
|
|
366
368
|
.expect("MD013 rule config should exist");
|
|
367
|
-
//
|
|
369
|
+
// Now we should only get the explicitly configured key
|
|
368
370
|
let keys: Vec<_> = rule_cfg.values.keys().cloned().collect();
|
|
369
371
|
assert_eq!(keys, vec!["line-length"]);
|
|
370
372
|
let val = &rule_cfg.values["line-length"].value;
|
|
@@ -392,7 +394,8 @@ line-length = 102
|
|
|
392
394
|
line-length = 103
|
|
393
395
|
"#;
|
|
394
396
|
fs::write(&config_path, config_content).unwrap();
|
|
395
|
-
|
|
397
|
+
// Load the config with skip_auto_discovery to avoid environment config files
|
|
398
|
+
let sourced = SourcedConfig::load_with_discovery(Some(config_path.to_str().unwrap()), None, true).unwrap();
|
|
396
399
|
let config: Config = sourced.clone().into();
|
|
397
400
|
// Only the last section should win, and be present
|
|
398
401
|
let rule_cfg = sourced
|
|
@@ -417,7 +420,8 @@ line_length = 201
|
|
|
417
420
|
line-length = 202
|
|
418
421
|
"#;
|
|
419
422
|
fs::write(&config_path, config_content).unwrap();
|
|
420
|
-
|
|
423
|
+
// Load the config with skip_auto_discovery to avoid environment config files
|
|
424
|
+
let sourced = SourcedConfig::load_with_discovery(Some(config_path.to_str().unwrap()), None, true).unwrap();
|
|
421
425
|
let config: Config = sourced.clone().into();
|
|
422
426
|
let rule_cfg = sourced
|
|
423
427
|
.rules
|
|
@@ -445,7 +449,8 @@ bar = 2
|
|
|
445
449
|
line-length = 303
|
|
446
450
|
"#;
|
|
447
451
|
fs::write(&config_path, config_content).unwrap();
|
|
448
|
-
|
|
452
|
+
// Load the config with skip_auto_discovery to avoid environment config files
|
|
453
|
+
let sourced = SourcedConfig::load_with_discovery(Some(config_path.to_str().unwrap()), None, true).unwrap();
|
|
449
454
|
let config: Config = sourced.clone().into();
|
|
450
455
|
// MD999 should not be present
|
|
451
456
|
assert!(!sourced.rules.contains_key("MD999"));
|
|
@@ -671,11 +676,25 @@ impl SourcedConfig {
|
|
|
671
676
|
pub fn load(
|
|
672
677
|
config_path: Option<&str>,
|
|
673
678
|
cli_overrides: Option<&SourcedGlobalConfig>,
|
|
679
|
+
) -> Result<Self, ConfigError> {
|
|
680
|
+
Self::load_with_discovery(config_path, cli_overrides, false)
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/// Load and merge configurations from files and CLI overrides.
|
|
684
|
+
/// If skip_auto_discovery is true, only explicit config paths are loaded.
|
|
685
|
+
pub fn load_with_discovery(
|
|
686
|
+
config_path: Option<&str>,
|
|
687
|
+
cli_overrides: Option<&SourcedGlobalConfig>,
|
|
688
|
+
skip_auto_discovery: bool,
|
|
674
689
|
) -> Result<Self, ConfigError> {
|
|
675
690
|
use std::env;
|
|
676
691
|
log::debug!("[rumdl-config] Current working directory: {:?}", env::current_dir());
|
|
677
692
|
if config_path.is_none() {
|
|
678
|
-
|
|
693
|
+
if skip_auto_discovery {
|
|
694
|
+
log::debug!("[rumdl-config] Skipping auto-discovery due to --no-config flag");
|
|
695
|
+
} else {
|
|
696
|
+
log::debug!("[rumdl-config] No explicit config_path provided, will search default locations");
|
|
697
|
+
}
|
|
679
698
|
} else {
|
|
680
699
|
log::debug!("[rumdl-config] Explicit config_path provided: {:?}", config_path);
|
|
681
700
|
}
|
|
@@ -717,7 +736,11 @@ impl SourcedConfig {
|
|
|
717
736
|
sourced_config.loaded_files.push(path_str.clone());
|
|
718
737
|
loaded_toml_or_pyproject = true;
|
|
719
738
|
}
|
|
720
|
-
} else if MARKDOWNLINT_FILENAMES.contains(&filename)
|
|
739
|
+
} else if MARKDOWNLINT_FILENAMES.contains(&filename)
|
|
740
|
+
|| path_str.ends_with(".json")
|
|
741
|
+
|| path_str.ends_with(".jsonc")
|
|
742
|
+
|| path_str.ends_with(".yaml")
|
|
743
|
+
|| path_str.ends_with(".yml") {
|
|
721
744
|
// Parse as markdownlint config (JSON/YAML)
|
|
722
745
|
let fragment = load_from_markdownlint(&path_str)?;
|
|
723
746
|
sourced_config.merge(fragment);
|
|
@@ -734,7 +757,10 @@ impl SourcedConfig {
|
|
|
734
757
|
sourced_config.loaded_files.push(path_str.clone());
|
|
735
758
|
loaded_toml_or_pyproject = true;
|
|
736
759
|
}
|
|
737
|
-
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// Only perform auto-discovery if not skipped AND no explicit config path provided
|
|
763
|
+
if !skip_auto_discovery && config_path.is_none() {
|
|
738
764
|
// 2. Discover and load default files: pyproject.toml first
|
|
739
765
|
if std::path::Path::new("pyproject.toml").exists() {
|
|
740
766
|
log::debug!("[rumdl-config] Found pyproject.toml in current directory");
|
|
@@ -773,20 +799,20 @@ impl SourcedConfig {
|
|
|
773
799
|
log::debug!("[rumdl-config] {} not found in current directory", filename);
|
|
774
800
|
}
|
|
775
801
|
}
|
|
776
|
-
}
|
|
777
802
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
803
|
+
// 4. Markdownlint config fallback if no TOML/pyproject config was loaded
|
|
804
|
+
if !loaded_toml_or_pyproject {
|
|
805
|
+
for filename in MARKDOWNLINT_CONFIG_FILES {
|
|
806
|
+
if std::path::Path::new(filename).exists() {
|
|
807
|
+
match load_from_markdownlint(filename) {
|
|
808
|
+
Ok(fragment) => {
|
|
809
|
+
sourced_config.merge(fragment);
|
|
810
|
+
sourced_config.loaded_files.push(filename.to_string());
|
|
811
|
+
break; // Load only the first one found
|
|
812
|
+
}
|
|
813
|
+
Err(_e) => {
|
|
814
|
+
// Log error but continue (it's just a fallback)
|
|
815
|
+
}
|
|
790
816
|
}
|
|
791
817
|
}
|
|
792
818
|
}
|
|
@@ -1281,7 +1307,7 @@ fn parse_rumdl_toml(content: &str, path: &str) -> Result<SourcedConfigFragment,
|
|
|
1281
1307
|
_ => unreachable!(), // Should not happen due to outer match
|
|
1282
1308
|
}
|
|
1283
1309
|
} else {
|
|
1284
|
-
|
|
1310
|
+
log::warn!(
|
|
1285
1311
|
"[WARN] Expected array for global key '{}' in {}, found {}",
|
|
1286
1312
|
key,
|
|
1287
1313
|
path,
|
|
@@ -1302,7 +1328,7 @@ fn parse_rumdl_toml(content: &str, path: &str) -> Result<SourcedConfigFragment,
|
|
|
1302
1328
|
None,
|
|
1303
1329
|
);
|
|
1304
1330
|
} else {
|
|
1305
|
-
|
|
1331
|
+
log::warn!(
|
|
1306
1332
|
"[WARN] Expected boolean for global key '{}' in {}, found {}",
|
|
1307
1333
|
key,
|
|
1308
1334
|
path,
|
|
@@ -1313,7 +1339,7 @@ fn parse_rumdl_toml(content: &str, path: &str) -> Result<SourcedConfigFragment,
|
|
|
1313
1339
|
_ => {
|
|
1314
1340
|
// Add to unknown_keys for potential validation later
|
|
1315
1341
|
// fragment.unknown_keys.push(("[global]".to_string(), key.to_string()));
|
|
1316
|
-
|
|
1342
|
+
log::warn!(
|
|
1317
1343
|
"[WARN] Unknown key in [global] section of {}: {}",
|
|
1318
1344
|
path, key
|
|
1319
1345
|
);
|
|
@@ -1350,21 +1376,21 @@ fn parse_rumdl_toml(content: &str, path: &str) -> Result<SourcedConfigFragment,
|
|
|
1350
1376
|
Some(toml::Value::Datetime(*formatted.value()))
|
|
1351
1377
|
}
|
|
1352
1378
|
Some(toml_edit::Value::Array(_)) => {
|
|
1353
|
-
|
|
1379
|
+
log::warn!(
|
|
1354
1380
|
"[WARN] Skipping array value for key '{}.{}' in {}. Array conversion not yet fully implemented in parser.",
|
|
1355
1381
|
norm_rule_name, norm_rk, path
|
|
1356
1382
|
);
|
|
1357
1383
|
None
|
|
1358
1384
|
}
|
|
1359
1385
|
Some(toml_edit::Value::InlineTable(_)) => {
|
|
1360
|
-
|
|
1386
|
+
log::warn!(
|
|
1361
1387
|
"[WARN] Skipping inline table value for key '{}.{}' in {}. Table conversion not yet fully implemented in parser.",
|
|
1362
1388
|
norm_rule_name, norm_rk, path
|
|
1363
1389
|
);
|
|
1364
1390
|
None
|
|
1365
1391
|
}
|
|
1366
1392
|
None => {
|
|
1367
|
-
|
|
1393
|
+
log::warn!(
|
|
1368
1394
|
"[WARN] Skipping non-value item for key '{}.{}' in {}. Expected simple value.",
|
|
1369
1395
|
norm_rule_name, norm_rk, path
|
|
1370
1396
|
);
|
|
@@ -1379,7 +1405,7 @@ fn parse_rumdl_toml(content: &str, path: &str) -> Result<SourcedConfigFragment,
|
|
|
1379
1405
|
}
|
|
1380
1406
|
}
|
|
1381
1407
|
} else if item.is_value() {
|
|
1382
|
-
|
|
1408
|
+
log::warn!(
|
|
1383
1409
|
"[WARN] Ignoring top-level value key in {}: '{}'. Expected a table like [{}].",
|
|
1384
1410
|
path, key, key
|
|
1385
1411
|
);
|
|
@@ -46,8 +46,7 @@ pub fn lint(content: &str, rules: &[Box<dyn Rule>], _verbose: bool) -> LintResul
|
|
|
46
46
|
warnings.extend(rule_warnings);
|
|
47
47
|
}
|
|
48
48
|
Err(e) => {
|
|
49
|
-
|
|
50
|
-
eprintln!("Error checking rule {}: {}", rule.name(), e);
|
|
49
|
+
log::error!("Error checking rule {}: {}", rule.name(), e);
|
|
51
50
|
return Err(e);
|
|
52
51
|
}
|
|
53
52
|
}
|
|
@@ -56,7 +55,7 @@ pub fn lint(content: &str, rules: &[Box<dyn Rule>], _verbose: bool) -> LintResul
|
|
|
56
55
|
if _verbose {
|
|
57
56
|
let rule_duration = _rule_start.elapsed();
|
|
58
57
|
if rule_duration.as_millis() > 500 {
|
|
59
|
-
|
|
58
|
+
log::debug!("Rule {} took {:?}", rule.name(), rule_duration);
|
|
60
59
|
}
|
|
61
60
|
}
|
|
62
61
|
}
|
|
@@ -64,12 +63,12 @@ pub fn lint(content: &str, rules: &[Box<dyn Rule>], _verbose: bool) -> LintResul
|
|
|
64
63
|
#[cfg(not(test))]
|
|
65
64
|
if _verbose {
|
|
66
65
|
let total_duration = _overall_start.elapsed();
|
|
67
|
-
|
|
66
|
+
log::debug!("Total lint time: {:?}", total_duration);
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
#[cfg(all(debug_assertions, not(test)))]
|
|
71
70
|
if !warnings.is_empty() {
|
|
72
|
-
|
|
71
|
+
log::info!("Found {} warnings", warnings.len());
|
|
73
72
|
}
|
|
74
73
|
|
|
75
74
|
Ok(warnings)
|
|
@@ -566,7 +566,6 @@ fn print_config_with_provenance(sourced: &rumdl_config::SourcedConfig) {
|
|
|
566
566
|
Box::new(MD005ListIndent),
|
|
567
567
|
Box::new(MD006StartBullets),
|
|
568
568
|
Box::new(MD007ULIndent::default()),
|
|
569
|
-
Box::new(MD008ULStyle::default()),
|
|
570
569
|
Box::new(MD009TrailingSpaces::default()),
|
|
571
570
|
Box::new(MD010NoHardTabs::default()),
|
|
572
571
|
Box::new(MD011NoReversedLinks {}),
|
|
@@ -814,9 +813,9 @@ build-backend = \"setuptools.build_meta\"
|
|
|
814
813
|
Some(Commands::Check(args)) => {
|
|
815
814
|
// If --no-config is set, skip config loading
|
|
816
815
|
if cli.no_config {
|
|
817
|
-
run_check(args, None);
|
|
816
|
+
run_check(args, None, cli.no_config);
|
|
818
817
|
} else {
|
|
819
|
-
run_check(args, cli.config.as_deref());
|
|
818
|
+
run_check(args, cli.config.as_deref(), cli.no_config);
|
|
820
819
|
}
|
|
821
820
|
}
|
|
822
821
|
Some(Commands::Rule { rule }) => {
|
|
@@ -829,7 +828,6 @@ build-backend = \"setuptools.build_meta\"
|
|
|
829
828
|
Box::new(MD005ListIndent),
|
|
830
829
|
Box::new(MD006StartBullets),
|
|
831
830
|
Box::new(MD007ULIndent::default()),
|
|
832
|
-
Box::new(MD008ULStyle::default()),
|
|
833
831
|
Box::new(MD009TrailingSpaces::default()),
|
|
834
832
|
Box::new(MD010NoHardTabs::default()),
|
|
835
833
|
Box::new(MD011NoReversedLinks {}),
|
|
@@ -910,7 +908,7 @@ build-backend = \"setuptools.build_meta\"
|
|
|
910
908
|
if let Some((section_part, field_part)) = key.split_once('.') {
|
|
911
909
|
// 1. Load the full SourcedConfig once
|
|
912
910
|
let sourced =
|
|
913
|
-
match rumdl_config::SourcedConfig::
|
|
911
|
+
match rumdl_config::SourcedConfig::load_with_discovery(cli.config.as_deref(), None, cli.no_config) {
|
|
914
912
|
Ok(s) => s,
|
|
915
913
|
Err(e) => {
|
|
916
914
|
eprintln!("{}: {}", "Config error".red().bold(), e);
|
|
@@ -1056,7 +1054,7 @@ build-backend = \"setuptools.build_meta\"
|
|
|
1056
1054
|
let sourced_reg = if *defaults {
|
|
1057
1055
|
rumdl_config::SourcedConfig::default()
|
|
1058
1056
|
} else {
|
|
1059
|
-
match rumdl_config::SourcedConfig::
|
|
1057
|
+
match rumdl_config::SourcedConfig::load_with_discovery(cli.config.as_deref(), None, cli.no_config) {
|
|
1060
1058
|
Ok(s) => s,
|
|
1061
1059
|
Err(e) => {
|
|
1062
1060
|
eprintln!("{}: {}", "Config error".red().bold(), e);
|
|
@@ -1080,7 +1078,7 @@ build-backend = \"setuptools.build_meta\"
|
|
|
1080
1078
|
rumdl_config::SourcedConfig::default()
|
|
1081
1079
|
} else {
|
|
1082
1080
|
// Reload config if not defaults (necessary because we exited early in 'get' case)
|
|
1083
|
-
match rumdl_config::SourcedConfig::
|
|
1081
|
+
match rumdl_config::SourcedConfig::load_with_discovery(cli.config.as_deref(), None, cli.no_config) {
|
|
1084
1082
|
Ok(s) => s,
|
|
1085
1083
|
Err(e) => {
|
|
1086
1084
|
eprintln!("{}: {}", "Config error".red().bold(), e);
|
|
@@ -1131,7 +1129,7 @@ build-backend = \"setuptools.build_meta\"
|
|
|
1131
1129
|
output: "text".to_string(),
|
|
1132
1130
|
};
|
|
1133
1131
|
eprintln!("{}: Deprecation warning: Running 'rumdl .' or 'rumdl [PATHS...]' without a subcommand is deprecated and will be removed in a future release. Please use 'rumdl check .' instead.", "[rumdl]".yellow().bold());
|
|
1134
|
-
run_check(&args, cli.config.as_deref());
|
|
1132
|
+
run_check(&args, cli.config.as_deref(), cli.no_config);
|
|
1135
1133
|
} else {
|
|
1136
1134
|
eprintln!(
|
|
1137
1135
|
"{}: No files or directories specified. Please provide at least one path to lint.",
|
|
@@ -1150,9 +1148,13 @@ build-backend = \"setuptools.build_meta\"
|
|
|
1150
1148
|
}
|
|
1151
1149
|
}
|
|
1152
1150
|
|
|
1153
|
-
fn run_check(args: &CheckArgs, global_config_path: Option<&str
|
|
1151
|
+
fn run_check(args: &CheckArgs, global_config_path: Option<&str>, no_config: bool) {
|
|
1154
1152
|
// 1. Load sourced config (for provenance and validation)
|
|
1155
|
-
let sourced = match rumdl_config::SourcedConfig::
|
|
1153
|
+
let sourced = match rumdl_config::SourcedConfig::load_with_discovery(
|
|
1154
|
+
global_config_path,
|
|
1155
|
+
None,
|
|
1156
|
+
no_config
|
|
1157
|
+
) {
|
|
1156
1158
|
Ok(sourced) => sourced,
|
|
1157
1159
|
Err(e) => {
|
|
1158
1160
|
// Syntax error or type mismatch: fail and exit
|
|
@@ -24,10 +24,6 @@ pub fn load_markdownlint_config(path: &str) -> Result<MarkdownlintConfig, String
|
|
|
24
24
|
.or_else(|_| serde_yaml::from_str(&content))
|
|
25
25
|
.map_err(|e| format!("Failed to parse config as JSON or YAML: {}", e))
|
|
26
26
|
};
|
|
27
|
-
if let Err(ref err) = parse_result {
|
|
28
|
-
eprintln!("\x1b[31mError: Failed to parse configuration file '{}':\n {}\n\nPlease ensure your JSON is valid. All keys and string values must be double-quoted.\x1b[0m", path, err);
|
|
29
|
-
std::process::exit(1);
|
|
30
|
-
}
|
|
31
27
|
parse_result
|
|
32
28
|
}
|
|
33
29
|
|
|
@@ -182,7 +178,7 @@ impl MarkdownlintConfig {
|
|
|
182
178
|
});
|
|
183
179
|
}
|
|
184
180
|
} else {
|
|
185
|
-
|
|
181
|
+
log::error!("Could not convert value for rule key {:?} to rumdl's internal config format. This likely means the configuration value is invalid or not supported for this rule. Please check your markdownlint config.", key);
|
|
186
182
|
std::process::exit(1);
|
|
187
183
|
}
|
|
188
184
|
}
|
|
@@ -5,7 +5,7 @@ use std::fmt;
|
|
|
5
5
|
/// The style for emphasis (MD049)
|
|
6
6
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Default, Hash)]
|
|
7
7
|
pub enum EmphasisStyle {
|
|
8
|
-
/// Consistent with the
|
|
8
|
+
/// Consistent with the most prevalent emphasis style found (or first found if tied)
|
|
9
9
|
#[default]
|
|
10
10
|
Consistent,
|
|
11
11
|
/// Asterisk style (*)
|