@@ -85,7 +85,7 @@ def main(
8585 typer .Option (
8686 "-f" ,
8787 "--format" ,
88- help = "Output format for --emit json: json or msgpack ." ,
88+ help = "Output format for --emit json: json." ,
8989 case_sensitive = False ,
9090 ),
9191 ] = OutputFormat .JSON ,
@@ -141,26 +141,31 @@ def main(
141141 ),
142142 ] = None ,
143143 analysis_level : Annotated [
144- int ,
144+ Optional [ int ] ,
145145 typer .Option (
146146 "-a" ,
147147 "--analysis-level" ,
148148 help = "Analysis depth: 1=symbol table+Jedi call graph, 2=+PyCG call "
149149 "graph, 3=+native intraprocedural dataflow (CFG/PDG), "
150- "4=+interprocedural SDG (param/summary edges, alias-aware DDG)." ,
150+ "4=+interprocedural SDG (param/summary edges, alias-aware DDG). "
151+ "[default: 1; incompatible with --emit neo4j, which is always "
152+ "full-depth]" ,
151153 min = 1 ,
152154 max = 4 ,
155+ show_default = "1" ,
153156 ),
154- ] = 1 ,
157+ ] = None ,
155158 graphs : Annotated [
156- str ,
159+ Optional [ str ] ,
157160 typer .Option (
158161 "--graphs" ,
159162 help = "Level 3+ only: comma-separated program-graph sections to emit "
160163 "(cfg, dfg, pdg, sdg). Default: cfg,dfg,pdg. `dfg` emits the PDG's data "
161- "edges only; `sdg` requires -a 4." ,
164+ "edges only; `sdg` requires -a 4. Incompatible with --emit neo4j "
165+ "(always full-depth)." ,
166+ show_default = "cfg,dfg,pdg" ,
162167 ),
163- ] = "cfg,dfg,pdg" ,
168+ ] = None ,
164169 graph_field_depth : Annotated [
165170 int ,
166171 typer .Option (
@@ -300,9 +305,40 @@ def main(
300305 _pin_hash_seed ()
301306
302307 # Flag validation (strict: unrecognized values error out, never fall back).
303- selected_graphs = [g .strip () for g in graphs .split ("," ) if g .strip ()]
308+ # -a and --graphs use None sentinels so an explicitly-passed flag is
309+ # distinguishable from the default (#119).
310+ explicit_level = analysis_level is not None
311+ explicit_graphs = graphs is not None
312+
313+ # Neo4j is always full-depth (#119): the graph carries every level's
314+ # facts, so depth/section selectors cannot be combined with it — reject
315+ # explicitly-passed flags and force level 4 with every graph section.
304316 from codeanalyzer .dataflow .builder import VALID_GRAPHS
305317
318+ if emit == EmitTarget .NEO4J :
319+ explicit = [
320+ flag
321+ for flag , was_explicit in (
322+ ("-a/--analysis-level" , explicit_level ),
323+ ("--graphs" , explicit_graphs ),
324+ )
325+ if was_explicit
326+ ]
327+ if explicit :
328+ logger .error (
329+ "--emit neo4j is always full-depth (level 4, all graph "
330+ f"sections); { ' and ' .join (explicit )} cannot be combined with it."
331+ )
332+ raise typer .Exit (code = 2 )
333+ analysis_level = 4
334+ graphs = "," .join (VALID_GRAPHS )
335+
336+ if analysis_level is None :
337+ analysis_level = 1
338+ if graphs is None :
339+ graphs = "cfg,dfg,pdg"
340+ selected_graphs = [g .strip () for g in graphs .split ("," ) if g .strip ()]
341+
306342 unknown_graphs = [g for g in selected_graphs if g not in VALID_GRAPHS ]
307343 if unknown_graphs :
308344 logger .error (
@@ -316,7 +352,7 @@ def main(
316352 if "sdg" in selected_graphs and analysis_level < 4 :
317353 logger .error ("--graphs sdg requires -a 4 (interprocedural SDG)." )
318354 raise typer .Exit (code = 2 )
319- if analysis_level < 3 and graphs != "cfg,dfg,pdg" :
355+ if analysis_level < 3 and explicit_graphs :
320356 logger .error ("--graphs is a level-3 option; pass -a 3 to emit program graphs." )
321357 raise typer .Exit (code = 2 )
322358 if analysis_level < 3 and graph_field_depth != 3 :
@@ -408,16 +444,6 @@ def _write_output(artifacts, output_dir: Path, format: OutputFormat):
408444 f .write (json_str )
409445 logger .info (f"Analysis saved to { output_file } " )
410446
411- elif format == OutputFormat .MSGPACK :
412- output_file = output_dir / "analysis.msgpack"
413- msgpack_data = artifacts .to_msgpack_bytes ()
414- with output_file .open ("wb" ) as f :
415- f .write (msgpack_data )
416- logger .info (f"Analysis saved to { output_file } " )
417- logger .info (
418- f"Compression ratio: { artifacts .get_compression_ratio ():.1%} of JSON size"
419- )
420-
421447
422448app = typer .Typer (
423449 callback = main ,
0 commit comments