From e16e4665484a23e4955429d989c571b734fa65d2 Mon Sep 17 00:00:00 2001 From: clavedeluna Date: Thu, 9 Nov 2023 08:58:02 -0300 Subject: [PATCH] convert django debug codemod to use api --- src/core_codemods/django_debug_flag_on.py | 89 ++++++--------------- tests/codemods/test_django_debug_flag_on.py | 3 + 2 files changed, 29 insertions(+), 63 deletions(-) diff --git a/src/core_codemods/django_debug_flag_on.py b/src/core_codemods/django_debug_flag_on.py index b7d18d1b..da38891f 100644 --- a/src/core_codemods/django_debug_flag_on.py +++ b/src/core_codemods/django_debug_flag_on.py @@ -1,24 +1,16 @@ -from typing import List import libcst as cst -from libcst.codemod import Codemod, CodemodContext -from libcst.metadata import PositionProvider -from codemodder.change import Change -from codemodder.codemods.base_visitor import BaseTransformer -from codemodder.codemods.base_codemod import ( - SemgrepCodemod, - CodemodMetadata, - ReviewGuidance, -) -from codemodder.file_context import FileContext +from codemodder.codemods.api import SemgrepCodemod +from codemodder.codemods.base_codemod import ReviewGuidance from codemodder.codemods.utils import is_django_settings_file -class DjangoDebugFlagOn(SemgrepCodemod, Codemod): - METADATA = CodemodMetadata( - DESCRIPTION="Flip `Django` debug flag to off.", - NAME="django-debug-flag-on", - REVIEW_GUIDANCE=ReviewGuidance.MERGE_AFTER_CURSORY_REVIEW, - REFERENCES=[ +class DjangoDebugFlagOn(SemgrepCodemod): + NAME = "django-debug-flag-on" + DESCRIPTION = "Flip `Django` debug flag to off." + SUMMARY = "Disable Django Debug Mode" + REVIEW_GUIDANCE = ReviewGuidance.MERGE_AFTER_CURSORY_REVIEW + REFERENCES = ( + [ { "url": "https://owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure", "description": "", @@ -29,52 +21,23 @@ class DjangoDebugFlagOn(SemgrepCodemod, Codemod): }, ], ) - SUMMARY = "Disable Django Debug Mode" - CHANGE_DESCRIPTION = METADATA.DESCRIPTION - YAML_FILES = [ - "django-debug-flag-on.yaml", - ] - - METADATA_DEPENDENCIES = (PositionProvider,) - - def __init__(self, codemod_context: CodemodContext, *args): - Codemod.__init__(self, codemod_context) - SemgrepCodemod.__init__(self, *args) - def transform_module_impl(self, tree: cst.Module) -> cst.Module: - # checks if the file we looking is a settings.py file from django's default directory structure + @classmethod + def rule(cls): + return """ + rules: + - id: django-debug-flag-on + pattern: DEBUG = True + paths: + include: + - settings.py + """ + + def leave_Assign(self, original_node, updated_node): + # checks if this module is a settings.py file from django's default directory structure if is_django_settings_file(self.file_context.file_path): - debug_flag_transformer = DebugFlagTransformer( - self.context, self.file_context, self.file_context.findings - ) - new_tree = debug_flag_transformer.transform_module(tree) - if debug_flag_transformer.changes_in_file: - self.file_context.codemod_changes.extend( - debug_flag_transformer.changes_in_file - ) - return new_tree - return tree - - -class DebugFlagTransformer(BaseTransformer): - def __init__( - self, codemod_context: CodemodContext, file_context: FileContext, results - ): - super().__init__(codemod_context, results) - self.line_exclude = file_context.line_exclude - self.line_include = file_context.line_include - self.changes_in_file: List[Change] = [] - - def leave_Assign( - self, original_node: cst.Assign, updated_node: cst.Assign - ) -> cst.Assign: - pos_to_match = self.node_position(original_node) - if self.filter_by_result( - pos_to_match - ) and self.filter_by_path_includes_or_excludes(pos_to_match): - line_number = pos_to_match.start.line - self.changes_in_file.append( - Change(line_number, DjangoDebugFlagOn.CHANGE_DESCRIPTION) - ) - return updated_node.with_changes(value=cst.Name("False")) + return super().leave_Assign(original_node, updated_node) return updated_node + + def on_result_found(self, _, updated_node): + return updated_node.with_changes(value=cst.Name("False")) diff --git a/tests/codemods/test_django_debug_flag_on.py b/tests/codemods/test_django_debug_flag_on.py index 51d329d2..b66b603f 100644 --- a/tests/codemods/test_django_debug_flag_on.py +++ b/tests/codemods/test_django_debug_flag_on.py @@ -15,6 +15,7 @@ def test_settings_dot_py(self, tmpdir): input_code = """DEBUG = True""" expected = """DEBUG = False""" self.run_and_assert_filepath(django_root, file_path, input_code, expected) + assert len(self.file_context.codemod_changes) == 1 def test_not_settings_dot_py(self, tmpdir): django_root, settings_folder = self.create_dir_structure(tmpdir) @@ -23,6 +24,7 @@ def test_not_settings_dot_py(self, tmpdir): input_code = """DEBUG = True""" expected = input_code self.run_and_assert_filepath(django_root, file_path, input_code, expected) + assert len(self.file_context.codemod_changes) == 0 def test_no_manage_dot_py(self, tmpdir): django_root, settings_folder = self.create_dir_structure(tmpdir) @@ -30,3 +32,4 @@ def test_no_manage_dot_py(self, tmpdir): input_code = """DEBUG = True""" expected = input_code self.run_and_assert_filepath(django_root, file_path, input_code, expected) + assert len(self.file_context.codemod_changes) == 0