Skip to content

Commit a49fd50

Browse files
committed
add workflow inspect command with rich output and json export
1 parent 3b6756b commit a49fd50

8 files changed

Lines changed: 716 additions & 0 deletions

File tree

concore_cli/cli.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import click
2+
from rich.console import Console
3+
from rich.table import Table
4+
from rich.panel import Panel
5+
from rich import print as rprint
6+
import sys
7+
import os
8+
from pathlib import Path
9+
10+
from .commands.init import init_project
11+
from .commands.run import run_workflow
12+
from .commands.validate import validate_workflow
13+
from .commands.status import show_status
14+
from .commands.stop import stop_all
15+
from .commands.inspect import inspect_workflow
16+
17+
console = Console()
18+
19+
@click.group()
20+
@click.version_option(version='1.0.0', prog_name='concore')
21+
def cli():
22+
pass
23+
24+
@cli.command()
25+
@click.argument('name', required=True)
26+
@click.option('--template', default='basic', help='Template type to use')
27+
def init(name, template):
28+
try:
29+
init_project(name, template, console)
30+
except Exception as e:
31+
console.print(f"[red]Error:[/red] {str(e)}")
32+
sys.exit(1)
33+
34+
@cli.command()
35+
@click.argument('workflow_file', type=click.Path(exists=True))
36+
@click.option('--source', '-s', default='src', help='Source directory')
37+
@click.option('--output', '-o', default='out', help='Output directory')
38+
@click.option('--type', '-t', default='windows', type=click.Choice(['windows', 'posix', 'docker']), help='Execution type')
39+
@click.option('--auto-build', is_flag=True, help='Automatically run build after generation')
40+
def run(workflow_file, source, output, type, auto_build):
41+
try:
42+
run_workflow(workflow_file, source, output, type, auto_build, console)
43+
except Exception as e:
44+
console.print(f"[red]Error:[/red] {str(e)}")
45+
sys.exit(1)
46+
47+
@cli.command()
48+
@click.argument('workflow_file', type=click.Path(exists=True))
49+
def validate(workflow_file):
50+
try:
51+
validate_workflow(workflow_file, console)
52+
except Exception as e:
53+
console.print(f"[red]Error:[/red] {str(e)}")
54+
sys.exit(1)
55+
56+
@cli.command()
57+
@click.argument('workflow_file', type=click.Path(exists=True))
58+
@click.option('--json', 'output_json', is_flag=True, help='Output in JSON format')
59+
def inspect(workflow_file, output_json):
60+
try:
61+
inspect_workflow(workflow_file, console, output_json)
62+
except Exception as e:
63+
console.print(f"[red]Error:[/red] {str(e)}")
64+
sys.exit(1)
65+
66+
@cli.command()
67+
def status():
68+
try:
69+
show_status(console)
70+
except Exception as e:
71+
console.print(f"[red]Error:[/red] {str(e)}")
72+
sys.exit(1)
73+
74+
@cli.command()
75+
@click.confirmation_option(prompt='Stop all running concore processes?')
76+
def stop():
77+
try:
78+
stop_all(console)
79+
except Exception as e:
80+
console.print(f"[red]Error:[/red] {str(e)}")
81+
sys.exit(1)
82+
83+
if __name__ == '__main__':
84+
cli()

concore_cli/commands/init.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from pathlib import Path
2+
from rich.panel import Panel
3+
import shutil
4+
import os
5+
6+
def init_project(name, template, console):
7+
project_path = Path(name)
8+
9+
if project_path.exists():
10+
console.print(f"[red]Error:[/red] Directory '{name}' already exists")
11+
return
12+
13+
console.print(f"[cyan]Creating project:[/cyan] {name}")
14+
console.print()
15+
16+
project_path.mkdir(parents=True)
17+
(project_path / 'src').mkdir()
18+
(project_path / 'out').mkdir()
19+
(project_path / 'in').mkdir()
20+
21+
sample_workflow = '''<?xml version="1.0" encoding="UTF-8"?>
22+
<graphml xmlns="http://graphml.graphdrawing.org/xmlns">
23+
<graph id="workflow" edgedefault="directed">
24+
<node id="n0">
25+
<data key="d0">
26+
<y:ShapeNode>
27+
<y:NodeLabel>1:controller.py</y:NodeLabel>
28+
</y:ShapeNode>
29+
</data>
30+
</node>
31+
<node id="n1">
32+
<data key="d0">
33+
<y:ShapeNode>
34+
<y:NodeLabel>2:plant.py</y:NodeLabel>
35+
</y:ShapeNode>
36+
</data>
37+
</node>
38+
<edge id="e0" source="n0" target="n1">
39+
<data key="d1">
40+
<y:PolyLineEdge>
41+
<y:EdgeLabel>control_output</y:EdgeLabel>
42+
</y:PolyLineEdge>
43+
</data>
44+
</edge>
45+
<edge id="e1" source="n1" target="n0">
46+
<data key="d1">
47+
<y:PolyLineEdge>
48+
<y:EdgeLabel>sensor_data</y:EdgeLabel>
49+
</y:PolyLineEdge>
50+
</data>
51+
</edge>
52+
</graph>
53+
</graphml>'''
54+
55+
with open(project_path / 'workflow.graphml', 'w') as f:
56+
f.write(sample_workflow)
57+
58+
console.print(f"[green]✓[/green] Created project structure")
59+
console.print(f" [dim]├──[/dim] src/")
60+
console.print(f" [dim]├──[/dim] in/")
61+
console.print(f" [dim]├──[/dim] out/")
62+
console.print(f" [dim]└──[/dim] workflow.graphml")
63+
console.print()
64+
console.print(Panel.fit(
65+
f"[green]Project created successfully![/green]\n\n"
66+
f"Next steps:\n"
67+
f" 1. cd {name}\n"
68+
f" 2. Add your source files to src/\n"
69+
f" 3. concore run workflow.graphml",
70+
border_style="green"
71+
))

0 commit comments

Comments
 (0)