Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 0.40.1 - Unreleased

- Apps Script: keep file names within one TSV field in `appscript content`, escaping line breaks instead of splitting output rows. (#1091) — thanks @haosdent.
- Search Console: add `searchconsole inspect` for per-URL index status via the URL Inspection API (coverage state, indexing/page-fetch/robots.txt state, canonical, sitemaps, last crawl time), using the existing `webmasters` OAuth scope. (#1094) — thanks @laihenyi.
- Search Console: preserve permission-denied exit codes when adding API setup or scope guidance. (#1094)
- Dependencies and CI: refresh Google protocol modules and tracking-worker tooling within release-age limits; test the Go 1.26 minimum, check worker types and generated skills, and avoid duplicate pull-request test runs. (#1131)
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/appscript.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (c *AppScriptContentCmd) Run(ctx context.Context, flags *RootFlags) error {
if file == nil {
continue
}
u.Out().Linef("file\t%s\t%s", file.Name, file.Type)
u.Out().Linef("file\t%s\t%s", oneLine(file.Name), oneLine(file.Type))
}
return nil
}
Expand Down
47 changes: 47 additions & 0 deletions internal/cmd/appscript_content_output_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package cmd

import (
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
)

func TestAppScriptContentFileNamesStayInOneField(t *testing.T) {
const name = "Name\tWith\r\nBreaks"
for _, mode := range []string{"text", "plain", "json"} {
t.Run(mode, func(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]any{
"scriptId": "script123", "files": []map[string]any{{"name": name, "type": "SERVER_JS"}},
})
}))
defer srv.Close()
args := []string{"--account", "a@b.com", "appscript", "content", "script123"}
if mode != "text" {
args = append([]string{"--" + mode}, args...)
}
result := executeWithAppScriptTestService(t, args, newAppScriptTestService(t, srv))
if result.err != nil {
t.Fatal(result.err)
}
if mode == "json" {
var output struct {
Content struct {
Files []struct{ Name string } `json:"files"`
} `json:"content"`
}
if err := json.Unmarshal([]byte(result.stdout), &output); err != nil {
t.Fatal(err)
}
if len(output.Content.Files) != 1 || output.Content.Files[0].Name != name {
t.Fatalf("JSON changed the file name: %s", result.stdout)
}
} else if !strings.Contains(result.stdout, "file\tName With\\nBreaks\tSERVER_JS\n") {
t.Fatalf("unsafe file row: %q", result.stdout)
}
})
}
}
6 changes: 1 addition & 5 deletions internal/cmd/comment_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -525,11 +525,7 @@ func filterOpenComments(comments []*drive.Comment) []*drive.Comment {
}

func oneLineTSV(s string) string {
s = strings.ReplaceAll(s, "\r\n", "\n")
s = strings.ReplaceAll(s, "\r", "\n")
s = strings.ReplaceAll(s, "\t", " ")
s = strings.ReplaceAll(s, "\n", "\\n")
return strings.TrimSpace(s)
return strings.TrimSpace(oneLine(s))
}

func truncateString(s string, maxLen int) string {
Expand Down
10 changes: 10 additions & 0 deletions internal/cmd/output_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"context"
"io"
"strings"
"text/tabwriter"

"github.com/openclaw/gogcli/internal/outfmt"
Expand Down Expand Up @@ -62,3 +63,12 @@ func printNextPageHintWithAll(u *ui.UI, nextPageToken string, allFlag string) {
}
u.Err().Linef("# More results: use %s to fetch every page, or --page %s for the next page", allFlag, nextPageToken)
}

func oneLine(s string) string {
s = strings.ReplaceAll(s, "\r\n", "\n")
s = strings.ReplaceAll(s, "\r", "\n")
// Keep output parseable in tables/TSV.
s = strings.ReplaceAll(s, "\t", " ")
s = strings.ReplaceAll(s, "\n", "\\n")
return s
}
9 changes: 0 additions & 9 deletions internal/cmd/sheets_notes.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,3 @@ func (c *SheetsNotesCmd) Run(ctx context.Context, flags *RootFlags) error {

return outfmt.WriteTable(ctx, stdoutWriter(ctx), notes, sheetsNoteColumns())
}

func oneLine(s string) string {
s = strings.ReplaceAll(s, "\r\n", "\n")
s = strings.ReplaceAll(s, "\r", "\n")
// Keep output parseable in tables/TSV.
s = strings.ReplaceAll(s, "\t", " ")
s = strings.ReplaceAll(s, "\n", "\\n")
return s
}