Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat: add shell completion for ddev config and ddev config global#7356

Merged
rfay merged 3 commits intoddev:mainfrom
stasadev:20250606_stasadev_config_completion
Jun 16, 2025
Merged

feat: add shell completion for ddev config and ddev config global#7356
rfay merged 3 commits intoddev:mainfrom
stasadev:20250606_stasadev_config_completion

Conversation

@stasadev
Copy link
Member

@stasadev stasadev commented Jun 6, 2025

The Issue

ddev config and ddev config global should have autocompletion.

How This PR Solves The Issue

  • Adds autocompletion for ddev config and ddev config global with tests.
  • Updates description for some flags.

Manual Testing Instructions

ddev config --help
ddev config global --help

Press <TAB><TAB> with:

ddev config --project-type=
ddev config --php-version=
ddev config --router-http-port=
ddev config --router-https-port=
ddev config --xdebug-enabled=
ddev config --no-project-mount=
ddev config --omit-containers=
ddev config --omit-containers=db,
ddev config --omit-containers=ddev-ssh-agent,
ddev config --webserver-type=
ddev config --performance-mode=
ddev config --xhprof-mode=
ddev config --fail-on-hook-fail=
ddev config --mailpit-http-port=
ddev config --mailpit-https-port=
ddev config --project-tld=
ddev config --use-dns-when-possible=
ddev config --disable-settings-management=
ddev config --composer-version=
ddev config --bind-all-interfaces=
ddev config --database=
ddev config --nodejs-version=
ddev config --default-container-timeout=
ddev config --disable-upload-dirs-warning=
ddev config --corepack-enable=

Press <TAB><TAB> with:

ddev config global --omit-containers=
ddev config global --omit-containers=ddev-router,
ddev config global --omit-containers=ddev-ssh-agent,
ddev config global --instrumentation-opt-in=
ddev config global --router-bind-all-interfaces=
ddev config global --internet-detection-timeout-ms=
ddev config global --use-letsencrypt=
ddev config global --simple-formatting=
ddev config global --use-hardened-images=
ddev config global --fail-on-hook-fail=
ddev config global --performance-mode=
ddev config global --xhprof-mode=
ddev config global --table-style=
ddev config global --project-tld=
ddev config global --no-bind-mounts=
ddev config global --router-http-port=
ddev config global --router-https-port=
ddev config global --mailpit-http-port=
ddev config global --mailpit-https-port=
ddev config global --traefik-monitor-port=

Automated Testing Overview

Release/Deployment Notes

@stasadev stasadev requested a review from a team as a code owner June 6, 2025 14:05
@github-actions
Copy link

github-actions bot commented Jun 6, 2025

@stasadev
Copy link
Member Author

stasadev commented Jun 9, 2025

Moving to draft until I understand how DDEV handles default config values.

If it doesn't work as I expected, it's not a big deal to partially revert my last commit here.

@stasadev stasadev marked this pull request as draft June 9, 2025 17:45
@stasadev stasadev force-pushed the 20250606_stasadev_config_completion branch from 305e6e6 to 508c9c7 Compare June 12, 2025 12:21
Copy link
Member Author

@stasadev stasadev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving to draft until I understand how DDEV handles default config values.

I figured out why I couldn't set defaults for some values.

I reverted the change that broke the tests. I'll handle ddev help config normalization (according to https://ddev.readthedocs.io/en/stable/users/configuration/config/) in a new PR since this one is already too messy to read. GitHub isn't showing individual line changes, so I explained what was changed in a comment.

Comment on lines +303 to +317
_ = configGlobalCommand.RegisterFlagCompletionFunc("instrumentation-opt-in", configCompletionFunc([]string{"true", "false"}))
configGlobalCommand.Flags().Bool("router-bind-all-interfaces", false, "Bind host router ports on all interfaces, not only on the localhost network interface")
_ = configGlobalCommand.RegisterFlagCompletionFunc("router-bind-all-interfaces", configCompletionFunc([]string{"true", "false"}))
configGlobalCommand.Flags().Int("internet-detection-timeout-ms", nodeps.InternetDetectionTimeoutDefault, "Increase timeout when checking internet timeout, in milliseconds")
_ = configGlobalCommand.RegisterFlagCompletionFunc("internet-detection-timeout-ms", configCompletionFunc([]string{strconv.Itoa(nodeps.InternetDetectionTimeoutDefault)}))
configGlobalCommand.Flags().Bool("use-letsencrypt", false, "Enables experimental Let's Encrypt integration, 'ddev config global --use-letsencrypt' or 'ddev config global --use-letsencrypt=false'")
_ = configGlobalCommand.RegisterFlagCompletionFunc("use-letsencrypt", configCompletionFunc([]string{"true", "false"}))
configGlobalCommand.Flags().String("letsencrypt-email", "", "Email associated with Let's Encrypt, 'ddev config global [email protected]'")
configGlobalCommand.Flags().Bool("simple-formatting", false, "If true, use simple formatting and no color for tables")
configGlobalCommand.Flags().Bool("use-hardened-images", false, "If true, use more secure 'hardened' images for an actual internet deployment.")
configGlobalCommand.Flags().Bool("fail-on-hook-fail", false, "If true, 'ddev start' will fail when a hook fails.")
configGlobalCommand.Flags().Bool("mutagen-enabled", false, "If true, web container will use Mutagen caching/asynchronous updates.")
_ = configGlobalCommand.RegisterFlagCompletionFunc("simple-formatting", configCompletionFunc([]string{"true", "false"}))
configGlobalCommand.Flags().Bool("use-hardened-images", false, "If true, use more secure 'hardened' images for an actual internet deployment")
_ = configGlobalCommand.RegisterFlagCompletionFunc("use-hardened-images", configCompletionFunc([]string{"true", "false"}))
configGlobalCommand.Flags().Bool("fail-on-hook-fail", false, "If true, 'ddev start' will fail when a hook fails")
_ = configGlobalCommand.RegisterFlagCompletionFunc("fail-on-hook-fail", configCompletionFunc([]string{"true", "false"}))
configGlobalCommand.Flags().Bool("mutagen-enabled", false, "If true, web container will use Mutagen caching/asynchronous updates")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though it looks like a lot has been changed here, it only edits these:

  1. changing description:

    -router-bind-all-interfaces=true
    +Bind host router ports on all interfaces, not only on the localhost network interface
  2. using correct quotes:

    -Email associated with Let's Encrypt, `ddev config global [email protected]'
    +Email associated with Let's Encrypt, 'ddev config global [email protected]'
  3. removing periods at the end of descriptions:

    -If true, use more secure 'hardened' images for an actual internet deployment.
    +If true, use more secure 'hardened' images for an actual internet deployment
  4. adding autocompletion function for each flag:

    +_ = configGlobalCommand.RegisterFlagCompletionFunc(...)

Comment on lines +315 to +333
_ = ConfigCommand.RegisterFlagCompletionFunc("disable-settings-management", configCompletionFunc([]string{"true", "false"}))

ConfigCommand.Flags().String("composer-version", "", `Specify override for Composer version in web container. This may be "", "1", "2", "2.2", "stable", "preview", "snapshot" or a specific version.`)
ConfigCommand.Flags().String("composer-version", "", `Specify override for Composer version in web container. This may be "", "1", "2", "2.2", "stable", "preview", "snapshot" or a specific version`)
_ = ConfigCommand.RegisterFlagCompletionFunc("composer-version", configCompletionFunc([]string{"2", "2.2", "1", "stable", "preview", "snapshot"}))

ConfigCommand.Flags().Bool("auto", true, `Automatically run config without prompting.`)
ConfigCommand.Flags().Bool("auto", true, `Automatically run config without prompting`)
ConfigCommand.Flags().Bool("bind-all-interfaces", false, `Bind host ports on all interfaces, not only on the localhost network interface`)
ConfigCommand.Flags().String("database", "", fmt.Sprintf(`Specify the database type:version to use. Defaults to mariadb:%s`, nodeps.MariaDBDefaultVersion))
ConfigCommand.Flags().String("nodejs-version", "", fmt.Sprintf(`Specify the nodejs version to use if you don't want the default NodeJS %s`, nodeps.NodeJSDefault))
_ = ConfigCommand.RegisterFlagCompletionFunc("bind-all-interfaces", configCompletionFunc([]string{"true", "false"}))
ConfigCommand.Flags().String("database", "", fmt.Sprintf(`Specify the database type:version to use. Defaults to %s:%s`, ddevapp.DatabaseDefault.Type, ddevapp.DatabaseDefault.Version))
_ = ConfigCommand.RegisterFlagCompletionFunc("database", configCompletionFunc(nodeps.GetValidDatabaseVersions()))
ConfigCommand.Flags().String("nodejs-version", "", fmt.Sprintf(`Specify the Node.js version to use if you don't want the default Node.js %s`, nodeps.NodeJSDefault))
_ = ConfigCommand.RegisterFlagCompletionFunc("nodejs-version", configCompletionFunc([]string{nodeps.NodeJSDefault, "auto", "engine"}))
ConfigCommand.Flags().Int("default-container-timeout", 120, `default time in seconds that DDEV waits for all containers to become ready on start`)
ConfigCommand.Flags().Bool("disable-upload-dirs-warning", true, `Disable warnings about upload-dirs not being set when using performance-mode=mutagen.`)
ConfigCommand.Flags().StringVar(&ddevVersionConstraint, "ddev-version-constraint", "", `Specify a ddev version constraint to validate ddev against.`)
_ = ConfigCommand.RegisterFlagCompletionFunc("default-container-timeout", configCompletionFunc([]string{nodeps.DefaultDefaultContainerTimeout}))
ConfigCommand.Flags().Bool("disable-upload-dirs-warning", true, `Disable warnings about upload-dirs not being set when using --performance-mode=mutagen`)
_ = ConfigCommand.RegisterFlagCompletionFunc("disable-upload-dirs-warning", configCompletionFunc([]string{"true", "false"}))
ConfigCommand.Flags().StringVar(&ddevVersionConstraint, "ddev-version-constraint", "", `Specify a ddev version constraint to validate ddev against`)
ConfigCommand.Flags().Bool("corepack-enable", true, `Do 'corepack enable' to enable latest yarn/pnpm'`)
_ = ConfigCommand.RegisterFlagCompletionFunc("corepack-enable", configCompletionFunc([]string{"true", "false"}))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the same situation here, I just edited a few descriptions and GitHub shows the changes for whole lines.

@stasadev stasadev changed the title feat: add shell completion and normalize help for ddev config feat: add shell completion for ddev config and ddev config global Jun 12, 2025
@stasadev stasadev marked this pull request as ready for review June 12, 2025 12:47
Copy link
Collaborator

@tyler36 tyler36 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to get autocomplete working on local projects:

$ ddev config --webserver-type <tab>
-- completions --
apache-fpm  generic     nginx-fpm

$ddev config --webserver-type=<tab>
-- completions --
apache-fpm  generic     nginx-fpm

$ ddev config --database <tab>
-- completions --
mariadb:10.0   mariadb:10.3   mariadb:10.7   mariadb:5.5    mysql:8.0      postgres:12    postgres:16
mariadb:10.1   mariadb:10.4   mariadb:10.8   mysql:5.5      mysql:8.4      postgres:13    postgres:17
mariadb:10.11  mariadb:10.5   mariadb:11.4   mysql:5.6      postgres:10    postgres:14    postgres:9
mariadb:10.2   mariadb:10.6   mariadb:11.8   mysql:5.7      postgres:11    postgres:15

$ ddev config --database=<tab>
-- completions --
mariadb:10.0   mariadb:10.3   mariadb:10.7   mariadb:5.5    mysql:8.0      postgres:12    postgres:16
mariadb:10.1   mariadb:10.4   mariadb:10.8   mysql:5.5      mysql:8.4      postgres:13    postgres:17
mariadb:10.11  mariadb:10.5   mariadb:11.4   mysql:5.6      postgres:10    postgres:14    postgres:9
mariadb:10.2   mariadb:10.6   mariadb:11.8   mysql:5.7      postgres:11    postgres:15

But it did not work with global on my setup:

$ ddev config global --database=<tab>
# alert signal.
$ ddev config global --database <tab>
-- file --
README.md          artisan*           composer.json      config/

Probably something in my setup though. 🤷

DDEV : v1.24.6-21-g508c9c7fc
SHELL: zsh 5.9 (x86_64-pc-linux-gnu)
OS: WSL (Ubuntu 24.04) on Win11

@stasadev
Copy link
Member Author

But it did not work with global on my setup:

$ ddev config global --database=<tab>
# alert signal.
$ ddev config global --database <tab>
-- file --
README.md          artisan*           composer.json      config/

Probably something in my setup though. 🤷

@tyler36, there is no such flag in global.

Thanks for testing!

Copy link
Member

@rfay rfay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works perfectly for me, thank you! There's a lot of options there, and this really helps.

@rfay rfay merged commit 2552464 into ddev:main Jun 16, 2025
28 checks passed
@rfay rfay deleted the 20250606_stasadev_config_completion branch June 16, 2025 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments