1- import sys
21import typing as t
32
43import django
54import ellar_cli .click as click
5+ from django .core .management import get_commands , load_command_class
6+
7+ BLACKLISTED_COMMANDS : t .Final [t .Set [str ]] = {
8+ "runserver" ,
9+ "startapp" ,
10+ "startproject" ,
11+ }
612
713
814class _CommandItem (t .NamedTuple ):
915 name : str
1016 description : str
1117
1218
13- _django_support_commands : t .List [_CommandItem ] = [
14- _CommandItem (
15- name = "migrate" ,
16- description = "Synchronizes the database state with the current set of models and migrations" ,
17- ),
18- _CommandItem (
19- name = "makemigrations" ,
20- description = "Creates new migrations based on the changes detected to your models." ,
21- ),
22- _CommandItem (
23- name = "check" ,
24- description = "inspects the entire Django project for common problems" ,
25- ),
26- _CommandItem (
27- name = "createcachetable" ,
28- description = "Creates the cache tables for use with the database cache backend" ,
29- ),
30- _CommandItem (
31- name = "dbshell" ,
32- description = "Runs the command-line client for the database engine" ,
33- ),
34- _CommandItem (
35- name = "diffsettings" ,
36- description = "Displays differences between the current settings and default settings" ,
37- ),
38- _CommandItem (
39- name = "dumpdata" ,
40- description = "Outputs to standard output all data in the database" ,
41- ),
42- _CommandItem (
43- name = "flush" ,
44- description = "Removes all data from the database and re-executes any post-synchronization handlers" ,
45- ),
46- _CommandItem (
47- name = "inspectdb" , description = "Introspects the database tables in the database"
48- ),
49- _CommandItem (
50- name = "loaddata" ,
51- description = "Searches for and loads the contents into the database." ,
52- ),
53- _CommandItem (
54- name = "optimizemigration" ,
55- description = "Optimizes the operations for the named migration and overrides the existing file" ,
56- ),
57- _CommandItem (
58- name = "showmigrations" , description = "Shows all migrations in a project."
59- ),
60- _CommandItem (
61- name = "sqlflush" ,
62- description = "Prints the SQL statements that would be executed for the flush command" ,
63- ),
64- _CommandItem (
65- name = "sqlmigrate" , description = "Prints the SQL for the named migration."
66- ),
67- _CommandItem (
68- name = "sqlsequencereset" ,
69- description = "Prints the SQL statements for resetting sequences for the given app name(s)" ,
70- ),
71- _CommandItem (
72- name = "squashmigrations" , description = "Squashes the migrations for app_label"
73- ),
74- _CommandItem (
75- name = "startapp" , description = "Creates a Django app directory structure"
76- ),
77- _CommandItem (
78- name = "changepassword" ,
79- description = "This command is only available if Django’s authentication system" ,
80- ),
81- _CommandItem (
82- name = "createsuperuser" ,
83- description = "Creates a superuser account (a user who has all permissions)" ,
84- ),
85- _CommandItem (
86- name = "collectstatic" , description = "Expose static files to STATIC_ROOT folder"
87- ),
88- _CommandItem (name = "findstatic" , description = "Search for a static file location" ),
89- _CommandItem (
90- name = "clearsessions" ,
91- description = "Can be run as a cron job or directly to clean out expired sessions." ,
92- ),
93- ]
19+ def get_command_description (command_name : str ) -> str :
20+ module = get_commands ()[command_name ]
21+ CommandClass = load_command_class (module , command_name )
22+ return CommandClass .help or ""
23+
24+
25+ def generate_command_list () -> t .List [_CommandItem ]:
26+ commands = get_commands ()
27+ command_list : t .List [_CommandItem ] = []
28+ for command in commands :
29+ if command in BLACKLISTED_COMMANDS :
30+ continue
31+ description = get_command_description (command )
32+ command_list .append (_CommandItem (name = command , description = description ))
33+ return command_list
34+
35+
36+ _django_support_commands = generate_command_list ()
9437
9538
9639def version_callback (ctx : click .Context , _ : t .Any , value : bool ) -> None :
9740 if value :
9841 click .echo (f"Django Version: { django .__version__ } " )
99- raise click . Exit ( 0 )
42+ ctx . exit ( )
10043
10144
10245@click .group (
@@ -118,15 +61,6 @@ def django_command(ctx: click.Context) -> None:
11861
11962
12063def _add_django_command (command_item : _CommandItem ) -> None :
121- def help_callback (ctx : click .Context , _ : t .Any , value : bool ) -> None :
122- from django .core .management import execute_from_command_line
123-
124- if value :
125- args = ["manage.py" , command_item .name , "--help" ]
126-
127- execute_from_command_line (args )
128- raise click .Exit (0 )
129-
13064 @django_command .command (
13165 name = command_item .name ,
13266 help = command_item .description ,
@@ -136,21 +70,17 @@ def help_callback(ctx: click.Context, _: t.Any, value: bool) -> None:
13670 @click .option (
13771 "-h" ,
13872 "--help" ,
139- callback = help_callback ,
140- help = "Show the version and exit." ,
73+ help = "Show the command help." ,
14174 is_flag = True ,
14275 expose_value = False ,
14376 is_eager = True ,
14477 )
145- @click .with_app_context
146- def _command () -> None :
147- from django .core .management import execute_from_command_line
148-
149- args = ["manage.py" , command_item .name ]
150-
151- for item in sys .argv [3 :]:
152- args .extend (item .split (" " ))
153- execute_from_command_line (args )
78+ @click .pass_context
79+ def command (
80+ ctx : click .Context , * args : t .Tuple [t .Any , ...], ** kwargs : t .Dict [str , t .Any ]
81+ ) -> None :
82+ command_args = ["manage.py" , command_item .name ] + list (ctx .args )
83+ django .core .management .execute_from_command_line (command_args )
15484
15585
15686list (map (_add_django_command , _django_support_commands ))
0 commit comments