diff --git a/README.md b/README.md index e018fa9..9050950 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ Flags: --github-token GitHub API token (or env var GITHUB_TOKEN) --interval update interval (ex. 5ms, 10s, 1m, 3h) (default: 1m0s) --once run once and exit, do not run as a daemon (default: false) + --verbose-keys include title data in keys --orgs organizations to include (this option only applies to --autofill) (default: []) --watch-since defines the starting point of the issues been watched (format: 2006-01-02T15:04:05Z). defaults to no filter (default: 2008-01-01T00:00:00Z) --watched include the watched repositories (default: false) @@ -84,19 +85,20 @@ Commands: Your airtable table must have the following fields: -- `reference` **(single line text)** -- `title` **(single line text)** -- `type` **(single select)** -- `state` **(single line text)** -- `author` **(single line text)** -- `labels` **(multiple select)** -- `comments` **(number)** -- `url` **(url)** -- `updated` **(date, include time)** -- `created` **(date, include time)** -- `completed` **(date, include time)** -- `project` **(link to another sheet)** -- `repository` **(single line text)** +- `Reference` **(single line text)** +- `Title` **(single line text)** +- `Body` **(single line text)** +- `Type` **(single select)** +- `State` **(single select)** +- `Author` **(single line text)** +- `Labels` **(multiple select)** +- `Comments` **(number)** +- `URL` **(url)** +- `Updated` **(date, include time)** +- `Created` **(date, include time)** +- `Completed` **(date, include time)** +- `Project` **(link to another sheet)** +- `Repository` **(single line text)** The only data you need to initialize **(if not running with `--autofill`)** is the `Reference` which is in the format diff --git a/main.go b/main.go index 37bbdd3..01f60a5 100644 --- a/main.go +++ b/main.go @@ -14,7 +14,7 @@ import ( "golang.org/x/oauth2" - airtable "github.com/fabioberger/airtable-go" + airtable "github.com/iwoj/airtable-go" "github.com/genuinetools/pkg/cli" "github.com/google/go-github/github" "github.com/jessfraz/gitable/version" @@ -22,9 +22,10 @@ import ( ) var ( - interval time.Duration - autofill bool - once bool + interval time.Duration + autofill bool + verboseKeys bool + once bool githubToken string orgs stringSlice @@ -64,6 +65,7 @@ func main() { p.FlagSet = flag.NewFlagSet("global", flag.ExitOnError) p.FlagSet.DurationVar(&interval, "interval", time.Minute, "update interval (ex. 5ms, 10s, 1m, 3h)") p.FlagSet.BoolVar(&autofill, "autofill", false, "autofill all pull requests and issues for a user [or orgs] to a table (defaults to current user unless --orgs is set)") + p.FlagSet.BoolVar(&verboseKeys, "verbose-keys", false, "include title data in keys") p.FlagSet.BoolVar(&once, "once", false, "run once and exit, do not run as a daemon") p.FlagSet.StringVar(&githubToken, "github-token", os.Getenv("GITHUB_TOKEN"), "GitHub API token (or env var GITHUB_TOKEN)") @@ -196,12 +198,14 @@ type bot struct { type githubRecord struct { ID string `json:"id,omitempty"` Fields Fields `json:"fields,omitempty"` + Typecast bool `json:"typecast,omitempty"` } // Fields defines the airtable fields for the data. type Fields struct { Reference string Title string + Body string State string Author string Type string @@ -345,6 +349,7 @@ func (bot *bot) applyRecordToTable(ctx context.Context, issue *github.Issue, key Fields: Fields{ Reference: key, Title: issue.GetTitle(), + Body: issue.GetBody(), State: issue.GetState(), Author: issue.GetUser().GetLogin(), Type: issueType, @@ -355,12 +360,14 @@ func (bot *bot) applyRecordToTable(ctx context.Context, issue *github.Issue, key Completed: issue.GetClosedAt(), Repository: repo, }, + Typecast: true, } // Update the record fields. fields := map[string]interface{}{ "Reference": record.Fields.Reference, "Title": record.Fields.Title, + "Body": record.Fields.Body, "State": record.Fields.State, "Author": record.Fields.Author, "Type": record.Fields.Type, @@ -375,7 +382,7 @@ func (bot *bot) applyRecordToTable(ctx context.Context, issue *github.Issue, key if id != "" { // If we were passed a record ID, update the record instead of create. logrus.Debugf("updating record %s for issue %s", id, key) - if err := bot.airtableClient.UpdateRecord(airtableTableName, id, fields, &record); err != nil { + if err := bot.airtableClient.UpdateRecord(airtableTableName, id, fields, &record, true); err != nil { logrus.Warnf("updating record %s for issue %s failed: %v", id, key, err) return nil } @@ -390,7 +397,7 @@ func (bot *bot) applyRecordToTable(ctx context.Context, issue *github.Issue, key // Try again with labels, since the user may not have pre-populated the label options. // TODO: add a create multiple select when the airtable API supports it. fields["Labels"] = labels - if err := bot.airtableClient.UpdateRecord(airtableTableName, record.ID, fields, &record); err != nil { + if err := bot.airtableClient.UpdateRecord(airtableTableName, record.ID, fields, &record, true); err != nil { logrus.Warnf("updating record with labels %s for issue %s failed: %v", record.ID, key, err) } @@ -415,10 +422,18 @@ func (bot *bot) getRepositories(ctx context.Context, page, perPage int, affiliat if in(orgs, repo.GetOwner().GetLogin()) { logrus.Debugf("getting issues for repo %s...", repo.GetFullName()) ipage := 0 - if err := bot.getIssues(ctx, ipage, perPage, repo.GetOwner().GetLogin(), repo.GetName(), repo.UpdatedAt.Time); err != nil { + since, err := time.Parse("2006-01-02T15:04:05Z", "1900-01-02T15:04:05Z") + if err != nil { + return err + } + if !autofill { + since = repo.UpdatedAt.Time + } + if err := bot.getIssues(ctx, ipage, perPage, repo.GetOwner().GetLogin(), repo.GetName(), since); err != nil { logrus.Debugf("Failed to get issues for repo %s - %v\n", repo.GetName(), err) return err } + logrus.Debugf("Total issues: %d...", len(bot.issues)) } } @@ -478,6 +493,10 @@ func (bot *bot) getIssues(ctx context.Context, page, perPage int, owner, repo st for _, issue := range issues { key := fmt.Sprintf("%s/%s#%d", owner, repo, issue.GetNumber()) + if verboseKeys { + key = fmt.Sprintf("%s/%s#%d - %s", owner, repo, issue.GetNumber(), issue.GetTitle()) + } + // logrus.Debugf("handling issue %s...", key) bot.issues[key] = issue } @@ -494,6 +513,9 @@ func (bot *bot) getIssues(ctx context.Context, page, perPage int, owner, repo st func parseReference(ref string) (string, string, int, error) { // Split the reference into repository and issue number. parts := strings.SplitN(ref, "#", 2) + verboseParts := strings.SplitN(parts[1], " - ", 2) + parts[1] = verboseParts[0] + if len(parts) < 2 { return "", "", 0, fmt.Errorf("could not parse reference name into repository and issue number for %s, got: %#v", ref, parts) }