Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement additional SearchIssuesRequest options #1228

Merged
merged 13 commits into from
Apr 29, 2016

Conversation

ryangribble
Copy link
Contributor

@ryangribble ryangribble commented Mar 29, 2016

Status

  • Implemented new options
  • Unit tests for the request parameters for all new (and existing types)
  • Flesh out some integration tests to use some of the new options
  • Get feedback on naming of No property and IssueNoMetadataQualifier enum
  • Get feedback on implementation of exclusion parameters
  • Guidance from @haacked +/- @shiftkey on whether to include additional fields other than label in the exclusion support

Details

Fixes #1227
https://developer.github.com/v3/search/#search-issues
https://help.github.com/articles/searching-issues

Added new options to SearchIssuesRequest

  • Searching by team
  • Searching by "not" label syntax -label
  • Searching on missing metadata no
  • The "human" styled is query
    • (although state and type cover most of the is options, the merged/unmerged have no alternative)
  • Searching by commit status
  • Searching by branch names base or head
  • Searching on closed date range

Testing

Added unit tests for each parameter on this class to verify that when not set, the parameter is not in the query string, and when set the parameter is set as expected

Added some integration tests that excercise some of the new options

Discussion

I'd appreciate feedback on the implementation for "excluding" labels. In the API docs, this is done by using notation -label:labelname as opposed to label:labelname to include a label. At first I thought we could just implement this by having any label prepended with a hyphen be deemed to be an "exclusion" label, however it turns out that it's actually valid to have labels that start with a hyphen. So I implemented this as a separate list property SearchIssuesRequest.NotLabels

It feels a bit ugly so if someone has a better way, let me know

Update: Now renamed to SearchIssuesRequest.ExcludeLabels
See #1228 (comment) for how the "exclusion" field implementation is shaping up...

Similarly, the "missing metadata" search option, ive called the class property No to match the query property in API docs no, and gone with IssueNoMetadataQualifier as the enum name. Open to better suggestions...

@M-Zuber
Copy link
Contributor

M-Zuber commented Mar 29, 2016

A few things off the top of my head:

  • Have a test that uses a label starting with a hyphen and exclude it
    • Codifies the reasoning behind having that separate list
  • Can a username also start with a -?
    • If so, excluding issues by a given user would also necessitate a similar construct

Edit:
Real bran-fart this time: If a number of filterable items can start with a - (meaning to actually filter you'd need to do a --), maybe make a .Not property that contains a nested SearchIssuesRequest? (I know crazy idea but you only live once or something)

@ryangribble ryangribble changed the title [WIP] Implement additional SearchIssuesRequest options Implement additional SearchIssuesRequest options Mar 29, 2016
@ryangribble
Copy link
Contributor Author

Thanks for the feedback 👍

Unless Im missing something, I dont see anything in the API docs about being able to "negate" any of the other filter types though...

The only thing mentioned is labels (-label:labelname vs label:labelname) and keywords (specifying NOT fish instead of fish as the search term).

Have a test that uses a label starting with a hyphen and exclude it

With the way it's been implemented the label name doesn't really matter. I have a unit test that checks when 2 labels are specified in NotLabel we get the expected -label:label1 -label:label2 arguments. Also I added an integration test that searches octokit.net repo for "up-for-grabs" labelled issues and a 2nd search for NOT "up-for-grabs" labelled issues, then checks to make sure the lists are unique

@M-Zuber
Copy link
Contributor

M-Zuber commented Mar 29, 2016

image

It works on (almost) anything

Have a test that uses a label starting with a hyphen and exclude it

With the way it's been implemented the label name doesn't really matter. I have a unit test that checks when 2 labels are specified in NotLabel we get the expected -label:label1 -label:label2 arguments. Also I added an integration test that searches octokit.net repo for "up-for-grabs" labelled issues and a 2nd search for NOT "up-for-grabs" labelled issues, then checks to make sure the lists are unique

What I was trying to say was have a test that looks for a label that starts with a - so as to show that it is legal for a label to start with that char, and it will not be treated as negation if such a label exists.
Not showing that NotLabel will exclude it, but that Label/Term will include it

@shiftkey
Copy link
Member

@M-Zuber be careful, the repository issue search on the website is likely to be a bit different to what's available through the API. Someone asked me a while ago about this and I'm pretty sure -label doesn't work through the API when looking at repository issues, for example.

@ryangribble regarding your question about the properties, an alternative might be ExcludeLabels. Personally, I don't think that users should need to know or care that you need to do a - prefix, so this is a good direction to head.

@M-Zuber
Copy link
Contributor

M-Zuber commented Mar 29, 2016

  • :embarrassed: guess I just assumed the api was being dogfooded.
  • as someone who wrote (albeit a simple one) a query language, hiding syntax behind human readable properties is A Very Good Thing™

Update doc comments for all items
Organise order of parameters inline with API docs for easier comparisons
…o replace IssueTypeQualifier.PR (which is now marked obsolete)
@ryangribble
Copy link
Contributor Author

  • rebased on latest master
  • renamed NotLabels to ExcludeLabels
  • I also tidied up an inconsistency that was irking me. We refer to pull requests as PullRequest pretty much everywhere in octokit.net - except the IssueTypeQualifier.PR enum value. So to maintain consistent naming and terminology, Ive added IssueTypeQualifier.PullRequest to that enum and flagged the PR value as [Obsolete] so it can be removed sometime down the track 😄

guess I just assumed the api was being dogfooded.

It could well be that the API accepts more options than the doco says, but for now Im thinking of just implementing what the doc says (where labels are the only things that can be excluded).

Although Im thinking perhaps for future proofing (If it does turn out that lots more fields can be negated or even the fact that it's likely in the future more fields would be able to be), I could perhaps move to having a new class to hold all the exclusions (and thus refer to them as normal names like Label).

new SearchIssuesRequest("fish")
{
  Type = IssueTypeQualifier.PullRequest,
  Is = IssueIsQualifier.Merged,
  Exclusions = new SearchIssuesExclusions
  {
      Labels = new[] { "label1", "label2" },
      Author = "M-Zuber" // Docs dont say this is supported but this is where more exclude fields could go if/when added
  }
}

Thoughts? Is collecting any exclusions under a sub class, preferable to ending up with multiple properties like ExcludeLabels ExcludeAuthor ExcludeMentions ExcludeTeam and so on?

@M-Zuber
Copy link
Contributor

M-Zuber commented Mar 30, 2016

Although Im thinking perhaps for future proofing (If it does turn out that lots more fields can be negated or even the fact that it's likely in the future more fields would be able to be), I could perhaps move to having a new class to hold all the exclusions (and thus refer to them as normal names like Label).

That is pretty much what I was trying to say with this ⬇️, and your example implementation is nicer 😄

Edit:
Real bran-fart this time: If a number of filterable items can start with a - (meaning to actually filter you'd need to do a --), maybe make a .Not property that contains a nested SearchIssuesRequest? (I know crazy idea but you only live once or something)

@M-Zuber
Copy link
Contributor

M-Zuber commented Mar 30, 2016

It could well be that the API accepts more options than the doco says, but for now Im thinking of just implementing what the doc says (where labels are the only things that can be excluded).

Sounds good to me, I just wanted to bring up such a possibility

…d all fields that passed tests for properly working exclusions
@ryangribble
Copy link
Contributor Author

OK so ive just pushed up a change that has moved the exclusions fields out into a subclass, as discussed above. So they are now accessed via SearchIssuesRequest.Exclusions

eg

    // Search for PullRequests that dont have "skip-release-notes" label
    var request = new SearchIssuesRequest();
    request.Type = IssueTypeQualifier.PullRequest;
    request.Repos.Add("octokit", "octokit.net");
    request.Exclusions = new SearchIssuesRequestExclusions
    {
        Labels = new[] { "skip-release-notes" }
    };

    var pullRequests = await _gitHubClient.Search.SearchIssues(request);

Regarding which fields are supported, I did some poking at the API and determined that it actually does support quite a few fields in "exclusion" syntax, in addition to the mentioned "label" field.

So the following fields have been implemented in the Exceptions parameters:

  • Author, Assignee, Mentions, Commenter, Involves, State, Labels, Language, Status, Head, Base
    These were all tested and work correctly - integration tests are added to assert this.
    Although not mentioned in the docs (except Labels), these do seem useful (ie to search for items where Assignee is not me, or shiftkey is not mentioned etc)

The following fields were not implemented for exclusion for listed reasons:

  • Type,In,No,Is
    These failed integration tests, API doesnt support negating these
  • Created,Updated,Merged,Closed,Comments
    These date/range fields already support greater/less than and "between" syntax, so having an exclusion option doesnt really make sense so I didnt attempt to implement/test
  • Team
    I didnt get time to find a suitable repo that has teams being @mentioned in issues, to run integration tests against
  • User
    Not tested.
    Does it make sense to do a search for something in all repos EXCEPT those owned by a user or organisation?
  • Repos
    Not tested.
    Does it make sense to do a search in all repos EXCEPT some specified?

Thoughts?
Will definitely need some guidance from @haacked and @shiftkey on this
On the one hand it seems prudent to only implement the mentioned label field for exclusion and "dangerous" to implement something that isnt listed in the API docs. But on the other, being able to exclude by author, target branch etc have real life beneficial use cases, and the API clearly does support them (and the integration tests will detect if they ever cease to work)...

@shiftkey shiftkey self-assigned this Apr 4, 2016
@M-Zuber
Copy link
Contributor

M-Zuber commented Apr 13, 2016

Created,Updated,Merged,Closed,Comments
These date/range fields already support greater/less than and "between" syntax, so having an exclusion option doesnt really make sense so I didnt attempt to implement/test

I would say to yes implement (assuming support) as some users may find it easier conceptually to use .Exclusions (BTW great job on naming)
Might be open to doing a PR into this PR for those fields.

User
Not tested.
Does it make sense to do a search for something in all repos EXCEPT those owned by a user or organisation?
Repos
Not tested.
Does it make sense to do a search in all repos EXCEPT some specified?

I vote for yes as I have done both in the past.

One example that covers both is looking for something .Net Core related - but not in anything from Microsoft & Microsoft related repositories.

@ryangribble
Copy link
Contributor Author

Cool... i didnt actually even test/probe those options to see whether api accepts excluding them or not... i will look into it since those use cases do sound reasonable

@ryangribble
Copy link
Contributor Author

Hey @shiftkey just a reminder that I'm waiting on some input from your good self before I take any next steps 😀

I know you've been on the road etc, hoping that since you've assigned this to yourself it is somewhere on your list to get to 🔮

@shiftkey
Copy link
Member

@ryangribble I haven't forgotten, just been digging myself out from under work since I got back to Oz last week and needed a bit of mundane work to take a break. I'll pick this up tomorrow.

@shiftkey
Copy link
Member

@ryangribble looking over the recent questions:

The following fields were not implemented for exclusion for listed reasons:

  • Type,In,No,Is
    These failed integration tests, API doesnt support negating these

Works for me.

  • Created,Updated,Merged,Closed,Comments
    These date/range fields already support greater/less than and "between" syntax, so having an exclusion option doesnt really make sense so I didnt attempt to implement/test

Yep, I like this too.

  • Team
    I didnt get time to find a suitable repo that has teams being @mentioned in issues, to run integration tests against

This is fine. We'll cross that bridge if we have to.

  • User
    Not tested.
    Does it make sense to do a search for something in all repos EXCEPT those owned by a user or organisation?

Happy to kick this can down the road until someone comes looking for it.

  • Repos
    Not tested.
    Does it make sense to do a search in all repos EXCEPT some specified?

I guess if you wanted to offload more of the search work onto the API. But again, really edge case. 👢 this for now.

@@ -126,4 +126,392 @@ public SearchClientTests()
Assert.NotEmpty(closedIssues);
Assert.NotEmpty(openedIssues);
}

[Fact]
Copy link
Member

Choose a reason for hiding this comment

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

I think these should all be [IntegrationTest] to ensure they only run when you have an integration test account setup.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice spot, thanks

@shiftkey
Copy link
Member

Changes look good, integration tests are working fine on my end.

I'm happy with the direction, happy to give it another look now that I finally got around to answering your questions...

@ryangribble
Copy link
Contributor Author

ryangribble commented Apr 20, 2016

Thanks @shiftkey ill tidy up those few things raised and rebase etc

There was also I guess 2 other things I just wanted a specific 👍 from you on:

I also tidied up an inconsistency that was irking me. We refer to pull requests as PullRequest pretty much everywhere in octokit.net - except the IssueTypeQualifier.PR enum value. So to maintain consistent naming and terminology, Ive added IssueTypeQualifier.PullRequest to that enum and flagged the PR value as [Obsolete] so it can be removed sometime down the track 😄

and

Similarly, the "missing metadata" search option, ive called the class property No to match the query property in API docs no, and gone with IssueNoMetadataQualifier as the enum name. Open to better suggestions...

@shiftkey
Copy link
Member

👍 to PR -> PullRequest - and ❤️ for doing the obsoletion already
👍 for No

{
var allRequest = new SearchIssuesRequest();
allRequest.Repos.Add("octokit", "octokit.net");
allRequest.Type = IssueTypeQualifier.PR;
Copy link
Member

Choose a reason for hiding this comment

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

💄 rename this to .PullRequest

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Lol, nice pickup!

@ryangribble
Copy link
Contributor Author

All feedback addressed, merged latest master and bashed Travis until it finally got a green run!

@shiftkey
Copy link
Member

@ryangribble +:100: nice work!

@shiftkey shiftkey merged commit 7bb751c into octokit:master Apr 29, 2016
@ryangribble ryangribble deleted the search-issues branch August 6, 2016 22:22
@nickfloyd nickfloyd added Type: Feature New feature or request and removed category: feature labels Oct 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Missing options on SearchIssuesRequest
4 participants