Skip to content

Commit fad3874

Browse files
committed
wip
1 parent 33b0ea4 commit fad3874

File tree

3 files changed

+39
-58
lines changed

3 files changed

+39
-58
lines changed

flake.nix

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
pyparsing
3030
rich
3131
networkx
32-
phart
3332
];
3433

3534
postInstall = ''
@@ -61,7 +60,7 @@
6160
shellHook = ''
6261
# Create/activate uv virtual environment
6362
if [ ! -d .venv ]; then
64-
echo "Creating uv virtual environment..."
63+
echo "Creating uv virtual environment..." >&2
6564
uv venv
6665
fi
6766
@@ -70,19 +69,22 @@
7069
7170
# Install package in development mode
7271
if [ ! -f .venv/.mudyla-installed ]; then
73-
echo "Installing mudyla with uv..."
72+
echo "Installing mudyla with uv..." >&2
7473
uv pip install -e ".[dev]"
7574
touch .venv/.mudyla-installed
7675
fi
7776
78-
echo "Mudyla development environment (with uv)"
79-
echo "Python version: $(python3 --version)"
80-
echo "UV version: $(uv --version)"
81-
echo ""
82-
echo "Commands:"
83-
echo " uv pip install <package> - Install a package"
84-
echo " uv pip sync - Sync dependencies"
85-
echo " mdl --help - Run mudyla CLI"
77+
# Only show welcome message in interactive shells
78+
if [ -t 0 ]; then
79+
echo "Mudyla development environment (with uv)"
80+
echo "Python version: $(python3 --version)"
81+
echo "UV version: $(uv --version)"
82+
echo ""
83+
echo "Commands:"
84+
echo " uv pip install <package> - Install a package"
85+
echo " uv pip sync - Sync dependencies"
86+
echo " mdl --help - Run mudyla CLI"
87+
fi
8688
'';
8789
};
8890

mudyla/cli.py

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,6 @@
1616
from .utils.project_root import find_project_root
1717
from .utils.colors import ColorFormatter
1818

19-
try:
20-
import networkx as nx
21-
from phart import ASCIIRenderer
22-
PHART_AVAILABLE = True
23-
except ImportError:
24-
PHART_AVAILABLE = False
25-
2619

2720
class CLI:
2821
"""Command-line interface for Mudyla."""
@@ -269,18 +262,7 @@ def run(self, argv: Optional[list[str]] = None) -> int:
269262
# Show execution plan
270263
execution_order = pruned_graph.get_execution_order()
271264
print(f"\n{'📋' if not args.no_color else '▸'} {color.bold('Execution plan:')}")
272-
273-
if PHART_AVAILABLE and not args.no_color:
274-
# Use phart to visualize the DAG
275-
self._visualize_execution_plan_phart(pruned_graph, execution_order, goals, color)
276-
else:
277-
# Fallback to simple text output
278-
for i, action_name in enumerate(execution_order, 1):
279-
node = pruned_graph.get_node(action_name)
280-
deps = ", ".join(sorted(node.dependencies)) if node.dependencies else "none"
281-
is_goal = action_name in goals
282-
goal_marker = " 🎯" if is_goal and not args.no_color else " [GOAL]" if is_goal else ""
283-
print(f" {color.dim(f'{i}.')} {color.highlight(action_name)}{goal_marker} {color.dim(f'(depends on: {deps})')}")
265+
self._visualize_execution_plan(pruned_graph, execution_order, goals, color, args.no_color)
284266

285267
if args.dry_run:
286268
print(f"\n{'ℹ️' if not args.no_color else 'i'} {color.info('Dry run - not executing')}")
@@ -367,42 +349,40 @@ def run(self, argv: Optional[list[str]] = None) -> int:
367349
traceback.print_exc()
368350
return 1
369351

370-
def _visualize_execution_plan_phart(self, graph, execution_order: list[str], goals: list[str], color) -> None:
371-
"""Visualize execution plan using phart.
352+
def _visualize_execution_plan(self, graph, execution_order: list[str], goals: list[str], color, no_color: bool) -> None:
353+
"""Visualize execution plan as a tree.
372354
373355
Args:
374356
graph: The execution graph
375357
execution_order: List of actions in execution order
376358
goals: List of goal actions
377359
color: Color formatter
360+
no_color: Whether to disable colors
378361
"""
379-
import networkx as nx
380-
from phart import ASCIIRenderer, NodeStyle
362+
# Create a tree-like visualization showing dependencies
363+
for i, action_name in enumerate(execution_order, 1):
364+
node = graph.get_node(action_name)
365+
is_goal = action_name in goals
366+
goal_marker = " 🎯" if is_goal and not no_color else " [GOAL]" if is_goal else ""
381367

382-
# Create a NetworkX DiGraph
383-
# Use labels as node IDs so they show up in the visualization
384-
G = nx.DiGraph()
368+
# Format the action with its number
369+
action_label = f"{i}. {action_name}{goal_marker}"
385370

386-
# Create a mapping from action names to labels
387-
label_map = {}
388-
for action_name in execution_order:
389-
order_num = execution_order.index(action_name) + 1
390-
is_goal = action_name in goals
391-
goal_marker = " 🎯" if is_goal else ""
392-
label = f"{order_num}. {action_name}{goal_marker}"
393-
label_map[action_name] = label
394-
G.add_node(label)
395-
396-
# Add edges using labels
397-
for action_name in execution_order:
398-
exec_node = graph.get_node(action_name)
399-
for dep in exec_node.dependencies:
400-
# In a dependency graph, edges go from dependency to dependent
401-
G.add_edge(label_map[dep], label_map[action_name])
402-
403-
# Render the graph with minimal style for compact output
404-
renderer = ASCIIRenderer(G, node_style=NodeStyle.MINIMAL, node_spacing=1, layer_spacing=0)
405-
print(renderer.render())
371+
if not node.dependencies:
372+
# No dependencies - just print the action
373+
print(f" {color.highlight(action_label)}")
374+
else:
375+
# Has dependencies - show them
376+
dep_names = []
377+
for dep in sorted(node.dependencies):
378+
dep_num = execution_order.index(dep) + 1
379+
dep_names.append(f"{dep_num}")
380+
381+
deps_str = ",".join(dep_names)
382+
arrow = "←" if not no_color else "<-"
383+
print(f" {color.highlight(action_label)} {color.dim(f'{arrow} [{deps_str}]')}")
384+
385+
print() # Empty line after plan
406386

407387
def _list_actions(self, document: ParsedDocument) -> None:
408388
"""List all available actions."""

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ dependencies = [
2222
"pyparsing>=3.0.0",
2323
"rich>=13.0.0",
2424
"networkx>=3.0",
25-
"phart>=1.0.0",
2625
]
2726

2827
[project.optional-dependencies]

0 commit comments

Comments
 (0)