Skip to content

Commit b3e32f4

Browse files
committed
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.
1 parent 1183655 commit b3e32f4

1 file changed

Lines changed: 93 additions & 44 deletions

File tree

docs/design/command-structure.rst

Lines changed: 93 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
Command Structure
22
=================
33

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.
55

66
Decision
77
--------
88

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.
1010

1111
Rationale
1212
---------
@@ -25,10 +25,11 @@ Common Usage Patterns
2525

2626
The most frequently used commands should be at the top level:
2727

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
3233

3334
These are the primary workflows, so they should be as accessible as possible.
3435

@@ -37,51 +38,103 @@ Consistency with Git
3738

3839
Git uses top-level commands (``git clone``, ``git pull``, ``git push``) rather than nested groups (``git repo clone``). This pattern is familiar to developers.
3940

40-
When to Use Command Groups
41-
~~~~~~~~~~~~~~~~~~~~~~~~~~~
41+
Current Command Inventory
42+
-------------------------
4243

43-
Command groups are still useful for:
44+
Top-Level Commands
45+
~~~~~~~~~~~~~~~~~~
4446

45-
- **Related subcommands**: ``dbx env create``, ``dbx env activate``, ``dbx env list``
46-
- **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:
4848

49-
Examples
50-
--------
49+
.. code-block:: text
5150
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:
5471

5572
.. code-block:: bash
5673
57-
# Clone repositories
58-
dbx clone -g pymongo
74+
# Configuration management
75+
dbx config init
76+
dbx config show
77+
dbx config edit
5978
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
6283
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+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
65100

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:
68102

69103
.. code-block:: bash
70104
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
75109
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
80133

81134
Migration Notes
82135
---------------
83136

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.
85138

86139
**Before:**
87140

@@ -99,12 +152,12 @@ This decision was implemented in a refactoring that moved ``clone`` and ``sync``
99152
dbx sync mongo-python-driver
100153
dbx list
101154
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()``.
103156

104157
Smart Defaults for Convenience
105158
-------------------------------
106159

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.
108161

109162
Project Commands Default to Newest
110163
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -113,35 +166,31 @@ Most ``dbx project`` commands default to the newest project when no project name
113166

114167
.. code-block:: bash
115168
116-
# These commands work without specifying a project name
117169
dbx project run # Run newest project
118170
dbx project manage shell # Open shell on newest project
119171
dbx project su # Create superuser on newest project
120172
dbx project migrate # Run migrations on newest project
121173
dbx project remove # Remove newest project
122174
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:
126176

127177
.. code-block:: text
128178
129179
ℹ️ No project specified, using newest: 'myproject'
130180
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.
132182

133183
Future Considerations
134184
---------------------
135185

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:
137187

138188
- **Top level**: Frequently used, standalone operations
139189
- **Command groups**: Related operations that share context or configuration
190+
- **Two-level groups**: Only when a domain is large enough to have distinct sub-domains
140191

141-
We should also look for opportunities to add smart defaults that reduce typing while maintaining clarity:
192+
When adding smart defaults:
142193

143194
- **Sensible defaults**: Commands should work with minimal arguments for common use cases
144195
- **Clear feedback**: When defaults are applied, inform the user what was chosen
145196
- **Easy override**: Defaults should be easy to override when needed
146-
147-
The goal is to keep the CLI intuitive and easy to use while maintaining good organization.

0 commit comments

Comments
 (0)