This repository was archived by the owner on Sep 21, 2023. It is now read-only.

Retrieve issues from both services - #1

Merged
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync
Jul 20, 2017
Merged

Retrieve issues from both services#1
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync

Conversation

@MorganEPatch

@MorganEPatchMorganEPatch commented Jul 7, 2017

Copy link
Copy Markdown
Contributor

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.

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

type Field struct {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Agreed. Maybe JIRAField?

Comment threadcmd/root.go
return err
}

for _, field := range *fields {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
ghIssues, _, err := ghClient.Issues.ListByRepo(ctx, repo[0], repo[1], &github.IssueListByRepoOptions{
Since: since,
ListOptions: github.ListOptions{
PerPage: 100,

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown

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

kans commented Jul 12, 2017

Copy link
Copy Markdown

@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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
log.Debugln(err)

Copy link
Copy Markdown
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.

Comment threadcmd/root.go
}
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

Comment threadcmd/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
Copy Markdown
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

Comment threadcmd/root.go
return client, nil
}

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also document please.

Comment threadcmd/root.go
return nil
}

type JIRAField struct {

Copy link
Copy Markdown
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

Comment threadcmd/root.go
return nil
}

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

Copy link
Copy Markdown
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

Comment threadcmd/root.go
}

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
return err
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
rootCmdFile string
rootCmdCfg *viper.Viper

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

Copy link
Copy Markdown
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
Copy Markdown
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

Comment threadcmd/root.go

var (
log *logrus.Logger
log *logrus.Entry

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

@MorganEPatchMorganEPatchJul 19, 2017

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@squat

Copy link
Copy Markdown
Contributor

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 reviewJuly 20, 2017 17:30

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

@MorganEPatch
MorganEPatch merged commit b77ece9 into coreos:masterJul 20, 2017
Sign up for freeto 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

@MorganEPatch@kans@squat
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
This repository was archived by the owner on Sep 21, 2023. It is now read-only.

Retrieve issues from both services - #1

Merged
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync
Jul 20, 2017
Merged

Retrieve issues from both services#1
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync

Conversation

@MorganEPatch

@MorganEPatchMorganEPatch commented Jul 7, 2017

Copy link
Copy Markdown
Contributor

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.

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

type Field struct {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Agreed. Maybe JIRAField?

Comment threadcmd/root.go
return err
}

for _, field := range *fields {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
ghIssues, _, err := ghClient.Issues.ListByRepo(ctx, repo[0], repo[1], &github.IssueListByRepoOptions{
Since: since,
ListOptions: github.ListOptions{
PerPage: 100,

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown

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

kans commented Jul 12, 2017

Copy link
Copy Markdown

@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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
log.Debugln(err)

Copy link
Copy Markdown
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.

Comment threadcmd/root.go
}
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

Comment threadcmd/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
Copy Markdown
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

Comment threadcmd/root.go
return client, nil
}

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also document please.

Comment threadcmd/root.go
return nil
}

type JIRAField struct {

Copy link
Copy Markdown
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

Comment threadcmd/root.go
return nil
}

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

Copy link
Copy Markdown
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

Comment threadcmd/root.go
}

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
return err
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
rootCmdFile string
rootCmdCfg *viper.Viper

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

Copy link
Copy Markdown
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
Copy Markdown
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

Comment threadcmd/root.go

var (
log *logrus.Logger
log *logrus.Entry

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

@MorganEPatchMorganEPatchJul 19, 2017

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@squat

Copy link
Copy Markdown
Contributor

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 reviewJuly 20, 2017 17:30

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

@MorganEPatch
MorganEPatch merged commit b77ece9 into coreos:masterJul 20, 2017
Sign up for freeto 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

@MorganEPatch@kans@squat
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Sep 21, 2023. It is now read-only.

Retrieve issues from both services - #1

Merged
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync
Jul 20, 2017
Merged

Retrieve issues from both services#1
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync

Conversation

@MorganEPatch

@MorganEPatchMorganEPatch commented Jul 7, 2017

Copy link
Copy Markdown
Contributor

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.

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

type Field struct {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Agreed. Maybe JIRAField?

Comment threadcmd/root.go
return err
}

for _, field := range *fields {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
ghIssues, _, err := ghClient.Issues.ListByRepo(ctx, repo[0], repo[1], &github.IssueListByRepoOptions{
Since: since,
ListOptions: github.ListOptions{
PerPage: 100,

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown

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

kans commented Jul 12, 2017

Copy link
Copy Markdown

@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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
log.Debugln(err)

Copy link
Copy Markdown
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.

Comment threadcmd/root.go
}
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

Comment threadcmd/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
Copy Markdown
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

Comment threadcmd/root.go
return client, nil
}

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also document please.

Comment threadcmd/root.go
return nil
}

type JIRAField struct {

Copy link
Copy Markdown
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

Comment threadcmd/root.go
return nil
}

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

Copy link
Copy Markdown
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

Comment threadcmd/root.go
}

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
return err
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
rootCmdFile string
rootCmdCfg *viper.Viper

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

Copy link
Copy Markdown
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
Copy Markdown
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

Comment threadcmd/root.go

var (
log *logrus.Logger
log *logrus.Entry

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

@MorganEPatchMorganEPatchJul 19, 2017

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@squat

Copy link
Copy Markdown
Contributor

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 reviewJuly 20, 2017 17:30

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

@MorganEPatch
MorganEPatch merged commit b77ece9 into coreos:masterJul 20, 2017
Sign up for freeto 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

@MorganEPatch@kans@squat
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Sep 21, 2023. It is now read-only.

Retrieve issues from both services - #1

Merged
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync
Jul 20, 2017
Merged

Retrieve issues from both services#1
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync

Conversation

@MorganEPatch

@MorganEPatchMorganEPatch commented Jul 7, 2017

Copy link
Copy Markdown
Contributor

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.

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

type Field struct {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Agreed. Maybe JIRAField?

Comment threadcmd/root.go
return err
}

for _, field := range *fields {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
ghIssues, _, err := ghClient.Issues.ListByRepo(ctx, repo[0], repo[1], &github.IssueListByRepoOptions{
Since: since,
ListOptions: github.ListOptions{
PerPage: 100,

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown

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

kans commented Jul 12, 2017

Copy link
Copy Markdown

@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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
log.Debugln(err)

Copy link
Copy Markdown
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.

Comment threadcmd/root.go
}
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

Comment threadcmd/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
Copy Markdown
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

Comment threadcmd/root.go
return client, nil
}

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also document please.

Comment threadcmd/root.go
return nil
}

type JIRAField struct {

Copy link
Copy Markdown
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

Comment threadcmd/root.go
return nil
}

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

Copy link
Copy Markdown
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

Comment threadcmd/root.go
}

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
return err
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
rootCmdFile string
rootCmdCfg *viper.Viper

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

Copy link
Copy Markdown
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
Copy Markdown
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

Comment threadcmd/root.go

var (
log *logrus.Logger
log *logrus.Entry

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

@MorganEPatchMorganEPatchJul 19, 2017

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@squat

Copy link
Copy Markdown
Contributor

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 reviewJuly 20, 2017 17:30

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

@MorganEPatch
MorganEPatch merged commit b77ece9 into coreos:masterJul 20, 2017
Sign up for freeto 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

@MorganEPatch@kans@squat
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
This repository was archived by the owner on Sep 21, 2023. It is now read-only.

Retrieve issues from both services - #1

Merged
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync
Jul 20, 2017
Merged

Retrieve issues from both services#1
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync

Conversation

@MorganEPatch

@MorganEPatchMorganEPatch commented Jul 7, 2017

Copy link
Copy Markdown
Contributor

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.

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

type Field struct {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Agreed. Maybe JIRAField?

Comment threadcmd/root.go
return err
}

for _, field := range *fields {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
ghIssues, _, err := ghClient.Issues.ListByRepo(ctx, repo[0], repo[1], &github.IssueListByRepoOptions{
Since: since,
ListOptions: github.ListOptions{
PerPage: 100,

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown

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

kans commented Jul 12, 2017

Copy link
Copy Markdown

@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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
log.Debugln(err)

Copy link
Copy Markdown
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.

Comment threadcmd/root.go
}
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

Comment threadcmd/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
Copy Markdown
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

Comment threadcmd/root.go
return client, nil
}

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also document please.

Comment threadcmd/root.go
return nil
}

type JIRAField struct {

Copy link
Copy Markdown
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

Comment threadcmd/root.go
return nil
}

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

Copy link
Copy Markdown
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

Comment threadcmd/root.go
}

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
return err
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
rootCmdFile string
rootCmdCfg *viper.Viper

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

Copy link
Copy Markdown
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
Copy Markdown
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

Comment threadcmd/root.go

var (
log *logrus.Logger
log *logrus.Entry

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

@MorganEPatchMorganEPatchJul 19, 2017

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@squat

Copy link
Copy Markdown
Contributor

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 reviewJuly 20, 2017 17:30

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

@MorganEPatch
MorganEPatch merged commit b77ece9 into coreos:masterJul 20, 2017
Sign up for freeto 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

@MorganEPatch@kans@squat
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Sep 21, 2023. It is now read-only.

Retrieve issues from both services - #1

Merged
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync
Jul 20, 2017
Merged

Retrieve issues from both services#1
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync

Conversation

@MorganEPatch

@MorganEPatchMorganEPatch commented Jul 7, 2017

Copy link
Copy Markdown
Contributor

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.

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

type Field struct {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Agreed. Maybe JIRAField?

Comment threadcmd/root.go
return err
}

for _, field := range *fields {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
ghIssues, _, err := ghClient.Issues.ListByRepo(ctx, repo[0], repo[1], &github.IssueListByRepoOptions{
Since: since,
ListOptions: github.ListOptions{
PerPage: 100,

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown

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

kans commented Jul 12, 2017

Copy link
Copy Markdown

@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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
log.Debugln(err)

Copy link
Copy Markdown
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.

Comment threadcmd/root.go
}
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

Comment threadcmd/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
Copy Markdown
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

Comment threadcmd/root.go
return client, nil
}

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also document please.

Comment threadcmd/root.go
return nil
}

type JIRAField struct {

Copy link
Copy Markdown
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

Comment threadcmd/root.go
return nil
}

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

Copy link
Copy Markdown
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

Comment threadcmd/root.go
}

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
return err
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
rootCmdFile string
rootCmdCfg *viper.Viper

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

Copy link
Copy Markdown
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
Copy Markdown
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

Comment threadcmd/root.go

var (
log *logrus.Logger
log *logrus.Entry

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

@MorganEPatchMorganEPatchJul 19, 2017

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@squat

Copy link
Copy Markdown
Contributor

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 reviewJuly 20, 2017 17:30

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

@MorganEPatch
MorganEPatch merged commit b77ece9 into coreos:masterJul 20, 2017
Sign up for freeto 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

@MorganEPatch@kans@squat
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Sep 21, 2023. It is now read-only.

Retrieve issues from both services - #1

Merged
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync
Jul 20, 2017
Merged

Retrieve issues from both services#1
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync

Conversation

@MorganEPatch

@MorganEPatchMorganEPatch commented Jul 7, 2017

Copy link
Copy Markdown
Contributor

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.

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

type Field struct {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Agreed. Maybe JIRAField?

Comment threadcmd/root.go
return err
}

for _, field := range *fields {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
ghIssues, _, err := ghClient.Issues.ListByRepo(ctx, repo[0], repo[1], &github.IssueListByRepoOptions{
Since: since,
ListOptions: github.ListOptions{
PerPage: 100,

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown

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

kans commented Jul 12, 2017

Copy link
Copy Markdown

@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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
log.Debugln(err)

Copy link
Copy Markdown
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.

Comment threadcmd/root.go
}
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

Comment threadcmd/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
Copy Markdown
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

Comment threadcmd/root.go
return client, nil
}

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also document please.

Comment threadcmd/root.go
return nil
}

type JIRAField struct {

Copy link
Copy Markdown
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

Comment threadcmd/root.go
return nil
}

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

Copy link
Copy Markdown
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

Comment threadcmd/root.go
}

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
return err
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
rootCmdFile string
rootCmdCfg *viper.Viper

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

Copy link
Copy Markdown
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
Copy Markdown
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

Comment threadcmd/root.go

var (
log *logrus.Logger
log *logrus.Entry

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

@MorganEPatchMorganEPatchJul 19, 2017

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@squat

Copy link
Copy Markdown
Contributor

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 reviewJuly 20, 2017 17:30

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

@MorganEPatch
MorganEPatch merged commit b77ece9 into coreos:masterJul 20, 2017
Sign up for freeto 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

@MorganEPatch@kans@squat
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
This repository was archived by the owner on Sep 21, 2023. It is now read-only.

Retrieve issues from both services - #1

Merged
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync
Jul 20, 2017
Merged

Retrieve issues from both services#1
MorganEPatch merged 1 commit into
coreos:masterfrom
MorganEPatch:gh-to-jira-sync

Conversation

@MorganEPatch

@MorganEPatchMorganEPatch commented Jul 7, 2017

Copy link
Copy Markdown
Contributor

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.

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

type Field struct {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Agreed. Maybe JIRAField?

Comment threadcmd/root.go
return err
}

for _, field := range *fields {

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
ghIssues, _, err := ghClient.Issues.ListByRepo(ctx, repo[0], repo[1], &github.IssueListByRepoOptions{
Since: since,
ListOptions: github.ListOptions{
PerPage: 100,

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown

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

kans commented Jul 12, 2017

Copy link
Copy Markdown

@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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
log.Debugln(err)

Copy link
Copy Markdown
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.

Comment threadcmd/root.go
}
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

Comment threadcmd/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
Copy Markdown
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

Comment threadcmd/root.go
return client, nil
}

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also document please.

Comment threadcmd/root.go
return nil
}

type JIRAField struct {

Copy link
Copy Markdown
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

Comment threadcmd/root.go
return nil
}

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

Copy link
Copy Markdown
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

Comment threadcmd/root.go
}

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go Outdated
return err
}

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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

Comment threadcmd/root.go
rootCmdFile string
rootCmdCfg *viper.Viper

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

Copy link
Copy Markdown
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
Copy Markdown
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

Comment threadcmd/root.go

var (
log *logrus.Logger
log *logrus.Entry

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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

@MorganEPatchMorganEPatchJul 19, 2017

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@squat

Copy link
Copy Markdown
Contributor

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 reviewJuly 20, 2017 17:30

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

@MorganEPatch
MorganEPatch merged commit b77ece9 into coreos:masterJul 20, 2017
Sign up for freeto 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

@MorganEPatch@kans@squat