11import json
2+ from collections .abc import Sequence
23from dataclasses import asdict
34from pathlib import Path
45from typing import Any , Optional
56
67import click
8+ from dagster_shared .serdes .objects import PackageEntrySnap
79from rich .console import Console
810from rich .table import Table
11+ from rich .text import Text
912
1013from dagster_dg .cli .shared_options import dg_global_options
11- from dagster_dg .component import RemotePackageRegistry
14+ from dagster_dg .component import PackageEntryType , RemotePackageRegistry
1215from dagster_dg .config import normalize_cli_config
1316from dagster_dg .context import DgContext
1417from dagster_dg .defs import (
@@ -63,42 +66,89 @@ def list_component_command(**global_options: object) -> None:
6366
6467
6568# ########################
66- # ##### COMPONENT TYPE
69+ # ##### PACKAGE ENTRY
6770# ########################
6871
6972
70- def _list_package_entries (
71- registry : RemotePackageRegistry , output_json : bool , entry_type : Optional [str ]
73+ ENTRY_TYPE_COLOR_MAP = {"component" : "deep_sky_blue3" , "scaffold-target" : "khaki1" }
74+
75+
76+ def _pretty_entry_types (entry : PackageEntrySnap ) -> Text :
77+ text = Text ()
78+ for entry_type in entry .types :
79+ if len (text ) > 0 :
80+ text += Text (", " )
81+ text += Text (entry_type , style = ENTRY_TYPE_COLOR_MAP .get (entry_type , "" ))
82+ text = Text ("[" ) + text + Text ("]" )
83+ return text
84+
85+
86+ def _package_entry_table (entries : Sequence [PackageEntrySnap ]) -> Table :
87+ sorted_entries = sorted (entries , key = lambda x : x .key .to_typename ())
88+ table = Table (border_style = "dim" , show_lines = True )
89+ table .add_column ("Key" , style = "bold cyan" , no_wrap = True )
90+ table .add_column ("Summary" )
91+ table .add_column ("Types" )
92+ for entry in sorted_entries :
93+ table .add_row (entry .key .to_typename (), entry .summary , _pretty_entry_types (entry ))
94+ return table
95+
96+
97+ def _all_packages_entry_table (
98+ registry : RemotePackageRegistry , name_only : bool , entry_type : Optional [PackageEntryType ]
99+ ) -> Table :
100+ table = Table (border_style = "dim" )
101+
102+ table .add_column ("Package" , style = "bold" )
103+ if not name_only :
104+ table .add_column ("Entries" , style = "bold" )
105+
106+ for package in sorted (registry .packages ):
107+ if not name_only :
108+ entries = registry .get_entries (package , entry_type )
109+ inner_table = _package_entry_table (entries )
110+ table .add_row (package , inner_table )
111+ else :
112+ table .add_row (package )
113+ return table
114+
115+
116+ @list_group .command (name = "packages" , cls = DgClickCommand )
117+ @click .option (
118+ "--name-only" ,
119+ is_flag = True ,
120+ default = False ,
121+ help = "Only display the names of the packages." ,
122+ )
123+ @click .option (
124+ "--package" ,
125+ "-p" ,
126+ help = "Filter by package name." ,
127+ )
128+ @click .option (
129+ "--entry-type" ,
130+ "-t" ,
131+ type = click .Choice (["component" , "scaffold-target" ]),
132+ help = "Filter by entry type." ,
133+ )
134+ @dg_global_options
135+ @cli_telemetry_wrapper
136+ def list_packages_command (
137+ name_only : bool ,
138+ package : Optional [str ],
139+ entry_type : Optional [PackageEntryType ],
140+ ** global_options : object ,
72141) -> None :
73- sorted_keys = sorted (
74- [
75- key
76- for key in registry .keys ()
77- if entry_type is None or entry_type in registry .get (key ).types
78- ],
79- key = lambda k : k .to_typename (),
80- )
81- # JSON
82- if output_json :
83- output : list [dict [str , object ]] = []
84- for key in sorted_keys :
85- obj = registry .get (key )
86- output .append (
87- {
88- "key" : key .to_typename (),
89- "summary" : obj .summary ,
90- }
91- )
92- click .echo (json .dumps (output , indent = 4 ))
93- # TABLE
142+ """List registered Dagster components in the current project environment."""
143+ cli_config = normalize_cli_config (global_options , click .get_current_context ())
144+ dg_context = DgContext .for_defined_registry_environment (Path .cwd (), cli_config )
145+ registry = RemotePackageRegistry .from_dg_context (dg_context )
146+
147+ if package :
148+ table = _package_entry_table (registry .get_entries (package , entry_type ))
94149 else :
95- table = Table (border_style = "dim" )
96- table .add_column ("Package Entry" , style = "bold cyan" , no_wrap = True )
97- table .add_column ("Summary" )
98- for key in sorted_keys :
99- table .add_row (key .to_typename (), registry .get (key ).summary )
100- console = Console ()
101- console .print (table )
150+ table = _all_packages_entry_table (registry , name_only , entry_type = entry_type )
151+ Console ().print (table )
102152
103153
104154@list_group .command (name = "component-type" , cls = DgClickCommand )
@@ -117,7 +167,15 @@ def list_component_type_command(output_json: bool, **global_options: object) ->
117167 dg_context = DgContext .for_defined_registry_environment (Path .cwd (), cli_config )
118168 registry = RemotePackageRegistry .from_dg_context (dg_context )
119169
120- _list_package_entries (registry , output_json , "component" )
170+ if output_json :
171+ output : list [dict [str , object ]] = []
172+ for entry in sorted (
173+ registry .get_entries (entry_type = "component" ), key = lambda x : x .key .to_typename ()
174+ ):
175+ output .append ({"key" : entry .key .to_typename (), "summary" : entry .summary })
176+ click .echo (json .dumps (output , indent = 4 ))
177+ else :
178+ Console ().print (_all_packages_entry_table (registry , False , "component" ))
121179
122180
123181# ########################
0 commit comments