* feat(cli): improve agent ergonomics * fix(cli): address code review findings - Fix nil pointer dereference in confirmDestructive when flags is nil - Deduplicate dry-run logic by delegating to dryRunExit - Remove deprecated net.Error.Temporary() call (dead since Go 1.18) - Add unit tests for resolveTasklistID and resolveCalendarID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: resolve PR #201 conflicts and follow-ups (#201) (thanks @salmonumbrella) * fix: resolve rebase fallout for PR #201 landing (#201) (thanks @salmonumbrella) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Peter Steinberger <steipete@gmail.com>
58 lines
1.1 KiB
Go
58 lines
1.1 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/steipete/gogcli/internal/config"
|
|
)
|
|
|
|
// resolveInlineOrFileBytes supports agent-friendly inputs for flags that otherwise
|
|
// require shell-escaped JSON strings.
|
|
//
|
|
// Supported forms:
|
|
// - literal: '{"a":1}'
|
|
// - stdin: '-'
|
|
// - file: '@path/to/file.json'
|
|
// - stdin: '@-'
|
|
func resolveInlineOrFileBytes(spec string) ([]byte, error) {
|
|
spec = strings.TrimSpace(spec)
|
|
if spec == "" {
|
|
return nil, nil
|
|
}
|
|
|
|
readStdin := func() ([]byte, error) {
|
|
b, err := io.ReadAll(os.Stdin)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return b, nil
|
|
}
|
|
|
|
switch {
|
|
case spec == "-":
|
|
return readStdin()
|
|
case strings.HasPrefix(spec, "@"):
|
|
path := strings.TrimSpace(strings.TrimPrefix(spec, "@"))
|
|
if path == "" {
|
|
return nil, fmt.Errorf("empty @file reference")
|
|
}
|
|
if path == "-" {
|
|
return readStdin()
|
|
}
|
|
path, err := config.ExpandPath(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
b, err := os.ReadFile(path) //nolint:gosec // user-provided path
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return b, nil
|
|
default:
|
|
return []byte(spec), nil
|
|
}
|
|
}
|