You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: update command-structure design doc to reflect current command inventory
Adds the full top-level command list, one-level and two-level group examples
(dbx spec patch), fixes the stale dbx project -l example, and documents
when two-level nesting is appropriate.
Copy file name to clipboardExpand all lines: docs/design/command-structure.rst
+93-44Lines changed: 93 additions & 44 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,12 +1,12 @@
1
1
Command Structure
2
2
=================
3
3
4
-
This document explains the design decision to use top-level commands instead of nested command groups.
4
+
This document explains the design decisions behind how commands are organised in the CLI.
5
5
6
6
Decision
7
7
--------
8
8
9
-
We prefer **top-level commands** (``dbx clone``, ``dbx sync``) over **nested command groups** (``dbx repo clone``, ``dbx repo sync``).
9
+
We prefer **top-level commands** (``dbx clone``, ``dbx sync``) over **nested command groups** (``dbx repo clone``, ``dbx repo sync``), but command groups and even two-level nesting are used when the domain is rich enough to warrant it.
10
10
11
11
Rationale
12
12
---------
@@ -25,10 +25,11 @@ Common Usage Patterns
25
25
26
26
The most frequently used commands should be at the top level:
27
27
28
-
- ``dbx clone`` - Clone repositories from a group
29
-
- ``dbx sync`` - Sync repositories with upstream
30
-
- ``dbx install`` - Install packages
31
-
- ``dbx test`` - Run tests
28
+
- ``dbx clone`` — Clone repositories from a group
29
+
- ``dbx sync`` — Sync repositories with upstream
30
+
- ``dbx install`` — Install packages
31
+
- ``dbx test`` — Run tests
32
+
- ``dbx list`` — List cloned repositories
32
33
33
34
These are the primary workflows, so they should be as accessible as possible.
34
35
@@ -37,51 +38,103 @@ Consistency with Git
37
38
38
39
Git uses top-level commands (``git clone``, ``git pull``, ``git push``) rather than nested groups (``git repo clone``). This pattern is familiar to developers.
- **Namespacing**: When multiple commands share a common domain (e.g., environment management)
47
-
- **Organization**: When there are many related commands that would clutter the top level
47
+
Single-action commands that are frequently used or domain-agnostic:
48
48
49
-
Examples
50
-
--------
49
+
.. code-block:: text
51
50
52
-
Top-Level Commands (Preferred)
53
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
51
+
dbx branch Git branch operations across repositories
52
+
dbx clone Clone a repository group
53
+
dbx edit Open a repository in an editor
54
+
dbx install Install package dependencies
55
+
dbx just Run just commands in a repository
56
+
dbx list List cloned repositories
57
+
dbx log Git log across repositories
58
+
dbx open Open a repository in the browser
59
+
dbx patch Create Evergreen CI patches
60
+
dbx remove Remove a cloned repository
61
+
dbx status Git status across repositories
62
+
dbx swap Swap between repository versions
63
+
dbx switch Switch git branches across repositories
64
+
dbx sync Sync repositories with upstream
65
+
dbx test Run tests in a repository
66
+
67
+
Command Groups (One Level)
68
+
~~~~~~~~~~~~~~~~~~~~~~~~~~
69
+
70
+
Related subcommands that share a common domain:
54
71
55
72
.. code-block:: bash
56
73
57
-
# Clone repositories
58
-
dbx clone -g pymongo
74
+
# Configuration management
75
+
dbx config init
76
+
dbx config show
77
+
dbx config edit
59
78
60
-
# Sync a repository
61
-
dbx sync mongo-python-driver
79
+
# Documentation operations
80
+
dbx docs build
81
+
dbx docs list
82
+
dbx docs open
62
83
63
-
# List repositories
64
-
dbx list
84
+
# Virtual environment management
85
+
dbx env init
86
+
dbx env list
87
+
dbx env remove
88
+
89
+
# Django project management
90
+
dbx project add myproject
91
+
dbx project install
92
+
dbx project migrate
93
+
dbx project run
94
+
dbx project su
95
+
dbx project list
96
+
dbx project remove
97
+
98
+
Command Groups (Two Levels)
99
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
65
100
66
-
Command Groups (When Appropriate)
67
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
101
+
When a domain has enough distinct sub-domains, two levels of nesting are acceptable. The only current example is ``dbx spec``, where spec-level operations (``sync``, ``list``, ``status``) are clearly separate from patch lifecycle operations:
68
102
69
103
.. code-block:: bash
70
104
71
-
#Environment management
72
-
dbx env create -g pymongo
73
-
dbx env activate -g pymongo
74
-
dbx env list
105
+
#Spec-level operations
106
+
dbx spec sync crud sessions
107
+
dbx spec list
108
+
dbx spec status
75
109
76
-
# Project management
77
-
dbx project add myproject
78
-
dbx project run myproject
79
-
dbx project -l
110
+
# Patch lifecycle (sub-group)
111
+
dbx spec patch apply
112
+
dbx spec patch create PYTHON-1234
113
+
dbx spec patch list
114
+
dbx spec patch remove PYTHON-1234
115
+
dbx spec patch verify
116
+
117
+
Two-level nesting should remain rare. The bar for adding a third level is very high — if you find yourself wanting ``dbx foo bar baz``, consider whether ``foo`` and ``bar`` should be merged or whether ``baz`` belongs at a higher level.
118
+
119
+
When to Use Command Groups
120
+
~~~~~~~~~~~~~~~~~~~~~~~~~~
121
+
122
+
Command groups are appropriate when:
123
+
124
+
- **Multiple related subcommands** share a common domain (e.g., environment management, spec sync)
125
+
- **Namespacing prevents collisions** — ``dbx spec list`` and ``dbx list`` do different things
126
+
- **The group has 3+ subcommands** — a group with only one subcommand adds friction without benefit
127
+
128
+
Top-level placement is preferred when:
129
+
130
+
- The command is used frequently in isolation
131
+
- It has no natural siblings that share state or configuration
132
+
- Adding it to a group would make it harder to discover
80
133
81
134
Migration Notes
82
135
---------------
83
136
84
-
This decision was implemented in a refactoring that moved ``clone`` and ``sync`` from the ``repo`` command group to the top level.
137
+
This design was established when ``clone`` and ``sync`` were promoted from the ``repo`` command group to the top level.
85
138
86
139
**Before:**
87
140
@@ -99,12 +152,12 @@ This decision was implemented in a refactoring that moved ``clone`` and ``sync``
99
152
dbx sync mongo-python-driver
100
153
dbx list
101
154
102
-
The ``repo.py`` module was converted from a command module to a helper functions module, containing only utility functions like ``get_config()``, ``get_base_dir()``, and ``get_repo_groups()``.
155
+
The ``repo.py`` module was converted from a command module to a utility functions module containing helpers like ``get_config()``, ``get_base_dir()``, and ``get_repo_groups()``.
103
156
104
157
Smart Defaults for Convenience
105
158
-------------------------------
106
159
107
-
To further improve usability, commands should provide smart defaults when possible. This reduces typing and makes common workflows faster.
160
+
To further improve usability, commands should provide smart defaults when possible.
108
161
109
162
Project Commands Default to Newest
110
163
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -113,35 +166,31 @@ Most ``dbx project`` commands default to the newest project when no project name
113
166
114
167
.. code-block:: bash
115
168
116
-
# These commands work without specifying a project name
117
169
dbx project run # Run newest project
118
170
dbx project manage shell # Open shell on newest project
119
171
dbx project su # Create superuser on newest project
120
172
dbx project migrate # Run migrations on newest project
121
173
dbx project remove # Remove newest project
122
174
123
-
The "newest" project is determined by filesystem modification time. This is particularly useful during active development when you're frequently working with the same project.
124
-
125
-
When a command defaults to the newest project, it displays an informative message:
175
+
The "newest" project is determined by filesystem modification time. When a command defaults to the newest project, it displays an informative message:
126
176
127
177
.. code-block:: text
128
178
129
179
ℹ️ No project specified, using newest: 'myproject'
130
180
131
-
This design decision follows the principle of **optimizing for the common case**: developers typically work on one project at a time, so requiring the project name for every command adds unnecessary friction.
181
+
This follows the principle of **optimizing for the common case**: developers typically work on one project at a time, so requiring the project name for every command adds unnecessary friction.
132
182
133
183
Future Considerations
134
184
---------------------
135
185
136
-
As the CLI grows, we should continue to evaluate whether commands belong at the top level or in a group:
186
+
As the CLI grows, continue to evaluate whether commands belong at the top level or in a group:
0 commit comments