Skip to content

Commit 27b08ae

Browse files
artparclaude
andcommitted
Add --quiet, --no-truncate flags; fix e2e config isolation
--quiet/-q: output only reference_id for scripting. Suppresses context line. Works on list (one ref per line), get, create, update. --no-truncate: disable 50-char truncation in table output. e2e tests now use isolated DAPTIN_CLI_CONFIG to avoid mutating user's ~/.daptin/config.yaml. Closes #14, #15, #16, #18 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent cd4d0f9 commit 27b08ae

4 files changed

Lines changed: 84 additions & 24 deletions

File tree

cmd/app.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type AppContext struct {
1515
Client *client.ExtendedClient
1616
Config *config.Config
1717
Renderer render.Renderer
18+
Quiet bool
1819
}
1920

2021
func NewApp(cfg *config.Config, version string) *cli.App {
@@ -41,18 +42,25 @@ func NewApp(cfg *config.Config, version string) *cli.App {
4142
}
4243

4344
appCtx.Client = client.New(endpoint, authToken, c.Bool("debug"))
45+
appCtx.Quiet = c.Bool("quiet")
4446

45-
authed := ""
46-
if authToken != "" {
47-
authed = ", authenticated"
47+
if !appCtx.Quiet {
48+
authed := ""
49+
if authToken != "" {
50+
authed = ", authenticated"
51+
}
52+
fmt.Fprintf(os.Stderr, "Using %s (%s%s)\n", contextName, endpoint, authed)
4853
}
49-
fmt.Fprintf(os.Stderr, "Using %s (%s%s)\n", contextName, endpoint, authed)
5054

5155
switch c.String("output") {
5256
case "json":
5357
appCtx.Renderer = render.NewJsonRenderer()
5458
default:
55-
appCtx.Renderer = render.NewTableRenderer()
59+
if c.Bool("no-truncate") {
60+
appCtx.Renderer = render.NewTableRendererNoTruncate()
61+
} else {
62+
appCtx.Renderer = render.NewTableRenderer()
63+
}
5664
}
5765

5866
return nil
@@ -84,6 +92,15 @@ func NewApp(cfg *config.Config, version string) *cli.App {
8492
Name: "debug",
8593
Usage: "Enable debug output",
8694
},
95+
&cli.BoolFlag{
96+
Name: "no-truncate",
97+
Usage: "Show full values in table output (no 50-char truncation)",
98+
},
99+
&cli.BoolFlag{
100+
Name: "quiet",
101+
Aliases: []string{"q"},
102+
Usage: "Output only reference_id (for scripting)",
103+
},
87104
},
88105
Commands: []*cli.Command{
89106
contextCommand(appCtx),

cmd/crud.go

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ func listCommand(appCtx *AppContext) *cli.Command {
7878
}
7979

8080
rows := client.MapArray(result, "attributes")
81+
if appCtx.Quiet {
82+
return printRefs(rows)
83+
}
8184
if cols := c.String("columns"); cols != "" {
8285
rows = render.FilterColumns(rows, strings.Split(cols, ","))
8386
}
@@ -115,6 +118,9 @@ func getCommand(appCtx *AppContext) *cli.Command {
115118
return nil
116119
}
117120

121+
if appCtx.Quiet {
122+
return printRef(row)
123+
}
118124
if cols := c.String("columns"); cols != "" {
119125
row = render.IncludeColumns(row, strings.Split(cols, ","))
120126
}
@@ -151,10 +157,14 @@ func createCommand(appCtx *AppContext) *cli.Command {
151157
return err
152158
}
153159

154-
if data, ok := result["attributes"].(map[string]interface{}); ok {
155-
return appCtx.Renderer.RenderObject(data)
160+
data, _ := result["attributes"].(map[string]interface{})
161+
if data == nil {
162+
data = result
163+
}
164+
if appCtx.Quiet {
165+
return printRef(data)
156166
}
157-
return appCtx.Renderer.RenderObject(result)
167+
return appCtx.Renderer.RenderObject(data)
158168
},
159169
}
160170
}
@@ -189,10 +199,14 @@ func updateCommand(appCtx *AppContext) *cli.Command {
189199
return err
190200
}
191201

192-
if data, ok := result["attributes"].(map[string]interface{}); ok {
193-
return appCtx.Renderer.RenderObject(data)
202+
data, _ := result["attributes"].(map[string]interface{})
203+
if data == nil {
204+
data = result
194205
}
195-
return appCtx.Renderer.RenderObject(result)
206+
if appCtx.Quiet {
207+
return printRef(data)
208+
}
209+
return appCtx.Renderer.RenderObject(data)
196210
},
197211
}
198212
}
@@ -244,6 +258,9 @@ func relatedCommand(appCtx *AppContext) *cli.Command {
244258
}
245259

246260
rows := client.MapArray(result, "attributes")
261+
if appCtx.Quiet {
262+
return printRefs(rows)
263+
}
247264
if cols := c.String("columns"); cols != "" {
248265
rows = render.FilterColumns(rows, strings.Split(cols, ","))
249266
}
@@ -252,6 +269,24 @@ func relatedCommand(appCtx *AppContext) *cli.Command {
252269
}
253270
}
254271

272+
// printRef outputs only the reference_id from a single row.
273+
func printRef(row map[string]interface{}) error {
274+
if ref, ok := row["reference_id"].(string); ok {
275+
fmt.Println(ref)
276+
}
277+
return nil
278+
}
279+
280+
// printRefs outputs one reference_id per line from a list of rows.
281+
func printRefs(rows []map[string]interface{}) error {
282+
for _, row := range rows {
283+
if ref, ok := row["reference_id"].(string); ok {
284+
fmt.Println(ref)
285+
}
286+
}
287+
return nil
288+
}
289+
255290
// parseAttributes parses [key=val ...] args or a single JSON string into a map.
256291
func parseAttributes(args []string) (map[string]interface{}, error) {
257292
if len(args) == 0 {

render/render.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,28 @@ func ExcludeColumns(row map[string]interface{}, columns []string) map[string]int
4848
}
4949

5050
// TableRenderer outputs data as an aligned text table.
51-
type TableRenderer struct{}
51+
type TableRenderer struct {
52+
MaxWidth int // 0 means no truncation
53+
}
5254

5355
func NewTableRenderer() *TableRenderer {
54-
return &TableRenderer{}
56+
return &TableRenderer{MaxWidth: 50}
57+
}
58+
59+
func NewTableRendererNoTruncate() *TableRenderer {
60+
return &TableRenderer{MaxWidth: 0}
61+
}
62+
63+
func (t *TableRenderer) truncate(s string) string {
64+
if t.MaxWidth > 0 && len(s) > t.MaxWidth {
65+
return s[:t.MaxWidth] + "..."
66+
}
67+
return s
5568
}
5669

5770
func (t *TableRenderer) RenderObject(data map[string]interface{}) error {
5871
for header, val := range data {
59-
valString := fmt.Sprintf("%v", val)
60-
if len(valString) > 50 {
61-
valString = valString[:50] + "..."
62-
}
63-
fmt.Fprintf(os.Stdout, "[%s]: %s\n", header, valString)
72+
fmt.Fprintf(os.Stdout, "[%s]: %s\n", header, t.truncate(fmt.Sprintf("%v", val)))
6473
}
6574
return nil
6675
}
@@ -86,12 +95,7 @@ func (t *TableRenderer) RenderArray(data []map[string]interface{}) error {
8695

8796
for _, row := range data {
8897
for _, header := range headers {
89-
val := row[header]
90-
valString := fmt.Sprintf("%v", val)
91-
if len(valString) > 50 {
92-
valString = valString[:50] + "..."
93-
}
94-
fmt.Fprintf(tw, "%s\t", valString)
98+
fmt.Fprintf(tw, "%s\t", t.truncate(fmt.Sprintf("%v", row[header])))
9599
}
96100
fmt.Fprintln(tw)
97101
}

scripts/e2e.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ CLI="${DAPTIN_CLI:-./daptin-cli}"
88
PASS=0
99
FAIL=0
1010

11+
# Use isolated config so e2e tests don't mutate user's ~/.daptin/config.yaml
12+
export DAPTIN_CLI_CONFIG="/tmp/daptin-e2e-config-$$.yaml"
13+
trap "rm -f $DAPTIN_CLI_CONFIG" EXIT
14+
1115
# Build if binary doesn't exist
1216
if [ ! -f "$CLI" ]; then
1317
echo "Building $CLI..."

0 commit comments

Comments
 (0)