Merge pull request #8795 from dokku/8792-add-format-json-support-to-apps-list

Add --format json support to apps:list
This commit is contained in:
Jose Diaz-Gonzalez
2026-07-06 13:32:38 -04:00
committed by GitHub
5 changed files with 67 additions and 6 deletions

View File

@@ -8,7 +8,7 @@ apps:clone <old-app> <new-app> # Clones an app
apps:create <app> # Create a new app
apps:destroy <app> # Permanently destroy an app
apps:exists <app> # Checks if an app exists
apps:list # List your apps
apps:list [--format stdout|json] # List your apps
apps:lock <app> # Locks an app for deployment
apps:locked <app> # Checks if an app is locked for deployment
apps:rename <old-app> <new-app> # Rename an app
@@ -47,6 +47,18 @@ node-js-app
python-app
```
You can also retrieve the list of apps as a JSON array by using the `--format json` flag, which is useful for programmatic consumption:
```shell
dokku apps:list --format json
```
```json
["node-js-app","python-app"]
```
When no apps exist, the JSON output is an empty array (`[]`).
### Checking if an application exists
For CI/CD pipelines, it may be useful to see if an application exists before creating a "review" application for a specific branch. You can do so via the `apps:exists` command:

View File

@@ -23,7 +23,7 @@ Additional commands:`
apps:create <app>, Create a new app
apps:destroy <app>, Permanently destroy an app
apps:exists <app>, Checks if an app exists
apps:list, List your apps
apps:list [--format stdout|json], List your apps
apps:lock <app>, Locks an app for deployment
apps:locked <app>, Checks if an app is locked for deployment
apps:rename <old-app> <new-app>, Rename an app
@@ -43,7 +43,7 @@ func main() {
args.Usage = usage
args.Parse(os.Args[2:])
if err := apps.CommandList(); err != nil {
if err := apps.CommandList("stdout"); err != nil {
common.LogFailWithError(err)
}
case "apps:help":

View File

@@ -44,8 +44,9 @@ func main() {
err = apps.CommandExists(appName)
case "list":
args := flag.NewFlagSet("apps:list", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
args.Parse(os.Args[2:])
err = apps.CommandList()
err = apps.CommandList(*format)
case "lock":
args := flag.NewFlagSet("apps:lock", flag.ExitOnError)
args.Parse(os.Args[2:])

View File

@@ -1,6 +1,7 @@
package apps
import (
"encoding/json"
"errors"
"fmt"
"os"
@@ -98,9 +99,26 @@ func CommandExists(appName string) error {
}
// CommandList lists all apps
func CommandList() error {
common.LogInfo2Quiet("My Apps")
func CommandList(format string) error {
apps, err := common.DokkuApps()
if format == "json" {
if err != nil && !errors.Is(err, common.NoAppsExist) {
return err
}
appList := []string{}
appList = append(appList, apps...)
out, err := json.Marshal(appList)
if err != nil {
return err
}
common.Log(string(out))
return nil
}
common.LogInfo2Quiet("My Apps")
if err != nil {
common.LogWarn(err.Error())
return nil

View File

@@ -50,6 +50,36 @@ teardown() {
assert_success
}
@test "(apps) apps:list --format json" {
run /bin/bash -c "dokku apps:list --format json"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "[]"
run /bin/bash -c "dokku apps:create $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku apps:list --format json | jq '. | length'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "1"
run /bin/bash -c "dokku apps:list --format json | jq -r '.[0]'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "$TEST_APP"
run /bin/bash -c "dokku --force apps:destroy $TEST_APP"
echo "output: $output"
echo "status: $status"
assert_success
}
@test "(apps) apps:create" {
run /bin/bash -c "dokku apps:create $TEST_APP"
echo "output: $output"