Skip to content
This repository has been archived by the owner on Sep 21, 2023. It is now read-only.

Retrieve issues from both services #1

Merged
merged 1 commit into from
Jul 20, 2017
Merged

Retrieve issues from both services #1

merged 1 commit into from
Jul 20, 2017

Conversation

MorganEPatch
Copy link
Contributor

@MorganEPatch MorganEPatch commented Jul 7, 2017

Using provided credentials, request a list of GitHub issues updated after a certain time, then the matching list of JIRA issues where they exist. Pair the two lists: for each GitHub issue, if no matching JIRA issue exists, prepare to create it; if an issue exists, prepare to compare the two and update their differences.

Design docs are located at https://docs.google.com/a/coreos.com/document/d/1YjAIqAa-RGC2AZVvlRk1QWbLsJUyt67nIh8lWqKFcK8/edit?usp=sharing.

@MorganEPatch MorganEPatch self-assigned this Jul 7, 2017
@MorganEPatch MorganEPatch changed the title [WIP] Base synchronizing functionality [WIP] Retrieve issues from both services Jul 7, 2017
@MorganEPatch MorganEPatch changed the title [WIP] Retrieve issues from both services Retrieve issues from both services Jul 7, 2017
@MorganEPatch MorganEPatch requested review from kans and removed request for kans July 11, 2017 23:24
kans
kans previously requested changes Jul 12, 2017
cmd/root.go Outdated
return nil
}

type Field struct {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you rename this to something more descriptive?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Maybe JIRAField?

return err
}

for _, field := range *fields {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will happen if we don't set ghIDFieldID?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added checks that these fields exist on the project. Later I can make some of them optional and have the tool recognize that, but for now they're all required. I'll document it in the README when I write that up.

ghIssues, _, err := ghClient.Issues.ListByRepo(ctx, repo[0], repo[1], &github.IssueListByRepoOptions{
Since: since,
ListOptions: github.ListOptions{
PerPage: 100,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will have to add support for pagination later?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, for now it just operates on the most recent page of results.

cmd/root.go Outdated
if int64(*ghIssue.ID) == id {
found = true
if err := updateIssue(*ghIssue, jIssue); err != nil {
return err
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would probably be better to log this err and keep trucking - (and the same below).

@kans
Copy link

kans commented Jul 12, 2017

@LyonesGamer

If you have several more PRs chained after this and don't want to go through rebasing them all multiple times, you could just address the comments in a future PR.

@MorganEPatch
Copy link
Contributor Author

I think it'll be fine; they're all linear, and the comments are mostly small changes so far anyway. They should rebase pretty easily. If there's a comment asking for a big change, I'll probably make it a new PR.

cmd/root.go Outdated
)

func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
log.Debugln(err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than log.Debug followed by os.Exit consider using just log.Fatal. It is more semantic and will appropriately exit the process.

cmd/root.go Outdated
os.Exit(1)
}
}

func GetGitHubClient(token string) (*github.Client, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document all exported types like this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I admit that I should have been documenting all of these as I went, but I did document them all in #11, if that helps.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, it means that all the PRs until #11 lands are difficult to reason about. Please break up #11 and spread the documentation into each of the previous PRs

cmd/root.go Outdated
// Make a request so we can check that we can connect fine.
_, res, err := client.RateLimits(ctx)
if err != nil {
log.Errorf("Error connecting to GitHub; check your token. Error: %s", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is convention to format errors using %v rather than %s

return client, nil
}

func GetJIRAClient(username, password, baseURL string) (*jira.Client, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also document please.

return nil
}

type JIRAField struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document this type

return nil
}

func compareIssues(ghClient github.Client, jiraClient jira.Client) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please document this too even though it is not exported. would be nice to know without reading the whole function what this large block of code is trying to accomplish

}

func updateIssue(ghIssue github.Issue, jIssue jira.Issue) error {
log.Debugf("Updating JIRA issue %s with GitHub issue %d", jIssue.ID, *ghIssue.ID)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are currently just placeholders?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, they're just to help show that compareIssues is working until the function bodies are added in future PRs.

cmd/root.go Outdated
return err
}

f, err := os.OpenFile(rootCmdCfg.ConfigFileUsed(), os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0751)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why 751? the config is not executable. 644 sounds more appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. You're right. I got my permission values mixed up.

defaultLogLevel = logrus.InfoLevel
rootCmdFile string
rootCmdCfg *viper.Viper

since time.Time // The earliest GitHub issue updates we want to retrieve
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general we try to have as few global variables as possible. Why are all of these floating around vs being collected in a config?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, by convention we document types and variables by commenting above the variable: https://blog.golang.org/godoc-documenting-go-code

)

var (
log *logrus.Logger
log *logrus.Entry
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not logrus.Logger?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Entry is a logger with fields attached, such as the app name that's attached in newLogger().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I understand that theyre different, what I am asking is why did you change? not a big deal. we typically do not use Entry in other projects but it doesn't at all that it is wrong

Copy link
Contributor Author

@MorganEPatch MorganEPatch Jul 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using an Entry is how it was done in https://github.com/sym3tri/hookz, which is what I was told to use as a template for this project.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@squat
Copy link
Contributor

squat commented Jul 19, 2017

Overall looks ok, Most troubling is the use of lots of global variables rather than collecting all the configuration.

At this point, all GitHub issues are retrieved, all of their
matching JIRA issues are retrieved, and the two are matched
in preparation to either create or update the JIRA issues.
@MorganEPatch MorganEPatch dismissed kans’s stale review July 20, 2017 17:30

Outdated review; the issues have been fixed and approved by another member

@MorganEPatch MorganEPatch merged commit b77ece9 into coreos:master Jul 20, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants