Skip to content

Conversation

@ktro2828
Copy link
Collaborator

@ktro2828 ktro2828 commented Jan 29, 2026

What

This pull request introduces a new --fix option to the t4sanity CLI tool, enabling automatic fixing of issues detected by sanity checks. It updates the CLI, core checker logic, reporting, and documentation to support and clearly present this new feature. Additionally, it improves the exclusion and reporting of checks.

The following diagram shows the logic of checkers:

flowchart LR
    Start --> A{Can skip?}
    A --> |Yes| B[Skip check and <br/>returns skipped report]
    A --> |No| C[Perform check]
    C --> D{Failed and --fix=True?}
    D --> |Yes| E[Fix issues]
    E --> F[Return report]
    D --> |No| F
Loading

Major new feature: Automatic fixing of issues

  • Adds a --fix option to the CLI, allowing users to attempt to automatically fix issues found during sanity checks. [1] [2] [3]
  • Updates the Checker interface and all checker calls to support a fix parameter, and adds a fix() method for implementing fix logic in each checker. [1] [2]
  • Modifies the reporting system to track and display which issues were fixed, updating the Report dataclass and summary output to include a "Fixed" column. [1] [2] [3] [4] [5]

Documentation improvements

  • Updates the CLI documentation to describe the new --fix option and provide usage examples.
  • Improves the documentation of the --exclude option with clearer examples for excluding rules or groups.

Tests

I checked this feature with sample data tests/sample/t4dataset by editting category.json.

Before running t4sanity tests/sample/t4dataset --fix:

[
  {
    "token": "1c22a023c1a214447d0bc497088c9a3d",
    "name": "car",
    "description": "Vehicle designed primarily for passenger transportation",
    "index": null
  },
  {
    "token": "4db2cce0862dbdf1385186fd604d477a",
    "name": "pedestrian",
    "description": "Person walking or standing",
    "index": 1
  },
  {
    "token": "0531921ca79d7ca8c3815a77122de529",
    "name": "bicycle",
    "description": "Two-wheeled vehicle propelled by pedaling",
    "index": 2
  },
  {
    "token": "bdb3ce20fb731507f2ecf9387071335f",
    "name": "traffic_cone",
    "description": "Cone-shaped marker used to redirect traffic",
    "index": 3
  }
]

After running:

[
  {
    "token": "1c22a023c1a214447d0bc497088c9a3d",
    "name": "car",
    "description": "Vehicle designed primarily for passenger transportation",
    "index": 0
  },
  {
    "token": "4db2cce0862dbdf1385186fd604d477a",
    "name": "pedestrian",
    "description": "Person walking or standing",
    "index": 1
  },
  {
    "token": "0531921ca79d7ca8c3815a77122de529",
    "name": "bicycle",
    "description": "Two-wheeled vehicle propelled by pedaling",
    "index": 2
  },
  {
    "token": "bdb3ce20fb731507f2ecf9387071335f",
    "name": "traffic_cone",
    "description": "Cone-shaped marker used to redirect traffic",
    "index": 3
  }
]

The dumped report would be like:

[
    {
            "id": "REC007",
            "name": "category-indices-consistent",
            "severity": "ERROR",
            "description": "All categories must either have a unique 'index' or all have a 'null' index.",
            "status": "FAILED",
            "reasons": [
                "All categories either must have an 'index' set or all have a 'null' index."
            ],
            "fixed": true
        }
]

@github-actions github-actions bot added documentation Improvements or additions to documentation new-feature New feature or request labels Jan 29, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 29, 2026

☂️ Python Coverage

current status: ❌

Overall Coverage

Lines Covered Coverage Threshold Status
4192 3455 82% 50% 🟢

New Files

No new covered files...

Modified Files

File Coverage Status
t4_devkit/sanity/checker.py 91% 🟢
t4_devkit/sanity/context.py 83% 🟢
t4_devkit/sanity/record/rec007.py 66% 🔴
t4_devkit/sanity/result.py 63% 🔴
t4_devkit/sanity/run.py 100% 🟢
TOTAL 81% 🔴

updated for commit: 8c77fb5 by action🐍

@ktro2828 ktro2828 force-pushed the feat/sanity/fix-option branch 2 times, most recently from 83593cc to ca5df65 Compare January 29, 2026 15:18
@ktro2828 ktro2828 self-assigned this Jan 29, 2026
@ktro2828 ktro2828 force-pushed the feat/sanity/fix-option branch 2 times, most recently from 2c9efa0 to 3f28a79 Compare January 30, 2026 00:14
Signed-off-by: ktro2828 <kotaro.uetake@tier4.jp>
Signed-off-by: ktro2828 <kotaro.uetake@tier4.jp>
Signed-off-by: ktro2828 <kotaro.uetake@tier4.jp>
Signed-off-by: ktro2828 <kotaro.uetake@tier4.jp>
@ktro2828 ktro2828 force-pushed the feat/sanity/fix-option branch from 3f28a79 to 1d633a7 Compare January 30, 2026 00:22
@ktro2828 ktro2828 marked this pull request as ready for review January 30, 2026 00:46
severity: Severity

def __call__(self, context: SanityContext) -> Report:
def __call__(self, context: SanityContext, fix: bool = False) -> Report:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nit) It would be nice to have a short doc comment that stresses that if the check succeeded (has no reasons), no fixes will be applied.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch, I added docstring for the behavior in 6e3b1ec.

if not self.is_passed(strict=strict):
parts.append(f"\033[31m {self.id}:\033[0m\n")
# print failure reasons
color = self.PALETTE["RED"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nit) Rename color, color1 etc. to their color, e.g. ansi_red or color_red or red

Copy link
Collaborator Author

@ktro2828 ktro2828 Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I simplified color code by using colorama in 8c77fb5.

# print failure or warning but fixed reasons
color1 = self.PALETTE["YELLOW"] if self.severity.is_warning() else self.PALETTE["RED"]
color2 = self.PALETTE["GREEN"]
parts.append(f"{color1} {self.id}:\033[0m {color2}--> FIXED🎉\033[0m\n")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nit) Coloring looks a bit confusing since the category/reason are still red, so the user might think something is wrong. I don't have a better idea though 🤷‍♂️

Image

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good feedback! I updated to colorize green for fixed reasons, looks better than the previous one:

Screenshot from 2026-01-30 11-43-56

@mojomex
Copy link
Contributor

mojomex commented Jan 30, 2026

Tested with a few corrupted category.jsons and it behaved correctly with and without --fix.

Copy link
Contributor

@SamratThapa120 SamratThapa120 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks.

Copy link
Contributor

@shekharhimanshu shekharhimanshu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 💯
Thank you

Signed-off-by: ktro2828 <kotaro.uetake@tier4.jp>
Signed-off-by: ktro2828 <kotaro.uetake@tier4.jp>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation new-feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants