1717import argparse
1818import logging
1919import os
20+ import pathlib
2021import sys
2122import timeit
2223import traceback
@@ -105,12 +106,20 @@ def AddCommandLineOptions(self, parser: argparse.ArgumentParser) -> None:
105106 default = False ,
106107 help = "Exit on the first plugin failure." ,
107108 )
109+ parser .add_argument (
110+ "-l" ,
111+ "--plugin-list" ,
112+ action = "store_true" ,
113+ default = False ,
114+ help = "List all available plugins for the current configuration file and exit." ,
115+ )
108116 super ().AddCommandLineOptions (parser )
109117
110118 def RetrieveCommandLineOptions (self , args : argparse .Namespace ) -> None :
111119 """Retrieve command line options from the argparser."""
112120 self .disable_plugins = args .disable
113121 self .fail_fast = args .fail_fast
122+ self .list_plugins = args .plugin_list
114123 super ().RetrieveCommandLineOptions (args )
115124
116125 def GetSettingsClass (self ) -> type :
@@ -125,8 +134,42 @@ def GetLoggingFileName(self, loggerType: str) -> str:
125134 """Returns the filename (CI_BUILDLOG) of where the logs for the Edk2CiBuild invocable are stored in."""
126135 return "CI_BUILDLOG"
127136
137+ def ListPlugins (self ) -> None :
138+ """List all available plugins for the current configuration file and exit."""
139+ pluginList = self .plugin_manager .GetPluginsOfClass (ICiBuildPlugin )
140+
141+ data = [
142+ (entry .Module , str (pathlib .Path (entry .descriptor .get ("descriptor_file" , "unknown" )).parent ))
143+ for entry in pluginList
144+ ]
145+
146+ name_width = max (len ("Plugin Name" ), max (len (entry [0 ]) for entry in data ))
147+ dir_width = max (len ("Plugin Directory (Code, Documentation)" ), max (len (entry [1 ]) for entry in data ))
148+
149+ header = f"{ 'Plugin Name' .ljust (name_width )} | { 'Plugin Directory (Code, Documentation)' .ljust (dir_width )} "
150+ separator = f"{ '-' * name_width } -+-{ '-' * dir_width } "
151+
152+ rows = []
153+ for entry in data :
154+ rows .append (f"{ entry [0 ].ljust (name_width )} | { entry [1 ].ljust (dir_width )} " )
155+
156+ table = "\n " .join ([header , separator ] + rows )
157+
158+ print (table )
159+
160+ print ("\n NOTE: You can disable any plugin with PluginName=skip." )
161+ print ("NOTE: CI plugins are not guaranteed to to run in any particular order and may change at any time." )
162+ print (
163+ "NOTE: You can disable all plugins with the --disable-all option, then enable specific plugins with "
164+ "<PluginName>=run"
165+ )
166+
128167 def Go (self ) -> int :
129168 """Executes the core functionality of the Edk2CiBuild invocable."""
169+ if self .list_plugins :
170+ self .ListPlugins ()
171+ return 0
172+
130173 full_start_time = timeit .default_timer ()
131174
132175 log_directory = os .path .join (self .GetWorkspaceRoot (), self .GetLoggingFolderRelativeToRoot ())
0 commit comments