rumdl 0.0.55__tar.gz → 0.0.56__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.55 → rumdl-0.0.56}/Cargo.lock +1 -1
- {rumdl-0.0.55 → rumdl-0.0.56}/Cargo.toml +1 -1
- {rumdl-0.0.55 → rumdl-0.0.56}/PKG-INFO +1 -1
- {rumdl-0.0.55 → rumdl-0.0.56}/benches/rule_performance.rs +14 -24
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/RULES.md +1 -2
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md030.md +4 -2
- rumdl-0.0.56/parity_check.py +130 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/config.rs +26 -11
- {rumdl-0.0.55 → rumdl-0.0.56}/src/main.rs +78 -16
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rule.rs +4 -3
- rumdl-0.0.56/src/rules/md004_unordered_list_style.rs +456 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md007_ul_indent.rs +90 -28
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md013_line_length.rs +58 -43
- rumdl-0.0.56/src/rules/md030_list_marker_space.rs +226 -0
- rumdl-0.0.56/src/rules/md032_blanks_around_lists.rs +575 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md033_no_inline_html.rs +57 -130
- rumdl-0.0.56/src/rules/md034_no_bare_urls.rs +496 -0
- rumdl-0.0.56/src/rules/md039_no_space_in_links.rs +466 -0
- rumdl-0.0.56/src/rules/md049_emphasis_style.rs +303 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/mod.rs +1 -12
- {rumdl-0.0.55 → rumdl-0.0.56}/src/utils/document_structure.rs +55 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/advanced_integration_tests.rs +19 -10
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/config_application_tests.rs +2 -1
- rumdl-0.0.56/tests/integration_tests.rs +18 -0
- rumdl-0.0.56/tests/json_output_test.rs +34 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/perf_check.rs +5 -1
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md004_test.rs +164 -122
- rumdl-0.0.56/tests/rules/md007_test.rs +292 -0
- rumdl-0.0.56/tests/rules/md013_test.rs +262 -0
- rumdl-0.0.56/tests/rules/md030_test.rs +194 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md032_test.rs +34 -1
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md033_test.rs +23 -31
- rumdl-0.0.56/tests/rules/md034_test.rs +336 -0
- rumdl-0.0.56/tests/rules/md039_test.rs +296 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/mod.rs +0 -1
- rumdl-0.0.55/docs/md015.md +0 -93
- rumdl-0.0.55/src/rules/md004_unordered_list_style.rs +0 -361
- rumdl-0.0.55/src/rules/md015_no_missing_space_after_list_marker.rs +0 -157
- rumdl-0.0.55/src/rules/md030_list_marker_space.rs +0 -428
- rumdl-0.0.55/src/rules/md032_blanks_around_lists.rs +0 -418
- rumdl-0.0.55/src/rules/md034_no_bare_urls.rs +0 -328
- rumdl-0.0.55/src/rules/md039_no_space_in_links.rs +0 -365
- rumdl-0.0.55/src/rules/md049_emphasis_style.rs +0 -375
- rumdl-0.0.55/tests/integration_tests.rs +0 -40
- rumdl-0.0.55/tests/rules/md007_test.rs +0 -127
- rumdl-0.0.55/tests/rules/md013_test.rs +0 -128
- rumdl-0.0.55/tests/rules/md015_proptest.rs +0 -23
- rumdl-0.0.55/tests/rules/md015_test.rs +0 -243
- rumdl-0.0.55/tests/rules/md030_test.rs +0 -48
- rumdl-0.0.55/tests/rules/md034_test.rs +0 -255
- rumdl-0.0.55/tests/rules/md039_test.rs +0 -89
- {rumdl-0.0.55 → rumdl-0.0.56}/.rumdl.toml +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/MANIFEST.in +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/Makefile +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/README.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/assets/logo.png +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/benches/range_performance.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/benches/range_utils_benchmark.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md001.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md002.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md003.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md004.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md005.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md006.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md007.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md008.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md009.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md010.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md011.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md012.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md013.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md014.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md018.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md019.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md020.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md021.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md022.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md023.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md024.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md025.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md026.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md027.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md028.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md029.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md031.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md032.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md033.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md034.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md035.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md036.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md037.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md038.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md039.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md040.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md041.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md042.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md043.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md044.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md045.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md046.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md047.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md048.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md049.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md050.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md051.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md052.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md053.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md054.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md055.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md056.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md057.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/docs/md058.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/issues/plan-rule-parity-with-markdownlint.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/pyproject.toml +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/python/MANIFEST.in +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/python/PYTHON-README.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/python/rumdl/__init__.py +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/python/rumdl/__main__.py +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/python/rumdl/py.typed +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/rumdl.toml.example +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/init.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/lib.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/lint_context.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/markdownlint_config.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/profiling.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/python.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/blockquote_utils.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/code_block_utils.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/code_fence_utils.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/emphasis_style.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/front_matter_utils.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/heading_utils.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/list_utils.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md001_heading_increment.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md002_first_heading_h1.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md003_heading_style.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md005_list_indent.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md006_start_bullets.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md008_ul_style.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md009_trailing_spaces.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md010_no_hard_tabs.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md011_no_reversed_links.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md012_no_multiple_blanks.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md014_commands_show_output.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md018_no_missing_space_atx.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md019_no_multiple_space_atx.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md020_no_missing_space_closed_atx.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md021_no_multiple_space_closed_atx.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md022_blanks_around_headings.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md023_heading_start_left.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md024_no_duplicate_heading.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md025_single_title.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md026_no_trailing_punctuation.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md027_multiple_spaces_blockquote.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md028_no_blanks_blockquote.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md029_ordered_list_prefix.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md031_blanks_around_fences.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md035_hr_style.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md036_no_emphasis_only_first.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md037_spaces_around_emphasis.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md038_no_space_in_code.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md040_fenced_code_language.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md041_first_line_heading.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md042_no_empty_links.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md043_required_headings.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md044_proper_names.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md045_no_alt_text.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md046_code_block_style.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md047_single_trailing_newline.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md048_code_fence_style.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md050_strong_style.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md051_link_fragments.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md052_reference_links_images.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md053_link_image_reference_definitions.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md054_link_image_style.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md055_table_pipe_style.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md056_table_column_count.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md057_existing_relative_links.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/md058_blanks_around_tables.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/rules/strong_style.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/utils/code_block_utils.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/utils/early_returns.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/utils/element_cache.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/utils/markdown_elements.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/utils/mod.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/utils/range_utils.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/src/utils/regex_cache.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/cli_duplication_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/cli_integration_tests.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/commonmark_compliance_tests.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/comprehensive_integration_tests.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/config_tests.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/init_command_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/init_tests.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/lib.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/markdownlint_cli_integration.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/markdownlint_config_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/md030_edge_cases.md +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/output_format_tests.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/pyproject_config_tests.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md001_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md001_unicode_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md002_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md003_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md005_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md006_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md006_unicode_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md008_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md009_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md010_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md011_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md012_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md014_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md018_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md019_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md020_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md021_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md022_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md023_extended_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md023_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md024_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md025_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md026_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md027_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md028_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md029_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md031_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md033_extended_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md035_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md036_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md037_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md038_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md040_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md041_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md042_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md043_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md044_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md045_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md046_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md047_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md048_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md049_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md050_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md051_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md052_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md053_additional_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md053_proptest.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md053_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md054_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md054_unicode_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md055_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md056_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md057_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/rules/md058_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/utils/blockquote_utils_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/utils/code_block_utils_extended_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/utils/code_block_utils_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/utils/core_utils_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/utils/front_matter_utils_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/utils/line_index_test.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/utils/mod.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/utils_markdown_edge_cases.rs +0 -0
- {rumdl-0.0.55 → rumdl-0.0.56}/tests/utils_tests.rs +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
|
2
2
|
use rumdl::rule::Rule;
|
|
3
3
|
use rumdl::rules::{
|
|
4
|
-
MD013LineLength,
|
|
5
|
-
|
|
4
|
+
MD013LineLength, MD033NoInlineHtml, MD037NoSpaceInEmphasis, MD044ProperNames, MD051LinkFragments,
|
|
5
|
+
MD053LinkImageReferenceDefinitions,
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
/// Benchmark MD013 rule on a large content with long lines
|
|
@@ -16,20 +16,11 @@ fn bench_md013(c: &mut Criterion) {
|
|
|
16
16
|
let rule = MD013LineLength::default();
|
|
17
17
|
|
|
18
18
|
c.bench_function("MD013 check 100 long lines", |b| {
|
|
19
|
-
b.iter(|| rule.check(
|
|
19
|
+
b.iter(|| rule.check(&rumdl::lint_context::LintContext::new(&content)))
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
c.bench_function("MD013 fix 100 long lines", |b| {
|
|
23
|
-
b.iter(|| rule.fix(
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/// Benchmark MD015 rule on a large content with list items
|
|
28
|
-
fn bench_md015(c: &mut Criterion) {
|
|
29
|
-
let rule = MD015NoMissingSpaceAfterListMarker::new();
|
|
30
|
-
let content = "-Item 1\n*Item 2\n+Item 3".repeat(1000);
|
|
31
|
-
c.bench_function("MD015 fix 1000 items", |b| {
|
|
32
|
-
b.iter(|| rule.fix(black_box(&content)))
|
|
23
|
+
b.iter(|| rule.fix(&rumdl::lint_context::LintContext::new(&content)))
|
|
33
24
|
});
|
|
34
25
|
}
|
|
35
26
|
|
|
@@ -44,7 +35,7 @@ fn bench_md033(c: &mut Criterion) {
|
|
|
44
35
|
let rule = MD033NoInlineHtml::default();
|
|
45
36
|
|
|
46
37
|
c.bench_function("MD033 check 500 HTML tags", |b| {
|
|
47
|
-
b.iter(|| rule.check(
|
|
38
|
+
b.iter(|| rule.check(&rumdl::lint_context::LintContext::new(&content)))
|
|
48
39
|
});
|
|
49
40
|
}
|
|
50
41
|
|
|
@@ -68,11 +59,11 @@ fn bench_md037(c: &mut Criterion) {
|
|
|
68
59
|
let rule = MD037NoSpaceInEmphasis;
|
|
69
60
|
|
|
70
61
|
c.bench_function("MD037 check 500 emphasis markers", |b| {
|
|
71
|
-
b.iter(|| rule.check(
|
|
62
|
+
b.iter(|| rule.check(&rumdl::lint_context::LintContext::new(&content)))
|
|
72
63
|
});
|
|
73
64
|
|
|
74
65
|
c.bench_function("MD037 fix 500 emphasis markers", |b| {
|
|
75
|
-
b.iter(|| rule.fix(
|
|
66
|
+
b.iter(|| rule.fix(&rumdl::lint_context::LintContext::new(&content)))
|
|
76
67
|
});
|
|
77
68
|
}
|
|
78
69
|
|
|
@@ -117,11 +108,11 @@ fn bench_md044(c: &mut Criterion) {
|
|
|
117
108
|
let rule = MD044ProperNames::new(proper_names, true); // true = exclude code blocks
|
|
118
109
|
|
|
119
110
|
c.bench_function("MD044 check 500 proper name occurrences", |b| {
|
|
120
|
-
b.iter(|| rule.check(
|
|
111
|
+
b.iter(|| rule.check(&rumdl::lint_context::LintContext::new(&content)))
|
|
121
112
|
});
|
|
122
113
|
|
|
123
114
|
c.bench_function("MD044 fix 500 proper name occurrences", |b| {
|
|
124
|
-
b.iter(|| rule.fix(
|
|
115
|
+
b.iter(|| rule.fix(&rumdl::lint_context::LintContext::new(&content)))
|
|
125
116
|
});
|
|
126
117
|
}
|
|
127
118
|
|
|
@@ -155,7 +146,7 @@ fn bench_md051(c: &mut Criterion) {
|
|
|
155
146
|
let rule = MD051LinkFragments::new();
|
|
156
147
|
|
|
157
148
|
c.bench_function("MD051 check 500 link fragments", |b| {
|
|
158
|
-
b.iter(|| rule.check(
|
|
149
|
+
b.iter(|| rule.check(&rumdl::lint_context::LintContext::new(&content)))
|
|
159
150
|
});
|
|
160
151
|
}
|
|
161
152
|
|
|
@@ -190,7 +181,7 @@ fn bench_md053(c: &mut Criterion) {
|
|
|
190
181
|
c.bench_function("MD053 check cold cache", |b| {
|
|
191
182
|
b.iter_with_setup(
|
|
192
183
|
MD053LinkImageReferenceDefinitions::default, // Create a new instance for each iteration
|
|
193
|
-
|r| r.check(
|
|
184
|
+
|r| r.check(&rumdl::lint_context::LintContext::new(&content)),
|
|
194
185
|
)
|
|
195
186
|
});
|
|
196
187
|
|
|
@@ -198,21 +189,20 @@ fn bench_md053(c: &mut Criterion) {
|
|
|
198
189
|
c.bench_function("MD053 check warm cache", |b| {
|
|
199
190
|
// First, prime the cache
|
|
200
191
|
let primed_rule = rule.clone();
|
|
201
|
-
let _ = primed_rule.check(&content);
|
|
192
|
+
let _ = primed_rule.check(&rumdl::lint_context::LintContext::new(&content));
|
|
202
193
|
|
|
203
194
|
// Then benchmark with warm cache
|
|
204
|
-
b.iter(|| primed_rule.check(
|
|
195
|
+
b.iter(|| primed_rule.check(&rumdl::lint_context::LintContext::new(&content)))
|
|
205
196
|
});
|
|
206
197
|
|
|
207
198
|
c.bench_function("MD053 fix unused references", |b| {
|
|
208
|
-
b.iter(|| rule.fix(
|
|
199
|
+
b.iter(|| rule.fix(&rumdl::lint_context::LintContext::new(&content)))
|
|
209
200
|
});
|
|
210
201
|
}
|
|
211
202
|
|
|
212
203
|
criterion_group!(
|
|
213
204
|
benches,
|
|
214
205
|
bench_md013,
|
|
215
|
-
bench_md015,
|
|
216
206
|
bench_md033,
|
|
217
207
|
bench_md037,
|
|
218
208
|
bench_md044,
|
|
@@ -82,7 +82,7 @@ Each rule has a brief description and a link to its detailed documentation.
|
|
|
82
82
|
|
|
83
83
|
| Rule ID | Rule Name | Description |
|
|
84
84
|
|---------|-----------|-------------|
|
|
85
|
-
| [MD014](md014.md) | Commands show output |
|
|
85
|
+
| [MD014](md014.md) | Commands show output | Code blocks should show output when appropriate |
|
|
86
86
|
| [MD040](md040.md) | Fenced code language | Fenced code blocks should have a language specified |
|
|
87
87
|
| [MD046](md046.md) | Code block style | Code block style |
|
|
88
88
|
| [MD048](md048.md) | Code fence style | Code fence style |
|
|
@@ -111,7 +111,6 @@ Each rule has a brief description and a link to its detailed documentation.
|
|
|
111
111
|
|
|
112
112
|
| Rule ID | Rule Name | Description |
|
|
113
113
|
|---------|-----------|-------------|
|
|
114
|
-
| [MD015](md015.md) | No multiple space list | Multiple spaces after list marker |
|
|
115
114
|
| [MD057](md057.md) | Relative links | Relative links should exist |
|
|
116
115
|
|
|
117
116
|
## Using Rules
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## Description
|
|
4
4
|
|
|
5
|
-
This rule ensures that there is a consistent number of spaces between list markers and the list content.
|
|
6
|
-
By default, ordered lists should have one space after the list marker, and unordered lists should have
|
|
5
|
+
This rule ensures that there is a consistent number of spaces between list markers and the list content.
|
|
6
|
+
By default, ordered lists should have one space after the list marker, and unordered lists should have
|
|
7
7
|
one space after the list marker.
|
|
8
8
|
|
|
9
|
+
**Note:** This rule covers multiple spaces (e.g., `* Item`) after list markers, but does **not** warn for missing space (e.g., `*Item`) after the marker. Lines like `*Item` are not considered valid list items per CommonMark and markdownlint, and are ignored.
|
|
10
|
+
|
|
9
11
|
Consistent spacing improves readability and ensures proper rendering across different Markdown processors.
|
|
10
12
|
|
|
11
13
|
<!-- markdownlint-disable -->
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import subprocess
|
|
3
|
+
import json
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
PARITY_CORPUS = Path(__file__).parent / "parity_corpus"
|
|
8
|
+
RUMDL_BIN = "cargo run --bin rumdl --"
|
|
9
|
+
MARKDOWNLINT_BIN = "markdownlint-cli2"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def run_rumdl(md_file):
|
|
13
|
+
cmd = f"{RUMDL_BIN} check '{md_file}' --output json --no-config"
|
|
14
|
+
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
|
15
|
+
if result.returncode != 0 and not result.stdout.strip():
|
|
16
|
+
print(f"[rumdl] Error running on {md_file}: {result.stderr}")
|
|
17
|
+
return []
|
|
18
|
+
try:
|
|
19
|
+
return json.loads(result.stdout)
|
|
20
|
+
except Exception as e:
|
|
21
|
+
print(f"[rumdl] Failed to parse JSON for {md_file}: {e}")
|
|
22
|
+
return []
|
|
23
|
+
|
|
24
|
+
def run_markdownlint(md_file):
|
|
25
|
+
cmd = ["npx", MARKDOWNLINT_BIN, str(md_file), "--json", "--no-config", "--no-summary", "--quiet"]
|
|
26
|
+
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
27
|
+
if result.returncode not in (0, 1):
|
|
28
|
+
print(f"[markdownlint] Error running on {md_file}: {result.stderr}")
|
|
29
|
+
return []
|
|
30
|
+
# Try stdout first
|
|
31
|
+
if result.stdout.strip():
|
|
32
|
+
try:
|
|
33
|
+
return json.loads(result.stdout)
|
|
34
|
+
except Exception as e:
|
|
35
|
+
print(f"[markdownlint] Failed to parse JSON from stdout for {md_file}: {e}")
|
|
36
|
+
print(f"[markdownlint] stdout for {md_file}:")
|
|
37
|
+
print(result.stdout)
|
|
38
|
+
# If stdout is empty, try stderr
|
|
39
|
+
if result.stderr.strip():
|
|
40
|
+
try:
|
|
41
|
+
return json.loads(result.stderr)
|
|
42
|
+
except Exception as e:
|
|
43
|
+
print(f"[markdownlint] Failed to parse JSON from stderr for {md_file}: {e}")
|
|
44
|
+
print(f"[markdownlint] stderr for {md_file}:")
|
|
45
|
+
print(result.stderr)
|
|
46
|
+
return []
|
|
47
|
+
|
|
48
|
+
def normalize_rumdl(warning, file):
|
|
49
|
+
# TODO: Implement normalization logic for rumdl output
|
|
50
|
+
return {
|
|
51
|
+
"file": str(file),
|
|
52
|
+
"line": warning.get("line"),
|
|
53
|
+
"column": warning.get("column"),
|
|
54
|
+
"rule": warning.get("rule_name"),
|
|
55
|
+
"message": warning.get("message"),
|
|
56
|
+
"fix": warning.get("fix"),
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
def normalize_markdownlint(warning):
|
|
60
|
+
# TODO: Implement normalization logic for markdownlint output
|
|
61
|
+
return {
|
|
62
|
+
"file": warning.get("fileName"),
|
|
63
|
+
"line": warning.get("lineNumber"),
|
|
64
|
+
"column": (warning.get("errorRange") or [1])[0] if warning.get("errorRange") else 1,
|
|
65
|
+
"rule": warning.get("ruleNames", [None])[0],
|
|
66
|
+
"message": warning.get("ruleDescription"),
|
|
67
|
+
"fix": warning.get("fixInfo"),
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
def compare_warnings(rumdl_warnings, markdownlint_warnings):
|
|
71
|
+
# Sort by (line, column, rule, message)
|
|
72
|
+
def key(w):
|
|
73
|
+
return (
|
|
74
|
+
w.get("line", 0),
|
|
75
|
+
w.get("column", 0),
|
|
76
|
+
w.get("rule", ""),
|
|
77
|
+
w.get("message", "")
|
|
78
|
+
)
|
|
79
|
+
r_sorted = sorted(rumdl_warnings, key=key)
|
|
80
|
+
m_sorted = sorted(markdownlint_warnings, key=key)
|
|
81
|
+
|
|
82
|
+
r_set = set(json.dumps(w, sort_keys=True) for w in r_sorted)
|
|
83
|
+
m_set = set(json.dumps(w, sort_keys=True) for w in m_sorted)
|
|
84
|
+
|
|
85
|
+
only_in_rumdl = r_set - m_set
|
|
86
|
+
only_in_markdownlint = m_set - r_set
|
|
87
|
+
|
|
88
|
+
if not only_in_rumdl and not only_in_markdownlint:
|
|
89
|
+
print("All warnings match!")
|
|
90
|
+
return True
|
|
91
|
+
|
|
92
|
+
if only_in_rumdl:
|
|
93
|
+
print(f" Warnings only in rumdl ({len(only_in_rumdl)}):")
|
|
94
|
+
for w in list(only_in_rumdl)[:10]:
|
|
95
|
+
print(" ", json.loads(w))
|
|
96
|
+
if len(only_in_rumdl) > 10:
|
|
97
|
+
print(f" ...and {len(only_in_rumdl) - 10} more.")
|
|
98
|
+
if only_in_markdownlint:
|
|
99
|
+
print(f" Warnings only in markdownlint ({len(only_in_markdownlint)}):")
|
|
100
|
+
for w in list(only_in_markdownlint)[:10]:
|
|
101
|
+
print(" ", json.loads(w))
|
|
102
|
+
if len(only_in_markdownlint) > 10:
|
|
103
|
+
print(f" ...and {len(only_in_markdownlint) - 10} more.")
|
|
104
|
+
print(f" Common warnings: {len(r_set & m_set)}")
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
def main():
|
|
108
|
+
md_files = sorted(PARITY_CORPUS.glob("*.md"))
|
|
109
|
+
if not md_files:
|
|
110
|
+
print("No markdown files found in parity_corpus/")
|
|
111
|
+
sys.exit(1)
|
|
112
|
+
all_passed = True
|
|
113
|
+
for md_file in md_files:
|
|
114
|
+
print(f"\n=== {md_file} ===")
|
|
115
|
+
rumdl_raw = run_rumdl(md_file)
|
|
116
|
+
markdownlint_raw = run_markdownlint(md_file)
|
|
117
|
+
rumdl_norm = [normalize_rumdl(w, md_file) for w in rumdl_raw]
|
|
118
|
+
markdownlint_norm = [normalize_markdownlint(w) for w in markdownlint_raw if w.get("fileName") == str(md_file)]
|
|
119
|
+
if not compare_warnings(rumdl_norm, markdownlint_norm):
|
|
120
|
+
print(f"Mismatch found in {md_file}")
|
|
121
|
+
all_passed = False
|
|
122
|
+
if all_passed:
|
|
123
|
+
print("\nAll files match between rumdl and markdownlint!")
|
|
124
|
+
sys.exit(0)
|
|
125
|
+
else:
|
|
126
|
+
print("\nSome files have mismatches.")
|
|
127
|
+
sys.exit(1)
|
|
128
|
+
|
|
129
|
+
if __name__ == "__main__":
|
|
130
|
+
main()
|
|
@@ -12,6 +12,8 @@ use std::fs;
|
|
|
12
12
|
use std::io;
|
|
13
13
|
use std::path::Path;
|
|
14
14
|
use toml_edit::DocumentMut;
|
|
15
|
+
use std::env;
|
|
16
|
+
use log;
|
|
15
17
|
|
|
16
18
|
lazy_static! {
|
|
17
19
|
// Map common markdownlint config keys to rumdl rule names
|
|
@@ -150,7 +152,7 @@ exclude = [
|
|
|
150
152
|
"vendor",
|
|
151
153
|
"dist",
|
|
152
154
|
"build",
|
|
153
|
-
|
|
155
|
+
|
|
154
156
|
# Specific files or patterns
|
|
155
157
|
"CHANGELOG.md",
|
|
156
158
|
"LICENSE.md",
|
|
@@ -670,6 +672,13 @@ impl SourcedConfig {
|
|
|
670
672
|
config_path: Option<&str>,
|
|
671
673
|
cli_overrides: Option<&SourcedGlobalConfig>,
|
|
672
674
|
) -> Result<Self, ConfigError> {
|
|
675
|
+
use std::env;
|
|
676
|
+
log::debug!("[rumdl-config] Current working directory: {:?}", env::current_dir());
|
|
677
|
+
if config_path.is_none() {
|
|
678
|
+
log::debug!("[rumdl-config] No explicit config_path provided, will search default locations");
|
|
679
|
+
} else {
|
|
680
|
+
log::debug!("[rumdl-config] Explicit config_path provided: {:?}", config_path);
|
|
681
|
+
}
|
|
673
682
|
let mut sourced_config = SourcedConfig::default();
|
|
674
683
|
let mut loaded_toml_or_pyproject = false;
|
|
675
684
|
|
|
@@ -680,6 +689,8 @@ impl SourcedConfig {
|
|
|
680
689
|
.file_name()
|
|
681
690
|
.and_then(|name| name.to_str())
|
|
682
691
|
.unwrap_or("");
|
|
692
|
+
log::debug!("[rumdl-config] Trying to load config file: {}", filename);
|
|
693
|
+
let path_str = path.to_string();
|
|
683
694
|
|
|
684
695
|
// Known markdownlint config files
|
|
685
696
|
const MARKDOWNLINT_FILENAMES: &[&str] = &[
|
|
@@ -692,40 +703,41 @@ impl SourcedConfig {
|
|
|
692
703
|
{
|
|
693
704
|
let content = std::fs::read_to_string(path).map_err(|e| ConfigError::IoError {
|
|
694
705
|
source: e,
|
|
695
|
-
path:
|
|
706
|
+
path: path_str.clone(),
|
|
696
707
|
})?;
|
|
697
708
|
if filename == "pyproject.toml" {
|
|
698
|
-
if let Some(fragment) = parse_pyproject_toml(&content,
|
|
709
|
+
if let Some(fragment) = parse_pyproject_toml(&content, &path_str)? {
|
|
699
710
|
sourced_config.merge(fragment);
|
|
700
|
-
sourced_config.loaded_files.push(
|
|
711
|
+
sourced_config.loaded_files.push(path_str.clone());
|
|
701
712
|
loaded_toml_or_pyproject = true;
|
|
702
713
|
}
|
|
703
714
|
} else {
|
|
704
|
-
let fragment = parse_rumdl_toml(&content,
|
|
715
|
+
let fragment = parse_rumdl_toml(&content, &path_str)?;
|
|
705
716
|
sourced_config.merge(fragment);
|
|
706
|
-
sourced_config.loaded_files.push(
|
|
717
|
+
sourced_config.loaded_files.push(path_str.clone());
|
|
707
718
|
loaded_toml_or_pyproject = true;
|
|
708
719
|
}
|
|
709
720
|
} else if MARKDOWNLINT_FILENAMES.contains(&filename) {
|
|
710
721
|
// Parse as markdownlint config (JSON/YAML)
|
|
711
|
-
let fragment = load_from_markdownlint(
|
|
722
|
+
let fragment = load_from_markdownlint(&path_str)?;
|
|
712
723
|
sourced_config.merge(fragment);
|
|
713
|
-
sourced_config.loaded_files.push(
|
|
724
|
+
sourced_config.loaded_files.push(path_str.clone());
|
|
714
725
|
// Do NOT set loaded_toml_or_pyproject = true; markdownlint is fallback only
|
|
715
726
|
} else {
|
|
716
727
|
// Try TOML only
|
|
717
728
|
let content = std::fs::read_to_string(path).map_err(|e| ConfigError::IoError {
|
|
718
729
|
source: e,
|
|
719
|
-
path:
|
|
730
|
+
path: path_str.clone(),
|
|
720
731
|
})?;
|
|
721
|
-
let fragment = parse_rumdl_toml(&content,
|
|
732
|
+
let fragment = parse_rumdl_toml(&content, &path_str)?;
|
|
722
733
|
sourced_config.merge(fragment);
|
|
723
|
-
sourced_config.loaded_files.push(
|
|
734
|
+
sourced_config.loaded_files.push(path_str.clone());
|
|
724
735
|
loaded_toml_or_pyproject = true;
|
|
725
736
|
}
|
|
726
737
|
} else {
|
|
727
738
|
// 2. Discover and load default files: pyproject.toml first
|
|
728
739
|
if std::path::Path::new("pyproject.toml").exists() {
|
|
740
|
+
log::debug!("[rumdl-config] Found pyproject.toml in current directory");
|
|
729
741
|
let content = std::fs::read_to_string("pyproject.toml").map_err(|e| {
|
|
730
742
|
ConfigError::IoError {
|
|
731
743
|
source: e,
|
|
@@ -746,6 +758,7 @@ impl SourcedConfig {
|
|
|
746
758
|
// 3. Discover and load .rumdl.toml / rumdl.toml (overrides pyproject)
|
|
747
759
|
for filename in [".rumdl.toml", "rumdl.toml"] {
|
|
748
760
|
if std::path::Path::new(filename).exists() {
|
|
761
|
+
log::debug!("[rumdl-config] Found {} in current directory", filename);
|
|
749
762
|
let content =
|
|
750
763
|
std::fs::read_to_string(filename).map_err(|e| ConfigError::IoError {
|
|
751
764
|
source: e,
|
|
@@ -756,6 +769,8 @@ impl SourcedConfig {
|
|
|
756
769
|
sourced_config.loaded_files.push(filename.to_string());
|
|
757
770
|
loaded_toml_or_pyproject = true;
|
|
758
771
|
break; // Load only the first one found
|
|
772
|
+
} else {
|
|
773
|
+
log::debug!("[rumdl-config] {} not found in current directory", filename);
|
|
759
774
|
}
|
|
760
775
|
}
|
|
761
776
|
}
|
|
@@ -37,9 +37,13 @@ struct Cli {
|
|
|
37
37
|
#[arg(long, global = true, help = "Path to configuration file")]
|
|
38
38
|
config: Option<String>,
|
|
39
39
|
|
|
40
|
+
/// Ignore all configuration files and use built-in defaults
|
|
41
|
+
#[arg(long, global = true, help = "Ignore all configuration files and use built-in defaults")]
|
|
42
|
+
no_config: bool,
|
|
43
|
+
|
|
40
44
|
/// Fix issues automatically where possible
|
|
41
45
|
#[arg(short, long, default_value = "false", hide = true)]
|
|
42
|
-
|
|
46
|
+
_fix: bool,
|
|
43
47
|
|
|
44
48
|
/// List all available rules
|
|
45
49
|
#[arg(short, long, default_value = "false", hide = true)]
|
|
@@ -127,7 +131,7 @@ struct CheckArgs {
|
|
|
127
131
|
|
|
128
132
|
/// Fix issues automatically where possible
|
|
129
133
|
#[arg(short, long, default_value = "false")]
|
|
130
|
-
|
|
134
|
+
_fix: bool,
|
|
131
135
|
|
|
132
136
|
/// List all available rules
|
|
133
137
|
#[arg(short, long, default_value = "false")]
|
|
@@ -168,6 +172,10 @@ struct CheckArgs {
|
|
|
168
172
|
/// Quiet mode
|
|
169
173
|
#[arg(short, long)]
|
|
170
174
|
quiet: bool,
|
|
175
|
+
|
|
176
|
+
/// Output format: text (default) or json
|
|
177
|
+
#[arg(long, short = 'o', default_value = "text")]
|
|
178
|
+
output: String,
|
|
171
179
|
}
|
|
172
180
|
|
|
173
181
|
// Get a complete set of enabled rules based on CLI options and config
|
|
@@ -203,11 +211,14 @@ fn get_enabled_rules_from_checkargs(
|
|
|
203
211
|
config.global.disable.iter().map(|s| s.as_str()).collect();
|
|
204
212
|
|
|
205
213
|
if let Some(enabled_cli) = &cli_enable_set {
|
|
206
|
-
//
|
|
207
|
-
|
|
214
|
+
// Normalize CLI enable values
|
|
215
|
+
let enabled_cli_normalized: HashSet<String> = enabled_cli.iter()
|
|
216
|
+
.map(|s| normalize_key(s))
|
|
217
|
+
.collect();
|
|
218
|
+
let _all_rule_names: Vec<String> = all_rules.iter().map(|r| normalize_key(r.name())).collect();
|
|
208
219
|
final_rules = all_rules
|
|
209
220
|
.into_iter()
|
|
210
|
-
.filter(|rule|
|
|
221
|
+
.filter(|rule| enabled_cli_normalized.contains(&normalize_key(rule.name())))
|
|
211
222
|
.collect();
|
|
212
223
|
// Note: CLI --disable is IGNORED if CLI --enable is present.
|
|
213
224
|
} else {
|
|
@@ -456,7 +467,7 @@ fn print_results_from_checkargs(params: PrintResultsArgs) {
|
|
|
456
467
|
// Show results summary
|
|
457
468
|
if has_issues {
|
|
458
469
|
// If fix mode is enabled, only show the fixed summary
|
|
459
|
-
if args.
|
|
470
|
+
if args._fix && total_issues_fixed > 0 {
|
|
460
471
|
println!(
|
|
461
472
|
"\n{} Fixed {}/{} issues in {} {} ({}ms)",
|
|
462
473
|
"Fixed:".green().bold(),
|
|
@@ -485,7 +496,7 @@ fn print_results_from_checkargs(params: PrintResultsArgs) {
|
|
|
485
496
|
duration_ms
|
|
486
497
|
);
|
|
487
498
|
|
|
488
|
-
if !args.
|
|
499
|
+
if !args._fix && total_fixable_issues > 0 {
|
|
489
500
|
// Display the exact count of fixable issues
|
|
490
501
|
println!(
|
|
491
502
|
"Run with `--fix` to automatically fix {} of the {} issues",
|
|
@@ -561,7 +572,6 @@ fn print_config_with_provenance(sourced: &rumdl_config::SourcedConfig) {
|
|
|
561
572
|
Box::new(MD011NoReversedLinks {}),
|
|
562
573
|
Box::new(MD012NoMultipleBlanks::default()),
|
|
563
574
|
Box::new(MD013LineLength::default()),
|
|
564
|
-
Box::new(MD015NoMissingSpaceAfterListMarker::default()),
|
|
565
575
|
Box::new(MD018NoMissingSpaceAtx {}),
|
|
566
576
|
Box::new(MD019NoMultipleSpaceAtx {}),
|
|
567
577
|
Box::new(MD020NoMissingSpaceClosedAtx {}),
|
|
@@ -802,7 +812,12 @@ build-backend = \"setuptools.build_meta\"
|
|
|
802
812
|
}
|
|
803
813
|
}
|
|
804
814
|
Some(Commands::Check(args)) => {
|
|
805
|
-
|
|
815
|
+
// If --no-config is set, skip config loading
|
|
816
|
+
if cli.no_config {
|
|
817
|
+
run_check(args, None);
|
|
818
|
+
} else {
|
|
819
|
+
run_check(args, cli.config.as_deref());
|
|
820
|
+
}
|
|
806
821
|
}
|
|
807
822
|
Some(Commands::Rule { rule }) => {
|
|
808
823
|
use rumdl::rules::*;
|
|
@@ -820,7 +835,6 @@ build-backend = \"setuptools.build_meta\"
|
|
|
820
835
|
Box::new(MD011NoReversedLinks {}),
|
|
821
836
|
Box::new(MD012NoMultipleBlanks::default()),
|
|
822
837
|
Box::new(MD013LineLength::default()),
|
|
823
|
-
Box::new(MD015NoMissingSpaceAfterListMarker::default()),
|
|
824
838
|
Box::new(MD018NoMissingSpaceAtx {}),
|
|
825
839
|
Box::new(MD019NoMultipleSpaceAtx {}),
|
|
826
840
|
Box::new(MD020NoMissingSpaceClosedAtx {}),
|
|
@@ -1104,7 +1118,7 @@ build-backend = \"setuptools.build_meta\"
|
|
|
1104
1118
|
if !cli.paths.is_empty() {
|
|
1105
1119
|
let args = CheckArgs {
|
|
1106
1120
|
paths: cli.paths.clone(),
|
|
1107
|
-
|
|
1121
|
+
_fix: cli._fix,
|
|
1108
1122
|
list_rules: cli.list_rules,
|
|
1109
1123
|
disable: cli.disable.clone(),
|
|
1110
1124
|
enable: cli.enable.clone(),
|
|
@@ -1114,6 +1128,7 @@ build-backend = \"setuptools.build_meta\"
|
|
|
1114
1128
|
verbose: cli.verbose,
|
|
1115
1129
|
profile: cli.profile,
|
|
1116
1130
|
quiet: cli.quiet,
|
|
1131
|
+
output: "text".to_string(),
|
|
1117
1132
|
};
|
|
1118
1133
|
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());
|
|
1119
1134
|
run_check(&args, cli.config.as_deref());
|
|
@@ -1182,8 +1197,25 @@ fn run_check(args: &CheckArgs, global_config_path: Option<&str>) {
|
|
|
1182
1197
|
return;
|
|
1183
1198
|
}
|
|
1184
1199
|
|
|
1200
|
+
// JSON output mode: collect all warnings and print as JSON
|
|
1201
|
+
if args.output == "json" {
|
|
1202
|
+
let mut all_warnings = Vec::new();
|
|
1203
|
+
for file_path in &file_paths {
|
|
1204
|
+
let warnings = process_file_collect_warnings(
|
|
1205
|
+
file_path,
|
|
1206
|
+
&enabled_rules,
|
|
1207
|
+
args._fix,
|
|
1208
|
+
args.verbose,
|
|
1209
|
+
args.quiet,
|
|
1210
|
+
);
|
|
1211
|
+
all_warnings.extend(warnings);
|
|
1212
|
+
}
|
|
1213
|
+
println!("{}", serde_json::to_string_pretty(&all_warnings).unwrap());
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1185
1217
|
// Confirm with the user if we're fixing a large number of files
|
|
1186
|
-
if args.
|
|
1218
|
+
if args._fix && file_paths.len() > 10 && !args.quiet {
|
|
1187
1219
|
println!(
|
|
1188
1220
|
"You are about to fix {} files. This will modify files in-place.",
|
|
1189
1221
|
file_paths.len()
|
|
@@ -1214,7 +1246,7 @@ fn run_check(args: &CheckArgs, global_config_path: Option<&str>) {
|
|
|
1214
1246
|
let (file_has_issues, issues_found, issues_fixed, fixable_issues) = process_file(
|
|
1215
1247
|
file_path,
|
|
1216
1248
|
&enabled_rules,
|
|
1217
|
-
args.
|
|
1249
|
+
args._fix,
|
|
1218
1250
|
args.verbose,
|
|
1219
1251
|
args.quiet,
|
|
1220
1252
|
);
|
|
@@ -1265,7 +1297,7 @@ fn run_check(args: &CheckArgs, global_config_path: Option<&str>) {
|
|
|
1265
1297
|
fn process_file(
|
|
1266
1298
|
file_path: &str,
|
|
1267
1299
|
rules: &[Box<dyn Rule>],
|
|
1268
|
-
|
|
1300
|
+
_fix: bool,
|
|
1269
1301
|
verbose: bool,
|
|
1270
1302
|
quiet: bool,
|
|
1271
1303
|
) -> (bool, usize, usize, usize) {
|
|
@@ -1329,7 +1361,7 @@ fn process_file(
|
|
|
1329
1361
|
|
|
1330
1362
|
// Add fix indicator if this warning has a fix
|
|
1331
1363
|
let fix_indicator = if warning.fix.is_some() {
|
|
1332
|
-
if
|
|
1364
|
+
if _fix {
|
|
1333
1365
|
" [fixed]"
|
|
1334
1366
|
} else {
|
|
1335
1367
|
" [*]"
|
|
@@ -1353,7 +1385,7 @@ fn process_file(
|
|
|
1353
1385
|
|
|
1354
1386
|
// Fix issues if requested
|
|
1355
1387
|
let mut warnings_fixed = 0;
|
|
1356
|
-
if
|
|
1388
|
+
if _fix {
|
|
1357
1389
|
// Skip rules that don't have fixes
|
|
1358
1390
|
for rule in rules {
|
|
1359
1391
|
if all_warnings
|
|
@@ -1415,3 +1447,33 @@ fn process_file(
|
|
|
1415
1447
|
|
|
1416
1448
|
(true, total_warnings, warnings_fixed, fixable_warnings)
|
|
1417
1449
|
}
|
|
1450
|
+
|
|
1451
|
+
fn process_file_collect_warnings(
|
|
1452
|
+
file_path: &str,
|
|
1453
|
+
rules: &[Box<dyn Rule>],
|
|
1454
|
+
_fix: bool,
|
|
1455
|
+
verbose: bool,
|
|
1456
|
+
quiet: bool,
|
|
1457
|
+
) -> Vec<rumdl::rule::LintWarning> {
|
|
1458
|
+
use std::time::Instant;
|
|
1459
|
+
let _start_time = Instant::now();
|
|
1460
|
+
if verbose && !quiet {
|
|
1461
|
+
println!("Processing file: {}", file_path);
|
|
1462
|
+
}
|
|
1463
|
+
let content = match std::fs::read_to_string(file_path) {
|
|
1464
|
+
Ok(content) => content,
|
|
1465
|
+
Err(_) => return Vec::new(),
|
|
1466
|
+
};
|
|
1467
|
+
std::env::set_var("RUMDL_FILE_PATH", file_path);
|
|
1468
|
+
let warnings_result = rumdl::lint(&content, rules, verbose);
|
|
1469
|
+
std::env::remove_var("RUMDL_FILE_PATH");
|
|
1470
|
+
let mut all_warnings = warnings_result.unwrap_or_default();
|
|
1471
|
+
all_warnings.sort_by(|a, b| {
|
|
1472
|
+
if a.line == b.line {
|
|
1473
|
+
a.column.cmp(&b.column)
|
|
1474
|
+
} else {
|
|
1475
|
+
a.line.cmp(&b.line)
|
|
1476
|
+
}
|
|
1477
|
+
});
|
|
1478
|
+
all_warnings
|
|
1479
|
+
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
use dyn_clone::DynClone;
|
|
6
6
|
use std::ops::Range;
|
|
7
7
|
use thiserror::Error;
|
|
8
|
+
use serde::Serialize;
|
|
8
9
|
|
|
9
10
|
// Import document structure
|
|
10
11
|
use crate::lint_context::LintContext;
|
|
@@ -36,7 +37,7 @@ pub enum LintError {
|
|
|
36
37
|
|
|
37
38
|
pub type LintResult = Result<Vec<LintWarning>, LintError>;
|
|
38
39
|
|
|
39
|
-
#[derive(Debug, PartialEq, Clone)]
|
|
40
|
+
#[derive(Debug, PartialEq, Clone, Serialize)]
|
|
40
41
|
pub struct LintWarning {
|
|
41
42
|
pub message: String,
|
|
42
43
|
pub line: usize,
|
|
@@ -46,13 +47,13 @@ pub struct LintWarning {
|
|
|
46
47
|
pub rule_name: Option<&'static str>,
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
#[derive(Debug, PartialEq, Clone)]
|
|
50
|
+
#[derive(Debug, PartialEq, Clone, Serialize)]
|
|
50
51
|
pub struct Fix {
|
|
51
52
|
pub range: Range<usize>,
|
|
52
53
|
pub replacement: String,
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
#[derive(Debug, PartialEq, Clone, Copy)]
|
|
56
|
+
#[derive(Debug, PartialEq, Clone, Copy, Serialize)]
|
|
56
57
|
pub enum Severity {
|
|
57
58
|
Error,
|
|
58
59
|
Warning,
|