File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 22import sys
33from importlib .metadata import version as _pkg_version , PackageNotFoundError
44from pathlib import Path
5- from typing import Optional , Annotated
5+ from typing import List , Optional , Annotated
66
77import typer
88
@@ -299,6 +299,14 @@ def main(
299299 min = - 1 ,
300300 ),
301301 ] = 50 ,
302+ entrypoint_rules : Annotated [
303+ Optional [List [Path ]],
304+ typer .Option (
305+ "--entrypoint-rules" ,
306+ help = "Extra entrypoint rules file (YAML). Repeatable; merges with "
307+ "the shipped rules. A malformed file is an error." ,
308+ ),
309+ ] = None ,
302310):
303311 # Determinism: pin the interpreter hash seed before any analysis (no-op
304312 # when PYTHONHASHSEED is already set; --version exits before this).
@@ -385,6 +393,7 @@ def main(
385393 pycg_shard_timeout = pycg_shard_timeout ,
386394 pycg_shard_strategy = pycg_shard_strategy ,
387395 pycg_max_iter = pycg_max_iter ,
396+ entrypoint_rules = tuple (entrypoint_rules or ()),
388397 )
389398
390399 _set_log_level (options .verbosity )
Original file line number Diff line number Diff line change @@ -39,3 +39,38 @@ def test_well_formed_disable_list_removes_the_shipped_rule(tmp_path):
3939 rs = load_rules ([user ])
4040 flask = rs .frameworks ["flask" ]
4141 assert all (r .id != "flask.route" for r in flask .decorators )
42+
43+
44+ def test_user_rules_merge_additively_with_shipped (tmp_path ):
45+ extra = tmp_path / "mine.yml"
46+ extra .write_text (
47+ "version: 1\n "
48+ "frameworks:\n "
49+ " inhouse:\n "
50+ " detect: [inhouse]\n "
51+ " decorators:\n "
52+ " - id: inhouse.handler\n "
53+ " match: 'inhouse.app.handler'\n "
54+ )
55+ rs = load_rules ([extra ])
56+ assert "flask" in rs .frameworks # shipped survives
57+ assert "inhouse" in rs .frameworks # user added
58+ assert rs .rulesets == ["shipped" , f"user:{ extra } " ]
59+
60+
61+ def test_user_file_can_disable_a_shipped_rule (tmp_path ):
62+ off = tmp_path / "off.yml"
63+ off .write_text ("version: 1\n disable: [flask.route]\n " )
64+ rs = load_rules ([off ])
65+ assert not any (r .id == "flask.route" for r in rs .frameworks ["flask" ].decorators )
66+ assert any (r .id == "flask.bp-verb" for r in rs .frameworks ["flask" ].decorators )
67+
68+
69+ def test_bad_confidence_value_is_rejected (tmp_path ):
70+ bad = tmp_path / "c.yml"
71+ bad .write_text (
72+ "version: 1\n frameworks:\n x:\n decorators:\n "
73+ " - id: x.y\n match: 'x.y'\n confidence: probably\n "
74+ )
75+ with pytest .raises (RulesError ):
76+ load_rules ([bad ])
You can’t perform that action at this time.
0 commit comments