Skip to content

Commit

Permalink
Cli fix (#21)
Browse files Browse the repository at this point in the history
* allow to call name or id

* define id and name classmethods

* move lists
  • Loading branch information
clavedeluna authored Sep 6, 2023
1 parent b0fefe7 commit 4668619
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 23 deletions.
6 changes: 3 additions & 3 deletions integration_tests/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ def _assert_run_fields(self, run, output_path):
assert run["elapsed"] != ""
assert (
run["commandLine"]
== f"python -m codemodder tests/samples/ --output {output_path} --codemod-include={self.codemod.METADATA.NAME}"
== f"python -m codemodder tests/samples/ --output {output_path} --codemod-include={self.codemod.name()}"
)
assert run["directory"] == os.path.abspath("tests/samples/")
assert run["sarifs"] == []

def _assert_results_fields(self, results, output_path):
assert len(results) == 1
result = results[0]
assert result["codemod"] == self.codemod.full_name()
assert result["codemod"] == self.codemod.id()
assert len(result["changeset"]) == self.num_changed_files

# A codemod may change multiple files. For now we will
Expand Down Expand Up @@ -116,7 +116,7 @@ def test_file_rewritten(self):
"tests/samples/",
"--output",
self.output_path,
f"--codemod-include={self.codemod.METADATA.NAME}",
f"--codemod-include={self.codemod.name()}",
]

self.check_code_before()
Expand Down
10 changes: 5 additions & 5 deletions src/codemodder/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import sys

from codemodder import __VERSION__
from codemodder.codemods import DEFAULT_CODEMODS
from codemodder.codemods import DEFAULT_CODEMODS, CODEMOD_NAMES, CODEMOD_IDS
from codemodder.logging import logger


Expand All @@ -20,7 +20,7 @@ class ListAction(argparse.Action):

def _print_codemods(self):
for codemod in DEFAULT_CODEMODS:
print(f"pixee:python/{codemod.full_name()}")
print(codemod.id())

def __call__(self, parser, *args, **kwargs):
"""
Expand Down Expand Up @@ -57,13 +57,13 @@ class ValidatedCodmods(CsvListAction):
"""

def validate_items(self, items):
codemod_names = [codemod.METADATA.NAME for codemod in DEFAULT_CODEMODS]
unrecognized_codemods = [name for name in items if name not in codemod_names]
potential_names = CODEMOD_IDS + CODEMOD_NAMES
unrecognized_codemods = [name for name in items if name not in potential_names]

if unrecognized_codemods:
args = {
"values": unrecognized_codemods,
"choices": ", ".join(map(repr, codemod_names)),
"choices": ", ".join(map(repr, CODEMOD_NAMES)),
}
msg = "invalid choice(s): %(values)r (choose from %(choices)s)"
raise argparse.ArgumentError(self, msg % args)
Expand Down
9 changes: 6 additions & 3 deletions src/codemodder/codemods/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@
}
ALL_CODEMODS = DEFAULT_CODEMODS

CODEMOD_IDS = [codemod.id() for codemod in DEFAULT_CODEMODS]
CODEMOD_NAMES = [codemod.name() for codemod in DEFAULT_CODEMODS]


def match_codemods(codemod_include: list, codemod_exclude: list) -> dict:
if not codemod_include and not codemod_exclude:
return {codemod.METADATA.NAME: codemod for codemod in DEFAULT_CODEMODS}
return {codemod.name(): codemod for codemod in DEFAULT_CODEMODS}

# cli should've already prevented both include/exclude from being set.
assert codemod_include or codemod_exclude
Expand All @@ -45,11 +48,11 @@ def match_codemods(codemod_include: list, codemod_exclude: list) -> dict:
return {
name: codemod
for codemod in DEFAULT_CODEMODS
if (name := codemod.METADATA.NAME) not in codemod_exclude
if (name := codemod.name()) not in codemod_exclude
}

return {
name: codemod
for codemod in DEFAULT_CODEMODS
if (name := codemod.METADATA.NAME) in codemod_include
if (name := codemod.name()) in codemod_include
}
9 changes: 7 additions & 2 deletions src/codemodder/codemods/base_codemod.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,14 @@ def __init__(self, file_context):
self.file_context = file_context

@classmethod
def full_name(cls):
def name(cls):
# pylint: disable=no-member
return f"pixee:python/{cls.METADATA.NAME}"
return cls.METADATA.NAME

@classmethod
def id(cls):
# pylint: disable=no-member
return f"pixee:python/{cls.name()}"

@property
def should_transform(self):
Expand Down
2 changes: 1 addition & 1 deletion tests/codemods/base_codemod_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def results_by_id_filepath(self, input_code, root, file_path):
tmp_file.write(input_code)

return semgrep_run(
find_all_yaml_files({self.codemod.METADATA.NAME: self.codemod}), root
find_all_yaml_files({self.codemod.name(): self.codemod}), root
)

def run_and_assert_filepath(self, root, file_path, input_code, expected):
Expand Down
2 changes: 1 addition & 1 deletion tests/codemods/test_include_exclude.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
from codemodder.codemods import DEFAULT_CODEMODS, match_codemods

CODEMODS = {codemod.METADATA.NAME: codemod for codemod in DEFAULT_CODEMODS}
CODEMODS = {codemod.name(): codemod for codemod in DEFAULT_CODEMODS}


class TestMatchCodemods:
Expand Down
3 changes: 0 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import pytest
import mock
from codemodder.codemods import DEFAULT_CODEMODS
from tests.shared import reset_global_state # pylint: disable=unused-import

CODEMOD_NAMES = tuple(codemod.METADATA.NAME for codemod in DEFAULT_CODEMODS)


@pytest.fixture(autouse=True, scope="module")
def disable_write_report():
Expand Down
21 changes: 17 additions & 4 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import pytest
from codemodder.cli import parse_args
from codemodder import __VERSION__
from .conftest import CODEMOD_NAMES

from codemodder.codemods import CODEMOD_IDS


class TestParseArgs:
Expand Down Expand Up @@ -76,9 +77,10 @@ def test_list_prints_codemod_metadata(self, mock_print, cli_args):
with pytest.raises(SystemExit) as err:
parse_args(cli_args)

for print_call in mock_print.call_args_list:
assert print_call[0][0].startswith("pixee:python/")
assert print_call[0][0].endswith(CODEMOD_NAMES)
assert len(mock_print.call_args_list) == len(CODEMOD_IDS)

printed_names = [call[0][0] for call in mock_print.call_args_list]
assert sorted(CODEMOD_IDS) == sorted(printed_names)

assert err.value.args[0] == 0

Expand Down Expand Up @@ -120,3 +122,14 @@ def test_bad_option(self, error_logger):
"CLI error: %s",
"ambiguous option: --codemod=url-sandbox could match --codemod-exclude, --codemod-include",
)

@pytest.mark.parametrize("codemod", ["secure-random", "pixee:python/secure-random"])
def test_codemod_name_or_id(self, codemod):
parse_args(
[
"tests/samples/",
"--output",
"here.txt",
f"--codemod-include={codemod}",
]
)
2 changes: 1 addition & 1 deletion tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from codemodder import global_state
from codemodder.semgrep import run as semgrep_run
from codemodder.cli import parse_args
from .conftest import CODEMOD_NAMES
from codemodder.codemods import CODEMOD_NAMES


class TestRun:
Expand Down

0 comments on commit 4668619

Please sign in to comment.