Function bodies 106 total
cmd.init function · go · L58-L63 (6 LOC)cmd/accounts.go
func init() {
accountsCmd.AddCommand(accountsListCmd)
accountsCmd.AddCommand(accountsSwitchCmd)
accountsCmd.AddCommand(accountsRemoveCmd)
rootCmd.AddCommand(accountsCmd)
}cmd.runAccountsList function · go · L65-L106 (42 LOC)cmd/accounts.go
func runAccountsList(cmd *cobra.Command, args []string) error {
store, err := auth.LoadAccountStore()
if err != nil {
return fmt.Errorf("failed to load account store: %w", err)
}
accounts := store.List()
if len(accounts) == 0 {
if GetOutputFormat() == "json" {
return outputJSON([]struct{}{})
}
fmt.Println("No authenticated accounts. Run 'gsuite login' to add one.")
return nil
}
if GetOutputFormat() == "json" {
type accountItem struct {
Email string `json:"email"`
AddedAt string `json:"added_at"`
Active bool `json:"active"`
}
var results []accountItem
for _, entry := range accounts {
results = append(results, accountItem{
Email: entry.Email,
AddedAt: entry.AddedAt.Format("2006-01-02"),
Active: strings.EqualFold(entry.Email, store.Active),
})
}
return outputJSON(results)
}
for _, entry := range accounts {
marker := " "
if strings.EqualFold(entry.Email, store.Active) {
marker = "*"
}
fmt.Printf("%s %s (addcmd.runAccountsSwitch function · go · L108-L126 (19 LOC)cmd/accounts.go
func runAccountsSwitch(cmd *cobra.Command, args []string) error {
email := args[0]
store, err := auth.LoadAccountStore()
if err != nil {
return fmt.Errorf("failed to load account store: %w", err)
}
if err := store.SetActive(email); err != nil {
return err
}
if err := store.Save(); err != nil {
return fmt.Errorf("failed to save account store: %w", err)
}
fmt.Printf("Switched to %s\n", email)
return nil
}cmd.runAccountsRemove function · go · L128-L150 (23 LOC)cmd/accounts.go
func runAccountsRemove(cmd *cobra.Command, args []string) error {
email := args[0]
store, err := auth.LoadAccountStore()
if err != nil {
return fmt.Errorf("failed to load account store: %w", err)
}
if err := store.RemoveAccount(email); err != nil {
return err
}
if err := store.Save(); err != nil {
return fmt.Errorf("failed to save account store: %w", err)
}
if err := auth.DeleteTokenFor(email); err != nil {
return fmt.Errorf("failed to remove token: %w", err)
}
fmt.Printf("Removed account %s\n", email)
return nil
}cmd.init function · go · L168-L249 (82 LOC)cmd/calendar.go
func init() {
rootCmd.AddCommand(calendarCmd)
calendarCmd.AddCommand(calendarListCmd)
calendarCmd.AddCommand(calendarGetCmd)
calendarCmd.AddCommand(calendarTodayCmd)
calendarCmd.AddCommand(calendarWeekCmd)
calendarCmd.AddCommand(calendarCalendarsCmd)
calendarCmd.AddCommand(calendarCreateCmd)
calendarCmd.AddCommand(calendarUpdateCmd)
calendarCmd.AddCommand(calendarDeleteCmd)
calendarCmd.AddCommand(calendarRespondCmd)
// List flags
calendarListCmd.Flags().StringVar(&calendarID, "calendar-id", "primary", "Calendar ID")
calendarListCmd.Flags().Int64VarP(&calendarMaxResults, "max-results", "n", 25, "Maximum number of events")
calendarListCmd.Flags().StringVar(&calendarAfter, "after", "", "Show events after this time")
calendarListCmd.Flags().StringVar(&calendarBefore, "before", "", "Show events before this time")
calendarListCmd.Flags().StringVarP(&calendarQuery, "query", "q", "", "Search query")
calendarListCmd.Flags().BoolVar(&calendarSingleEvents, "single-events", true,cmd.resolveTimezone function · go · L251-L260 (10 LOC)cmd/calendar.go
func resolveTimezone() (*time.Location, error) {
if calendarTimezone != "" {
loc, err := time.LoadLocation(calendarTimezone)
if err != nil {
return nil, fmt.Errorf("invalid timezone %q: %w", calendarTimezone, err)
}
return loc, nil
}
return time.Now().Location(), nil
}cmd.listCalendarEvents function · go · L262-L346 (85 LOC)cmd/calendar.go
func listCalendarEvents(cmd *cobra.Command, calID string, timeMin, timeMax time.Time, maxResults int64, query string, singleEvents bool, orderBy string, tz *time.Location, showDeleted bool) error {
ctx := context.Background()
service, err := auth.NewCalendarService(ctx, GetAccountEmail())
if err != nil {
return auth.HandleCalendarError(err, "authentication failed")
}
call := service.Events.List(calID).
TimeMin(timeMin.Format(time.RFC3339)).
TimeMax(timeMax.Format(time.RFC3339)).
SingleEvents(singleEvents).
ShowDeleted(showDeleted).
Fields("items(id,summary,start,end,location,status,recurringEventId),nextPageToken")
if orderBy != "" {
call = call.OrderBy(orderBy)
}
if query != "" {
call = call.Q(query)
}
if calendarTimezone != "" {
call = call.TimeZone(calendarTimezone)
}
call.MaxResults(min(maxResults, 250))
var allEvents []*calendar.Event
err = call.Pages(ctx, func(page *calendar.Events) error {
allEvents = append(allEvents, page.Items...)
if iRepobility analyzer · published findings · https://repobility.com
cmd.printEventTable function · go · L348-L362 (15 LOC)cmd/calendar.go
func printEventTable(events []*calendar.Event, tz *time.Location) {
fmt.Printf("%-12s %-20s %s\n", "DATE", "TIME", "SUMMARY")
fmt.Printf("%-12s %-20s %s\n", "----", "----", "-------")
for _, ev := range events {
date, timeRange := formatEventTableRow(ev, tz)
summary := ev.Summary
if ev.RecurringEventId != "" {
summary += " (recurring)"
}
fmt.Printf("%-12s %-20s %s\n", date, timeRange, summary)
}
fmt.Printf("\n[%d event(s)]\n", len(events))
}cmd.formatEventTableRow function · go · L364-L401 (38 LOC)cmd/calendar.go
func formatEventTableRow(ev *calendar.Event, tz *time.Location) (string, string) {
if ev.Start == nil {
return "", ""
}
if ev.Start.Date != "" {
t, err := time.Parse("2006-01-02", ev.Start.Date)
if err != nil {
return ev.Start.Date, "all day"
}
return t.Format("2006-01-02"), "all day"
}
if ev.Start.DateTime != "" {
startT, err := time.Parse(time.RFC3339, ev.Start.DateTime)
if err != nil {
return "", ev.Start.DateTime
}
startT = startT.In(tz)
date := startT.Format("2006-01-02")
startStr := startT.Format("03:04 PM")
endStr := ""
if ev.End != nil && ev.End.DateTime != "" {
endT, err := time.Parse(time.RFC3339, ev.End.DateTime)
if err == nil {
endStr = endT.In(tz).Format("03:04 PM")
}
}
if endStr != "" {
return date, startStr + " - " + endStr
}
return date, startStr
}
return "", ""
}cmd.runCalendarList function · go · L403-L430 (28 LOC)cmd/calendar.go
func runCalendarList(cmd *cobra.Command, args []string) error {
tz, err := resolveTimezone()
if err != nil {
return err
}
now := time.Now().In(tz)
timeMin := now
if calendarAfter != "" {
t, err := parseDateTime(calendarAfter, tz, now)
if err != nil {
return fmt.Errorf("invalid --after value: %w", err)
}
timeMin = t
}
timeMax := now.AddDate(0, 0, 30)
if calendarBefore != "" {
t, err := parseDateTime(calendarBefore, tz, now)
if err != nil {
return fmt.Errorf("invalid --before value: %w", err)
}
timeMax = t
}
return listCalendarEvents(cmd, calendarID, timeMin, timeMax, calendarMaxResults, calendarQuery, calendarSingleEvents, calendarOrderBy, tz, calendarShowDeleted)
}cmd.runCalendarGet function · go · L432-L565 (134 LOC)cmd/calendar.go
func runCalendarGet(cmd *cobra.Command, args []string) error {
eventID := args[0]
tz, err := resolveTimezone()
if err != nil {
return err
}
ctx := context.Background()
service, err := auth.NewCalendarService(ctx, GetAccountEmail())
if err != nil {
return auth.HandleCalendarError(err, "authentication failed")
}
ev, err := service.Events.Get(calendarID, eventID).Do()
if err != nil {
return auth.HandleCalendarError(err, "failed to get event")
}
if GetOutputFormat() == "json" {
type attendeeItem struct {
Email string `json:"email"`
DisplayName string `json:"display_name"`
ResponseStatus string `json:"response_status"`
Organizer bool `json:"organizer"`
Self bool `json:"self"`
}
type eventDetail struct {
ID string `json:"id"`
Summary string `json:"summary"`
Start string `json:"start"`
End string `json:"end"`
Status scmd.runCalendarToday function · go · L567-L578 (12 LOC)cmd/calendar.go
func runCalendarToday(cmd *cobra.Command, args []string) error {
tz, err := resolveTimezone()
if err != nil {
return err
}
now := time.Now().In(tz)
dayStart := startOfDay(now, tz)
dayEnd := dayStart.AddDate(0, 0, 1)
return listCalendarEvents(cmd, calendarID, dayStart, dayEnd, calendarMaxResults, "", true, "startTime", tz, false)
}cmd.runCalendarWeek function · go · L580-L593 (14 LOC)cmd/calendar.go
func runCalendarWeek(cmd *cobra.Command, args []string) error {
tz, err := resolveTimezone()
if err != nil {
return err
}
now := time.Now().In(tz)
// Find Monday of the current week
daysFromMonday := (int(now.Weekday()) - int(time.Monday) + 7) % 7
weekStart := startOfDay(now.AddDate(0, 0, -daysFromMonday), tz)
weekEnd := weekStart.AddDate(0, 0, 7)
return listCalendarEvents(cmd, calendarID, weekStart, weekEnd, calendarMaxResults, "", true, "startTime", tz, false)
}cmd.runCalendarCalendars function · go · L595-L654 (60 LOC)cmd/calendar.go
func runCalendarCalendars(cmd *cobra.Command, args []string) error {
ctx := context.Background()
service, err := auth.NewCalendarService(ctx, GetAccountEmail())
if err != nil {
return auth.HandleCalendarError(err, "authentication failed")
}
resp, err := service.CalendarList.List().
MaxResults(calendarMaxResults).
Do()
if err != nil {
return auth.HandleCalendarError(err, "failed to list calendars")
}
if GetOutputFormat() == "json" {
type calendarItem struct {
ID string `json:"id"`
Summary string `json:"summary"`
AccessRole string `json:"access_role"`
Primary bool `json:"primary"`
Timezone string `json:"timezone"`
}
if len(resp.Items) == 0 {
return outputJSON([]struct{}{})
}
items := make([]calendarItem, len(resp.Items))
for i, cal := range resp.Items {
items[i] = calendarItem{
ID: cal.Id,
Summary: cal.Summary,
AccessRole: cal.AccessRole,
Primary: cal.Primary,
Timezone: cal.TimeZoncmd.parseDateTime function · go · L24-L55 (32 LOC)cmd/calendar_time.go
func parseDateTime(input string, loc *time.Location, now time.Time) (time.Time, error) {
input = strings.TrimSpace(input)
if input == "" {
return time.Time{}, fmt.Errorf("empty datetime input; accepted formats: RFC3339, 2006-01-02, 2006-01-02 15:04, 2006-01-02T15:04:05, 15:04, today, tomorrow, monday-sunday, +Nd")
}
if t, ok := parseRelative(input, loc, now); ok {
return t, nil
}
if t, err := time.Parse(time.RFC3339, input); err == nil {
return t, nil
}
formats := []string{
"2006-01-02",
"2006-01-02 15:04",
"2006-01-02T15:04:05",
}
for _, f := range formats {
if t, err := time.ParseInLocation(f, input, loc); err == nil {
return t, nil
}
}
// Time-only: anchor to today
if t, err := time.ParseInLocation("15:04", input, loc); err == nil {
return time.Date(now.Year(), now.Month(), now.Day(), t.Hour(), t.Minute(), 0, 0, loc), nil
}
return time.Time{}, fmt.Errorf("cannot parse %q; accepted formats: RFC3339, 2006-01-02, 2006-01-02 15:04, 2006-01-02T15:Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
cmd.parseRelative function · go · L57-L80 (24 LOC)cmd/calendar_time.go
func parseRelative(input string, loc *time.Location, now time.Time) (time.Time, bool) {
lower := strings.ToLower(strings.TrimSpace(input))
switch lower {
case "today":
return startOfDay(now, loc), true
case "tomorrow":
return startOfDay(now.AddDate(0, 0, 1), loc), true
}
if wd, ok := dayNames[lower]; ok {
return nextWeekday(now.In(loc), wd), true
}
if m := relDaysRegexp.FindStringSubmatch(lower); m != nil {
n := 0
for _, c := range m[1] {
n = n*10 + int(c-'0')
}
return startOfDay(now.AddDate(0, 0, n), loc), true
}
return time.Time{}, false
}cmd.parseDuration function · go · L82-L91 (10 LOC)cmd/calendar_time.go
func parseDuration(input string) (time.Duration, error) {
d, err := time.ParseDuration(input)
if err != nil {
return 0, fmt.Errorf("invalid duration %q: %w", input, err)
}
if d <= 0 {
return 0, fmt.Errorf("duration must be positive, got %s", d)
}
return d, nil
}cmd.buildEventDateTime function · go · L93-L104 (12 LOC)cmd/calendar_time.go
func buildEventDateTime(t time.Time, allDay bool, tz string) *calendar.EventDateTime {
edt := &calendar.EventDateTime{}
if allDay {
edt.Date = t.Format("2006-01-02")
} else {
edt.DateTime = t.Format(time.RFC3339)
}
if tz != "" {
edt.TimeZone = tz
}
return edt
}cmd.formatEventTime function · go · L106-L125 (20 LOC)cmd/calendar_time.go
func formatEventTime(edt *calendar.EventDateTime, displayTz *time.Location) string {
if edt == nil {
return ""
}
if edt.Date != "" {
t, err := time.Parse("2006-01-02", edt.Date)
if err != nil {
return edt.Date
}
return t.Format("Mon Jan 02, 2006 (all day)")
}
if edt.DateTime != "" {
t, err := time.Parse(time.RFC3339, edt.DateTime)
if err != nil {
return edt.DateTime
}
return t.In(displayTz).Format("Mon Jan 02, 2006 03:04 PM MST")
}
return ""
}cmd.nextWeekday function · go · L131-L137 (7 LOC)cmd/calendar_time.go
func nextWeekday(from time.Time, target time.Weekday) time.Time {
days := int(target) - int(from.Weekday())
if days <= 0 {
days += 7
}
return startOfDay(from.AddDate(0, 0, days), from.Location())
}cmd.init function · go · L16-L21 (6 LOC)cmd/calendar_write.go
func init() {
calendarCreateCmd.RunE = runCalendarCreate
calendarUpdateCmd.RunE = runCalendarUpdate
calendarDeleteCmd.RunE = runCalendarDelete
calendarRespondCmd.RunE = runCalendarRespond
}cmd.runCalendarCreate function · go · L23-L119 (97 LOC)cmd/calendar_write.go
func runCalendarCreate(cmd *cobra.Command, args []string) error {
if err := validateCalendarCreateFlags(calendarStart, calendarEnd, calendarDuration, calendarAllDay); err != nil {
return err
}
tz, err := resolveTimezone()
if err != nil {
return err
}
now := time.Now().In(tz)
startTime, err := parseDateTime(calendarStart, tz, now)
if err != nil {
return fmt.Errorf("invalid --start value: %w", err)
}
var endTime time.Time
switch {
case calendarEnd != "":
endTime, err = parseDateTime(calendarEnd, tz, now)
if err != nil {
return fmt.Errorf("invalid --end value: %w", err)
}
case calendarDuration != "":
d, err := parseDuration(calendarDuration)
if err != nil {
return err
}
endTime = startTime.Add(d)
case calendarAllDay:
endTime = startTime.AddDate(0, 0, 1)
default:
endTime = startTime.Add(time.Hour)
}
event := &calendar.Event{
Summary: calendarSummary,
Description: calendarDescription,
Location: calendarLocation,
Start: cmd.runCalendarUpdate function · go · L121-L248 (128 LOC)cmd/calendar_write.go
func runCalendarUpdate(cmd *cobra.Command, args []string) error {
eventID := args[0]
tz, err := resolveTimezone()
if err != nil {
return err
}
ctx := context.Background()
service, err := auth.NewCalendarService(ctx, GetAccountEmail())
if err != nil {
return auth.HandleCalendarError(err, "authentication failed")
}
event, err := service.Events.Get(calendarID, eventID).Do()
if err != nil {
return auth.HandleCalendarError(err, "failed to get event")
}
// For recurring events with --recurring-scope all, operate on the parent
if calendarRecurringScope == "all" && event.RecurringEventId != "" {
eventID = event.RecurringEventId
event, err = service.Events.Get(calendarID, eventID).Do()
if err != nil {
return auth.HandleCalendarError(err, "failed to get recurring event")
}
}
now := time.Now().In(tz)
if cmd.Flags().Changed("summary") {
event.Summary = calendarSummary
}
if cmd.Flags().Changed("start") {
startTime, err := parseDateTime(calendarStart, tzOpen data scored by Repobility · https://repobility.com
cmd.runCalendarDelete function · go · L250-L292 (43 LOC)cmd/calendar_write.go
func runCalendarDelete(cmd *cobra.Command, args []string) error {
eventID := args[0]
if calendarRecurringScope == "all" && !calendarYes {
return fmt.Errorf("this will delete ALL instances of this recurring event. Use --yes to confirm, or --recurring-scope this to delete only this instance")
}
ctx := context.Background()
service, err := auth.NewCalendarService(ctx, GetAccountEmail())
if err != nil {
return auth.HandleCalendarError(err, "authentication failed")
}
// For recurring events with --recurring-scope all, operate on the parent
if calendarRecurringScope == "all" {
event, err := service.Events.Get(calendarID, eventID).Do()
if err != nil {
return auth.HandleCalendarError(err, "failed to get event")
}
if event.RecurringEventId != "" {
eventID = event.RecurringEventId
}
}
err = service.Events.Delete(calendarID, eventID).SendUpdates(calendarSendUpdates).Do()
if err != nil {
return auth.HandleCalendarError(err, "failed to delete event")
}
if Getcmd.runCalendarRespond function · go · L294-L357 (64 LOC)cmd/calendar_write.go
func runCalendarRespond(cmd *cobra.Command, args []string) error {
eventID := args[0]
validStatuses := map[string]bool{
"accepted": true,
"declined": true,
"tentative": true,
}
if !validStatuses[calendarStatus] {
return fmt.Errorf("invalid --status %q: must be one of accepted, declined, tentative", calendarStatus)
}
ctx := context.Background()
service, err := auth.NewCalendarService(ctx, GetAccountEmail())
if err != nil {
return auth.HandleCalendarError(err, "authentication failed")
}
event, err := service.Events.Get(calendarID, eventID).Do()
if err != nil {
return auth.HandleCalendarError(err, "failed to get event")
}
var selfAttendee *calendar.EventAttendee
for _, a := range event.Attendees {
if a.Self {
selfAttendee = a
break
}
}
if selfAttendee == nil {
return fmt.Errorf("you are not listed as an attendee of this event")
}
selfAttendee.ResponseStatus = calendarStatus
if calendarComment != "" {
selfAttendee.Comment = calendarCommencmd.validateCalendarCreateFlags function · go · L359-L367 (9 LOC)cmd/calendar_write.go
func validateCalendarCreateFlags(start, end, duration string, allDay bool) error {
if end != "" && duration != "" {
return fmt.Errorf("--end and --duration are mutually exclusive")
}
if allDay && duration != "" {
return fmt.Errorf("--all-day and --duration cannot be combined")
}
return nil
}cmd.validateAttendeeEmails function · go · L369-L391 (23 LOC)cmd/calendar_write.go
func validateAttendeeEmails(csv string) ([]string, error) {
parts := strings.Split(csv, ",")
emails := make([]string, 0, len(parts))
for _, part := range parts {
email := strings.TrimSpace(part)
if email == "" {
continue
}
addr, err := mail.ParseAddress(email)
if err != nil {
// Try wrapping with angle brackets for bare emails
addr, err = mail.ParseAddress("<" + email + ">")
if err != nil {
return nil, fmt.Errorf("invalid email address %q: %w", email, err)
}
}
emails = append(emails, addr.Address)
}
return emails, nil
}cmd.init function · go · L143-L171 (29 LOC)cmd/drafts.go
func init() {
rootCmd.AddCommand(draftsCmd)
draftsCmd.AddCommand(draftsListCmd)
draftsCmd.AddCommand(draftsGetCmd)
draftsCmd.AddCommand(draftsCreateCmd)
draftsCmd.AddCommand(draftsUpdateCmd)
draftsCmd.AddCommand(draftsSendCmd)
draftsCmd.AddCommand(draftsDeleteCmd)
// draftsListCmd flags
draftsListCmd.Flags().Int64VarP(&draftsMaxResults, "max-results", "n", 10, "Maximum number of drafts to return (max 500)")
// draftsCreateCmd flags
draftsCreateCmd.Flags().StringVarP(&draftTo, "to", "t", "", "Recipient email address (required)")
draftsCreateCmd.Flags().StringVarP(&draftSubject, "subject", "s", "", "Email subject (required)")
draftsCreateCmd.Flags().StringVarP(&draftBody, "body", "b", "", "Plain text body content (required)")
draftsCreateCmd.Flags().StringVar(&draftCc, "cc", "", "CC recipients (comma-separated)")
draftsCreateCmd.Flags().StringVar(&draftBcc, "bcc", "", "BCC recipients (comma-separated)")
draftsCreateCmd.MarkFlagRequired("to")
draftsCreateCmd.MarkFlagReqcmd.runDraftsList function · go · L173-L291 (119 LOC)cmd/drafts.go
func runDraftsList(cmd *cobra.Command, args []string) error {
ctx := context.Background()
service, err := auth.NewGmailService(ctx, GetAccountEmail())
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
// Build the list request
listCall := service.Users.Drafts.List("me")
// Apply max results (cap at 500)
if draftsMaxResults > 500 {
draftsMaxResults = 500
}
listCall.MaxResults(draftsMaxResults)
// Execute the request
resp, err := listCall.Do()
if err != nil {
return fmt.Errorf("Gmail API error: %w", err)
}
// Check if no drafts found
if len(resp.Drafts) == 0 {
if GetOutputFormat() == "json" {
return outputJSON([]struct{}{})
}
fmt.Println("No drafts found.")
return nil
}
// JSON output mode
if GetOutputFormat() == "json" {
type draftListItem struct {
DraftID string `json:"draft_id"`
MessageID string `json:"message_id"`
Subject string `json:"subject"`
Snippet string `json:"snippet"`
}
var results []draftLcmd.runDraftsGet function · go · L293-L367 (75 LOC)cmd/drafts.go
func runDraftsGet(cmd *cobra.Command, args []string) error {
draftID := args[0]
ctx := context.Background()
service, err := auth.NewGmailService(ctx, GetAccountEmail())
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
// Get the draft with full format
draft, err := service.Users.Drafts.Get("me", draftID).Format("full").Do()
if err != nil {
return fmt.Errorf("Gmail API error: %w", err)
}
if draft.Message == nil || draft.Message.Payload == nil {
return fmt.Errorf("draft not found: %s", draftID)
}
// Extract headers
var to, subject, date string
for _, header := range draft.Message.Payload.Headers {
switch header.Name {
case "To":
to = header.Value
case "Subject":
subject = header.Value
case "Date":
date = header.Value
}
}
// Extract body content
body := extractDraftBody(draft.Message)
// JSON output mode
if GetOutputFormat() == "json" {
type draftGetResult struct {
DraftID string `json:"draft_id"`
To stricmd.extractDraftBody function · go · L371-L383 (13 LOC)cmd/drafts.go
func extractDraftBody(msg *gmail.Message) string {
if msg.Payload == nil {
return ""
}
// Check if the payload itself has body data
if msg.Payload.MimeType == "text/plain" && msg.Payload.Body != nil && msg.Payload.Body.Data != "" {
return decodeDraftBase64URL(msg.Payload.Body.Data)
}
// Search through parts
return findDraftPlainTextPart(msg.Payload.Parts)
}Repobility — same analyzer, your code, free for public repos · /scan/
cmd.findDraftPlainTextPart function · go · L386-L399 (14 LOC)cmd/drafts.go
func findDraftPlainTextPart(parts []*gmail.MessagePart) string {
for _, part := range parts {
if part.MimeType == "text/plain" && part.Body != nil && part.Body.Data != "" {
return decodeDraftBase64URL(part.Body.Data)
}
// Recurse into nested parts (for multipart messages)
if len(part.Parts) > 0 {
if content := findDraftPlainTextPart(part.Parts); content != "" {
return content
}
}
}
return ""
}cmd.decodeDraftBase64URL function · go · L402-L412 (11 LOC)cmd/drafts.go
func decodeDraftBase64URL(encoded string) string {
decoded, err := base64.URLEncoding.DecodeString(encoded)
if err != nil {
// Try with padding
decoded, err = base64.RawURLEncoding.DecodeString(encoded)
if err != nil {
return ""
}
}
return string(decoded)
}cmd.runDraftsCreate function · go · L414-L458 (45 LOC)cmd/drafts.go
func runDraftsCreate(cmd *cobra.Command, args []string) error {
ctx := context.Background()
service, err := auth.NewGmailService(ctx, GetAccountEmail())
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
// Build RFC 2822 formatted message
message := buildRFC2822Message(draftTo, draftSubject, draftBody, draftCc, draftBcc)
// Base64url encode the message
encodedMessage := base64.URLEncoding.EncodeToString([]byte(message))
// Create the draft
draft := &gmail.Draft{
Message: &gmail.Message{
Raw: encodedMessage,
},
}
created, err := service.Users.Drafts.Create("me", draft).Do()
if err != nil {
return fmt.Errorf("Gmail API error: %w", err)
}
// JSON output mode
if GetOutputFormat() == "json" {
type draftCreateResult struct {
DraftID string `json:"draft_id"`
MessageID string `json:"message_id"`
}
msgID := ""
if created.Message != nil {
msgID = created.Message.Id
}
return outputJSON(draftCreateResult{
DraftID: crecmd.runDraftsUpdate function · go · L460-L558 (99 LOC)cmd/drafts.go
func runDraftsUpdate(cmd *cobra.Command, args []string) error {
draftID := args[0]
if draftTo == "" && draftSubject == "" && draftBody == "" && draftCc == "" && draftBcc == "" {
return fmt.Errorf("at least one of --to, --subject, --body, --cc, or --bcc is required")
}
ctx := context.Background()
service, err := auth.NewGmailService(ctx, GetAccountEmail())
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
// Get existing draft to preserve unmodified fields
existing, err := service.Users.Drafts.Get("me", draftID).Format("full").Do()
if err != nil {
return fmt.Errorf("draft not found: %s", draftID)
}
// Extract existing values from headers
var existingTo, existingSubject, existingCc, existingBcc string
if existing.Message != nil && existing.Message.Payload != nil {
for _, header := range existing.Message.Payload.Headers {
switch header.Name {
case "To":
existingTo = header.Value
case "Subject":
existingSubject = header.Value
cmd.runDraftsSend function · go · L560-L592 (33 LOC)cmd/drafts.go
func runDraftsSend(cmd *cobra.Command, args []string) error {
draftID := args[0]
ctx := context.Background()
service, err := auth.NewGmailService(ctx, GetAccountEmail())
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
// Send the draft
draft := &gmail.Draft{
Id: draftID,
}
sent, err := service.Users.Drafts.Send("me", draft).Do()
if err != nil {
return fmt.Errorf("Gmail API error: %w", err)
}
// JSON output mode
if GetOutputFormat() == "json" {
type draftSendResult struct {
MessageID string `json:"message_id"`
}
return outputJSON(draftSendResult{
MessageID: sent.Id,
})
}
fmt.Printf("Draft sent as message: %s\n", sent.Id)
return nil
}cmd.runDraftsDelete function · go · L594-L624 (31 LOC)cmd/drafts.go
func runDraftsDelete(cmd *cobra.Command, args []string) error {
draftID := args[0]
ctx := context.Background()
service, err := auth.NewGmailService(ctx, GetAccountEmail())
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
// Delete the draft
err = service.Users.Drafts.Delete("me", draftID).Do()
if err != nil {
return fmt.Errorf("Gmail API error: %w", err)
}
// JSON output mode
if GetOutputFormat() == "json" {
type draftDeleteResult struct {
DraftID string `json:"draft_id"`
Deleted bool `json:"deleted"`
}
return outputJSON(draftDeleteResult{
DraftID: draftID,
Deleted: true,
})
}
fmt.Printf("Draft deleted: %s\n", draftID)
return nil
}cmd.buildRFC2822Message function · go · L627-L644 (18 LOC)cmd/drafts.go
func buildRFC2822Message(to, subject, body, cc, bcc string) string {
var msg string
msg += fmt.Sprintf("To: %s\r\n", to)
if cc != "" {
msg += fmt.Sprintf("Cc: %s\r\n", cc)
}
if bcc != "" {
msg += fmt.Sprintf("Bcc: %s\r\n", bcc)
}
msg += fmt.Sprintf("Subject: %s\r\n", subject)
msg += "MIME-Version: 1.0\r\n"
msg += "Content-Type: text/plain; charset=\"UTF-8\"\r\n"
msg += "\r\n"
msg += body
return msg
}cmd.runInstallSkill function · go · L40-L49 (10 LOC)cmd/install_skill.go
func runInstallSkill(cmd *cobra.Command, args []string) error {
client, _ := cmd.Flags().GetString("client")
skillsDir, ok := clientSkillDirs[client]
if !ok {
return fmt.Errorf("unknown client %q (supported: claude, openclaw-workspace)", client)
}
targetDir := filepath.Join(skillsDir, "gsuite-manager")
return installSkillFiles(SkillFS, "skills/gsuite-manager", targetDir)
}Repobility analyzer · published findings · https://repobility.com
cmd.installSkillFiles function · go · L51-L80 (30 LOC)cmd/install_skill.go
func installSkillFiles(source fs.FS, embeddedRoot, targetDir string) error {
sub, err := fs.Sub(source, embeddedRoot)
if err != nil {
return fmt.Errorf("reading embedded skill files: %w", err)
}
return fs.WalkDir(sub, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
dest := filepath.Join(targetDir, path)
if d.IsDir() {
return os.MkdirAll(dest, 0o755)
}
data, err := fs.ReadFile(sub, path)
if err != nil {
return fmt.Errorf("reading %s: %w", path, err)
}
if err := os.WriteFile(dest, data, 0o644); err != nil {
return fmt.Errorf("writing %s: %w", dest, err)
}
fmt.Println(" wrote", dest)
return nil
})
}cmd.init function · go · L125-L142 (18 LOC)cmd/labels.go
func init() {
rootCmd.AddCommand(labelsCmd)
labelsCmd.AddCommand(labelsListCmd)
labelsCmd.AddCommand(labelsCreateCmd)
labelsCmd.AddCommand(labelsUpdateCmd)
labelsCmd.AddCommand(labelsDeleteCmd)
// labelsCreateCmd flags
labelsCreateCmd.Flags().StringVarP(&labelName, "name", "n", "", "Name for the new label (required)")
labelsCreateCmd.Flags().StringVar(&labelListVisibility, "label-list-visibility", "", "Label list visibility (labelShow, labelShowIfUnread, labelHide)")
labelsCreateCmd.Flags().StringVar(&messageListVisibility, "message-list-visibility", "", "Message list visibility (show, hide)")
labelsCreateCmd.MarkFlagRequired("name")
// labelsUpdateCmd flags (reuses the same flag variables)
labelsUpdateCmd.Flags().StringVarP(&labelName, "name", "n", "", "New name for the label")
labelsUpdateCmd.Flags().StringVar(&labelListVisibility, "label-list-visibility", "", "Label list visibility (labelShow, labelShowIfUnread, labelHide)")
labelsUpdateCmd.Flags().StringVar(&messagecmd.runLabelsList function · go · L144-L214 (71 LOC)cmd/labels.go
func runLabelsList(cmd *cobra.Command, args []string) error {
ctx := context.Background()
service, err := auth.NewGmailService(ctx, GetAccountEmail())
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
// List labels
resp, err := service.Users.Labels.List("me").Do()
if err != nil {
return fmt.Errorf("Gmail API error: %w", err)
}
// Separate system and user labels
var systemLabels, userLabels []*gmail.Label
for _, label := range resp.Labels {
if label.Type == "system" {
systemLabels = append(systemLabels, label)
} else {
userLabels = append(userLabels, label)
}
}
// Sort each group alphabetically by name
sort.Slice(systemLabels, func(i, j int) bool {
return systemLabels[i].Name < systemLabels[j].Name
})
sort.Slice(userLabels, func(i, j int) bool {
return userLabels[i].Name < userLabels[j].Name
})
// JSON output mode
if GetOutputFormat() == "json" {
type labelItem struct {
ID string `json:"id"`
Name string `json:"nacmd.runLabelsCreate function · go · L216-L265 (50 LOC)cmd/labels.go
func runLabelsCreate(cmd *cobra.Command, args []string) error {
if labelName == "" {
return fmt.Errorf("--name flag is required")
}
ctx := context.Background()
service, err := auth.NewGmailService(ctx, GetAccountEmail())
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
// Build the label object
label := &gmail.Label{
Name: labelName,
}
// Set optional visibility settings
if labelListVisibility != "" {
label.LabelListVisibility = labelListVisibility
}
if messageListVisibility != "" {
label.MessageListVisibility = messageListVisibility
}
// Create the label
created, err := service.Users.Labels.Create("me", label).Do()
if err != nil {
return fmt.Errorf("Gmail API error: %w", err)
}
// JSON output mode
if GetOutputFormat() == "json" {
type labelCreateResult struct {
ID string `json:"id"`
Name string `json:"name"`
LabelListVisibility string `json:"label_list_visibility"`
MessageLiscmd.runLabelsUpdate function · go · L267-L335 (69 LOC)cmd/labels.go
func runLabelsUpdate(cmd *cobra.Command, args []string) error {
labelID := args[0]
// Check if it's a system label
if systemLabelIDs[labelID] || strings.HasPrefix(labelID, "CATEGORY_") {
return fmt.Errorf("cannot modify system label: %s", labelID)
}
if labelName == "" && labelListVisibility == "" && messageListVisibility == "" {
return fmt.Errorf("at least one of --name, --label-list-visibility, or --message-list-visibility is required")
}
ctx := context.Background()
service, err := auth.NewGmailService(ctx, GetAccountEmail())
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
// First, get the existing label to check if it exists
existing, err := service.Users.Labels.Get("me", labelID).Do()
if err != nil {
if strings.Contains(err.Error(), "404") || strings.Contains(err.Error(), "Not Found") {
return fmt.Errorf("label not found: %s", labelID)
}
return fmt.Errorf("Gmail API error: %w", err)
}
// Check if it's a system label by type
cmd.runLabelsDelete function · go · L337-L386 (50 LOC)cmd/labels.go
func runLabelsDelete(cmd *cobra.Command, args []string) error {
labelID := args[0]
// Check if it's a system label
if systemLabelIDs[labelID] || strings.HasPrefix(labelID, "CATEGORY_") {
return fmt.Errorf("cannot delete system label: %s", labelID)
}
ctx := context.Background()
service, err := auth.NewGmailService(ctx, GetAccountEmail())
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
// First, verify the label exists and check if it's a system label
existing, err := service.Users.Labels.Get("me", labelID).Do()
if err != nil {
if strings.Contains(err.Error(), "404") || strings.Contains(err.Error(), "Not Found") {
return fmt.Errorf("label not found: %s", labelID)
}
return fmt.Errorf("Gmail API error: %w", err)
}
// Check if it's a system label by type
if existing.Type == "system" {
return fmt.Errorf("cannot delete system label: %s", labelID)
}
// Delete the label
err = service.Users.Labels.Delete("me", labelID).Do()
if err != ncmd.runLogin function · go · L52-L73 (22 LOC)cmd/login.go
func runLogin(cmd *cobra.Command, args []string) error {
credJSON, err := auth.LoadCredentials()
if err != nil {
return fmt.Errorf("no credentials found: %w", err)
}
ctx := context.Background()
email, err := auth.Login(ctx, credJSON)
if err != nil {
return err
}
fmt.Printf("Logged in as %s\n", email)
store, err := auth.LoadAccountStore()
if err == nil && len(store.List()) > 1 {
fmt.Printf("Active account set to %s. Use 'gsuite accounts list' to see all accounts.\n", email)
}
return nil
}cmd.runLogout function · go · L75-L113 (39 LOC)cmd/login.go
func runLogout(cmd *cobra.Command, args []string) error {
store, err := auth.LoadAccountStore()
if err != nil {
return fmt.Errorf("failed to load account store: %w", err)
}
var email string
if len(args) > 0 {
email = args[0]
} else {
email, err = store.GetActive()
if err != nil {
fmt.Println("Not logged in")
return nil
}
}
if err := store.RemoveAccount(email); err != nil {
return err
}
if err := store.Save(); err != nil {
return fmt.Errorf("failed to save account store: %w", err)
}
if err := auth.DeleteTokenFor(email); err != nil {
return fmt.Errorf("failed to remove token: %w", err)
}
fmt.Printf("Logged out of %s\n", email)
if len(store.List()) > 0 {
fmt.Printf("Active account: %s\n", store.Active)
} else {
fmt.Println("No remaining accounts")
}
return nil
}Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
cmd.init function · go · L132-L150 (19 LOC)cmd/messages.go
func init() {
rootCmd.AddCommand(messagesCmd)
messagesCmd.AddCommand(messagesListCmd)
messagesCmd.AddCommand(messagesGetCmd)
messagesCmd.AddCommand(messagesModifyCmd)
messagesCmd.AddCommand(messagesGetAttachmentCmd)
// messagesListCmd flags
messagesListCmd.Flags().Int64VarP(&maxResults, "max-results", "n", 10, "Maximum number of messages to return (max 500)")
messagesListCmd.Flags().StringVar(&labelIDs, "label-ids", "", "Comma-separated label IDs to filter by (e.g., INBOX,UNREAD)")
messagesListCmd.Flags().StringVarP(&query, "query", "q", "", "Gmail search query string")
// messagesModifyCmd flags
messagesModifyCmd.Flags().StringVar(&addLabels, "add-labels", "", "Comma-separated label IDs to add (e.g., STARRED,Label_123)")
messagesModifyCmd.Flags().StringVar(&removeLabels, "remove-labels", "", "Comma-separated label IDs to remove (e.g., UNREAD,INBOX)")
// messagesGetAttachmentCmd flags
messagesGetAttachmentCmd.Flags().StringVarP(&attachmentOutput, "output", "o", "", "Oucmd.runMessagesList function · go · L152-L240 (89 LOC)cmd/messages.go
func runMessagesList(cmd *cobra.Command, args []string) error {
ctx := context.Background()
service, err := auth.NewGmailService(ctx, GetAccountEmail())
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
// Build the list request
listCall := service.Users.Messages.List("me")
// Apply max results (cap at 500)
if maxResults > 500 {
maxResults = 500
}
listCall.MaxResults(maxResults)
// Apply label filter if provided
if labelIDs != "" {
labels := strings.Split(labelIDs, ",")
listCall.LabelIds(labels...)
}
// Apply search query if provided
if query != "" {
listCall.Q(query)
}
// Execute the request
resp, err := listCall.Do()
if err != nil {
return fmt.Errorf("Gmail API error: %w", err)
}
// Check if no messages found
if len(resp.Messages) == 0 {
if GetOutputFormat() == "json" {
return outputJSON([]struct{}{})
}
fmt.Println("No messages found.")
return nil
}
// JSON output mode
if GetOutputFormat() == "json" {
type cmd.runMessagesGet function · go · L242-L349 (108 LOC)cmd/messages.go
func runMessagesGet(cmd *cobra.Command, args []string) error {
messageID := args[0]
ctx := context.Background()
service, err := auth.NewGmailService(ctx, GetAccountEmail())
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
// Get the message with full format
msg, err := service.Users.Messages.Get("me", messageID).Format("full").Do()
if err != nil {
return fmt.Errorf("Gmail API error: %w", err)
}
// Extract headers
var from, to, subject, date string
for _, header := range msg.Payload.Headers {
switch header.Name {
case "From":
from = header.Value
case "To":
to = header.Value
case "Subject":
subject = header.Value
case "Date":
date = header.Value
}
}
// Extract body content
body := extractBody(msg)
if body == "" {
body = msg.Snippet
}
// Extract attachments
attachments := findAttachments(msg.Payload.Parts)
// JSON output mode
if GetOutputFormat() == "json" {
type attachmentJSON struct {
Filename stringpage 1 / 3next ›