Enabling rbt stamp for Perforce

Review Request #7153 — Created April 2, 2015 and submitted

Information

RBTools
master
1eff637...

Reviewers

Enable rbt stamp for Perforce

Previously, rbt stamp supported only git. I want to use it for perforce too,
so this change accomplishes that. I've tried to make stamp behave as similarly
as possible to post, with respect to the way a changelist is specified.

For perforce, rbt post is able to "update" an existing review without the -u
flag by trying to post the changelist to a new review. ReviewBoard then returns
an exception stating that the changelist already has a review, and then rbt
updates that review instead. To imitate this behavior in rbt stamp, since I
didn't want to actually have to post a review, I implemented a "guessing
strategy" that queries ReviewBoard for a review request associated with the
particular changelist ID. If one is found, that is the review whose URL is
stamped.

I would also like to add a stamp option directly into rbt post, so that a
review can be posted and stamped in one command (this would also eliminate
ambiguity about which commit the stamp is attached to), but that will come in a
a separate code review. This would also allow for an additional useful guessing
strategy, to find the review request ID by searching the commit message for a
URL.

Tested manually by posting and stamping many draft reviews with Perforce and Git.

Description From Last Updated

Col: 1 E302 expected 2 blank lines, found 1

reviewbotreviewbot

You don't need pass if you have a docstring. We need to fix all these eventually

brenniebrennie

I feel like we should have files=None be an extra key word arg to this function so that we can …

brenniebrennie

Why are you removing this behaviour? Also no blank line after the docstring.

brenniebrennie

You can do git rev-parse <revision-1> <revision-2> and Git will output them on seperate lines. We don't want to be …

brenniebrennie

Blank line between these.

brenniebrennie

Col: 21 E128 continuation line under-indented for visual indent

reviewbotreviewbot

Missing capital and period.

brenniebrennie

Docstrings must be formatted as follows: """Single line summary. Multi line description. """

brenniebrennie

No blank line here.

brenniebrennie

Can you replace this with a raise statement? We are moving away from die going forward.

brenniebrennie

Col: 40 E261 at least two spaces before inline comment

reviewbotreviewbot

Col: 50 E203 whitespace before ':'

reviewbotreviewbot

Blank line between these. Also, we are moving away from die. Please raise an exception instead.

brenniebrennie

Col: 80 E501 line too long (84 > 79 characters)

reviewbotreviewbot

How many colons to we expect to be in tip?

brenniebrennie

The summary should be on the first line. Please use the imperative mood ("Extract ...").

brenniebrennie

Blank line between these.

brenniebrennie

Same question here as the one regarding the number of colons we can have in tip.

brenniebrennie

Col: 80 E501 line too long (81 > 79 characters)

reviewbotreviewbot

Docstrings should be formatted as follows: """Single line summary. Multi-line description """ Also, docstrings should be written in the imperative …

brenniebrennie

Blank line between these.

brenniebrennie

Blank line between these.

brenniebrennie

Can you change this into an elif ?

brenniebrennie

No blank line here.

brenniebrennie

CLN = Change list name? Don't use the acronym here.

brenniebrennie

New line between these.

brenniebrennie

Blank line between these.

brenniebrennie

Col: 80 E501 line too long (82 > 79 characters)

reviewbotreviewbot

Col: 42 W292 no newline at end of file

reviewbotreviewbot

Could you split out the changes to this file into a new review request? The --stamp feature isn't really tied …

brenniebrennie

Col: 21 E128 continuation line under-indented for visual indent

reviewbotreviewbot

Undo this change.

brenniebrennie

Undo this change.

brenniebrennie

Undo this change.

brenniebrennie

undefined name 'get_user'

reviewbotreviewbot

Why this change?

brenniebrennie

undefined name 'get_repository_id'

reviewbotreviewbot

undefined name 'repository_name'

reviewbotreviewbot

Col: 17 E128 continuation line under-indented for visual indent

reviewbotreviewbot

Col: 1 W293 blank line contains whitespace

reviewbotreviewbot

Undo this.

brenniebrennie

Undo this change.

brenniebrennie

Do we really need ALL perforce options in stamp? Why don't we need the options of other SCMs?

brenniebrennie

See previous comments on docstrings. Also, if what we are determining is being returned, just say "Return ..." instead.

brenniebrennie

No blank line here.

brenniebrennie

Can you build this using an {}-expression?

brenniebrennie

Blank line here.

brenniebrennie

Blank line between tehse.

brenniebrennie

Can you add these to the {} expression I asked about above?

brenniebrennie

Col: 80 E501 line too long (80 > 79 characters)

reviewbotreviewbot

Blank line between these.

brenniebrennie

So if we've found multiple review requests, we don't use any of the results? What advantage does this have over …

brenniebrennie

Blank line between these.

brenniebrennie

Col: 13 E128 continuation line under-indented for visual indent

reviewbotreviewbot

Col: 13 E128 continuation line under-indented for visual indent

reviewbotreviewbot

Col: 13 E128 continuation line under-indented for visual indent

reviewbotreviewbot

Col: 13 E128 continuation line under-indented for visual indent

reviewbotreviewbot

Col: 13 E128 continuation line under-indented for visual indent

reviewbotreviewbot

Blank line between these.

brenniebrennie

You're missing the "latest commit" bit.

brenniebrennie

Undo this change.

brenniebrennie

Missing a period.

brenniebrennie

undefined name 'rid'

reviewbotreviewbot

Col: 80 E501 line too long (85 > 79 characters)

reviewbotreviewbot

Col: 1 W293 blank line contains whitespace

reviewbotreviewbot

Col: 34 W292 no newline at end of file

reviewbotreviewbot

Col: 1 E302 expected 2 blank lines, found 1

reviewbotreviewbot

See previous comment about docstrings.

brenniebrennie

No blank line here.

brenniebrennie

Blank line between these.

brenniebrennie

Since we're not expecting to use the STAMP_STRING_FORMAT anywhere else, you can just do a % formatting expression with the …

brenniebrennie

Blank line between these.

brenniebrennie

'get_repository_id' imported but unused

reviewbotreviewbot

'get_user' imported but unused

reviewbotreviewbot

Why do we need the review request and not just the ID? This is to save a round trip right?

brenniebrennie

Col: 38 E127 continuation line over-indented for visual indent

reviewbotreviewbot

Can you format these args better? guess_summary should be on the previous line.

brenniebrennie

"A generic error..."

brenniebrennie

Please ensure these are alphabetized.

brenniebrennie

Period. Perhaps "Query the Review Board server" ?

brenniebrennie

Period.

brenniebrennie

Period.

brenniebrennie

Can we put this in a comment above STMAMP_STRING_FORMAT ?

brenniebrennie

Typo -- compatibility.

gmyersgmyers

"which is delimited"

brenniebrennie

Blank line between these.

brenniebrennie

Missing a period.

brenniebrennie

Since you're only using the tip key of revisions, can we explicitly take the tip (and call it change_id) ?

brenniebrennie

How about "The review request objects returned by this function will only contain some fields, namely:" followed by a list …

brenniebrennie

How about "None will be returned instead." ?

brenniebrennie

Can you combine these two loggin calls?

brenniebrennie

I think it would be easier to read if we didn't use kwargs this way since most of the keys …

brenniebrennie

Missing a period.

brenniebrennie

Can we remove this debugging call since its basically the same as the next one?

brenniebrennie

Can we mention that this matches the tip revision so we know in the debug log what its referring to?

brenniebrennie

This function doesn't just determine the review request ID, but also the URL. Since it is returning both, can we …

brenniebrennie

This should also mention that its returning the URL.

brenniebrennie

Missing a period.

brenniebrennie

You shouldn't seperate sentences in comments onto separate lines.

brenniebrennie

Should we also have a debugging message when we've found it if we're going to print it out when we …

brenniebrennie

Col: 37 E127 continuation line over-indented for visual indent

reviewbotreviewbot

Col: 37 E127 continuation line over-indented for visual indent

reviewbotreviewbot

undefined name 'repository_name'

reviewbotreviewbot

Col: 16 E225 missing whitespace around operator

reviewbotreviewbot

This should use self.git instead of 'git'.

brenniebrennie

revisions should line up with the ' in 'git'

brenniebrennie

input => input_string ?

brenniebrennie

Blank line between end of block and statement.

brenniebrennie

I don't know if this comment is necessary.

brenniebrennie

Blank line between end of block and statement.

brenniebrennie

Can we do from __future__ import unicode_literals here?

brenniebrennie
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
  2. rbtools/clients/errors.py (Diff revision 1)
     
     
    Show all issues
    Col: 1
     E302 expected 2 blank lines, found 1
    
  3. rbtools/clients/git.py (Diff revision 1)
     
     
    Show all issues
    Col: 21
     E128 continuation line under-indented for visual indent
    
  4. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues
    Col: 40
     E261 at least two spaces before inline comment
    
  5. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues
    Col: 50
     E203 whitespace before ':'
    
  6. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues
    Col: 80
     E501 line too long (84 > 79 characters)
    
  7. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues
    Col: 80
     E501 line too long (81 > 79 characters)
    
  8. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues
    Col: 80
     E501 line too long (82 > 79 characters)
    
  9. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues
    Col: 42
     W292 no newline at end of file
    
  10. rbtools/commands/post.py (Diff revision 1)
     
     
    Show all issues
    Col: 21
     E128 continuation line under-indented for visual indent
    
  11. rbtools/commands/post.py (Diff revision 1)
     
     
    Show all issues
     undefined name 'get_user'
    
  12. rbtools/commands/post.py (Diff revision 1)
     
     
    Show all issues
     undefined name 'get_repository_id'
    
  13. rbtools/commands/post.py (Diff revision 1)
     
     
    Show all issues
     undefined name 'repository_name'
    
  14. rbtools/commands/post.py (Diff revision 1)
     
     
    Show all issues
    Col: 17
     E128 continuation line under-indented for visual indent
    
  15. rbtools/commands/post.py (Diff revision 1)
     
     
    Show all issues
    Col: 1
     W293 blank line contains whitespace
    
  16. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues
    Col: 80
     E501 line too long (80 > 79 characters)
    
  17. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues
    Col: 13
     E128 continuation line under-indented for visual indent
    
  18. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues
    Col: 13
     E128 continuation line under-indented for visual indent
    
  19. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues
    Col: 13
     E128 continuation line under-indented for visual indent
    
  20. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues
    Col: 13
     E128 continuation line under-indented for visual indent
    
  21. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues
    Col: 13
     E128 continuation line under-indented for visual indent
    
  22. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues
     undefined name 'rid'
    
  23. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues
    Col: 80
     E501 line too long (85 > 79 characters)
    
  24. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues
    Col: 1
     W293 blank line contains whitespace
    
  25. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues
    Col: 34
     W292 no newline at end of file
    
  26. rbtools/utils/commands.py (Diff revision 1)
     
     
    Show all issues
    Col: 1
     E302 expected 2 blank lines, found 1
    
  27. rbtools/utils/review_request.py (Diff revision 1)
     
     
    Show all issues
     'get_repository_id' imported but unused
    
  28. rbtools/utils/review_request.py (Diff revision 1)
     
     
    Show all issues
     'get_user' imported but unused
    
  29. rbtools/utils/review_request.py (Diff revision 1)
     
     
    Show all issues
    Col: 38
     E127 continuation line over-indented for visual indent
    
  30. 
      
chipx86
  1. Hi Andrew,

    Can you make sure to reuse the same review request for the contribution?

    1. You mean, use 'rbt post -r 7153'? Yes, of course.

      I did notice that if I just use 'rbt post' on git without specifying the review ID, rbt throws an exception rather than automatically re-using the same review. I would have expected it to automatically find the same review request, as it does for perforce, but rbt threw the exception before my change, so I'm considering that to be out of the scope of this code review.

    2. Perforce works a bit differently, since there's a non-changing ID involved. With Git, we don't have that luxury, unfortunately. That's why the behavior is a bit unexpected (when used to the Perforce behavior).

      However, if you use -u, it will try to find the matching review request. That's basically the equivalent of the Perforce behavior, and works for everything that's not Perforce.

      What exception did it throw? We definitely need to take a look at that.

      Thanks!

    3. It's API Error 204: "The commit ID specified has already been used."

      Can a user use -u when uploading the request for the first time as well? If so, then it would be fine, and maybe the error is expected behavior. But it would be nice if ReviewBoard realizes it's the same commit and updates the review anyway.

    4. You're right, we should do that. I'll make a note on that.

      -u doesn't work the first time. That's only used when trying to match an existing review request. We have to basically look up review requests from the user that look like the commit message. The reason we can't use commit SHAs is because they'll change every time you modify the commit, or add a new commit to the branch. There's no identifying information to key the review request off of.

    5. Right, that makes sense. As a user, I would like to set up a command line alias for rbt post with the options I need, and be able to use that all the time, whether or not I've posted a review before.

      Another thing I wanted to do, after I push this change, is to have rbt be able to guess the review ID based on the stamped URL, which might be one way to solve the issue in the git case. But since this talk is going the way of enhancements, perhaps we should take this conversation into another forum :-)

    6. We have command aliases as of RBTools 0.7, so you can check out http://blog.beanbaginc.com/2015/01/19/composing-workflows-using-aliases-in-rbtools/ for more info.

      With regards to feature enhancements, can you file them in the issue tracker on https://code.google.com/p/reviewboard/issues/list ? Thanks!

  2. 
      
DR
brennie
  1. I'd appreciate it if you could split out the --strip option for rbt post to another review request.

    Also, could you please write a more detailed description? Summaries should be in the imperative mood ("Enable rbt stamp...").

  2. rbtools/clients/errors.py (Diff revision 1)
     
     
    Show all issues

    You don't need pass if you have a docstring. We need to fix all these eventually

  3. rbtools/clients/git.py (Diff revision 1)
     
     
     
    Show all issues

    I feel like we should have files=None be an extra key word arg to this function so that we can provide the original behaviour as well.

    1. I'm not sure what the original behavior was, because these arguments were not being used previously; the invocation of this method did not send those parameters, so it's dead code as far as I can tell. It looks like it originally might have just been copy/pasted from create_commit(). The arguments make sense for create_commit(), but not so much for amend_commit() if it's decided that the message is the only thing that can be amended.

      From recent edits to this file, it looks like it was decided that stamping shouldn't work at all if there are local uncommitted changes (at least as far as Git is concerned), so it doesn't make sense to me why we would ever want to add files while amending.

    2. Ok since this isn't being used anywhere, you can ignore this.

  4. rbtools/clients/git.py (Diff revision 1)
     
     
     
     
     
    Show all issues

    Why are you removing this behaviour?

    Also no blank line after the docstring.

  5. rbtools/clients/git.py (Diff revision 1)
     
     
     
     
    Show all issues

    You can do git rev-parse <revision-1> <revision-2> and Git will output them on seperate lines. We don't want to be executing a lot of other processes unless we need to.

    You can give the split_lines=True key word argument to execute to have it split the lines for you.

    1. Cool, that's good to know.

  6. rbtools/clients/git.py (Diff revision 1)
     
     
     
    Show all issues

    Blank line between these.

  7. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues

    Missing capital and period.

  8. rbtools/clients/perforce.py (Diff revision 1)
     
     
     
     
     
    Show all issues

    Docstrings must be formatted as follows:

    """Single line summary.

    Multi line description.
    """

  9. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues

    No blank line here.

  10. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues

    Can you replace this with a raise statement? We are moving away from die going forward.

  11. rbtools/clients/perforce.py (Diff revision 1)
     
     
     
    Show all issues

    Blank line between these.

    Also, we are moving away from die. Please raise an exception instead.

    1. Do you have a suggestion for the type of exception to raise? It doesn't look like any of the existing ones are applicable for a generic perforce exception. Should I just make "PerforceError", or maybe "ScmError"?

    2. I think a general SCMError would be fine in both this and the above case.

  12. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues

    How many colons to we expect to be in tip?

    1. From the various SCM files, I inferred that a colon is the delimiter between a prefix and the actual change number, so I would be surprised/confused if there were more than one. If there are no colons, this statement returns the original string. I changed it here because I wanted to strip prefixes uniformly wherever they occurred.

    2. Is it possible someone could be using colons in their own changesets (so it is something like dev:mychangeset) and then this will come along and do the wrong thing?

      Maybe we should do tip.split(':', 1)[1] ?

    3. Perforce changelists are always numeric (with the exception of the "default" changelist). I'm not aware of a feature for users to be able to name changelists on top of this. There are labels/tags (which I've never used) http://www.perforce.com/perforce/r14.2/manuals/p4guide/chapter.labels.html, but it looks like rbt won't work with these anyway. So I think it's safe to say that the change number will never have a colon, unless Perforce makes radical changes to its overall design.

      In the perforce case, I think it's more likely that a prefix would contain another colon, but given that the colon is the de facto delimiter, I find that quite unlikely as well. If we want to encourage a standard way of stripping prefixes across SCMs though, then your suggestion will be equivalent in this case and more reliable in the general case.

  13. rbtools/clients/perforce.py (Diff revision 1)
     
     
     
    Show all issues

    The summary should be on the first line.

    Please use the imperative mood ("Extract ...").

  14. rbtools/clients/perforce.py (Diff revision 1)
     
     
     
    Show all issues

    Blank line between these.

  15. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues

    Same question here as the one regarding the number of colons we can have in tip.

    1. 0 or 1 (see above)

    2. See my above comment.

  16. rbtools/clients/perforce.py (Diff revision 1)
     
     
     
     
    Show all issues

    Docstrings should be formatted as follows:

    """Single line summary.
    
    Multi-line description
    """
    

    Also, docstrings should be written in the imperative mood. For example, "Replace the current description in the specified changeset."

  17. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues

    Blank line between these.

  18. rbtools/clients/perforce.py (Diff revision 1)
     
     
     
    Show all issues

    Blank line between these.

  19. rbtools/clients/perforce.py (Diff revision 1)
     
     
     
    Show all issues

    Can you change this into an elif ?

    1. It makes more sense to me as a reader to keep it this way. I was conceptualizing that there are two "modes" of scanning the document: either copying line-for-line, or ignoring the part that is the old description. What do you think?

    2. Its just a style thing and it doesn't really matter. it is up to you.

    3. I'll leave it this way. I did add a couple more comments to make it easier for readers to follow (and fixed an edge case in the logic as well).

  20. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues

    No blank line here.

  21. rbtools/clients/perforce.py (Diff revision 1)
     
     
    Show all issues

    CLN = Change list name? Don't use the acronym here.

    1. You know, it's used so often that I never realized it's not an official acronym. I think it means changelist number, but as is the case with most acronyms, half the time people just mean changelist. I've changed this instance, but note that this is far from the only time the term is used in this file.

  22. rbtools/clients/perforce.py (Diff revision 1)
     
     
     
    Show all issues

    New line between these.

  23. rbtools/clients/perforce.py (Diff revision 1)
     
     
     
    Show all issues

    Blank line between these.

  24. rbtools/commands/post.py (Diff revision 1)
     
     
     
     
     
     
     
     
    Show all issues

    Could you split out the changes to this file into a new review request? The --stamp feature isn't really tied to the Perforce changes. It will make both features easier to review.

    1. Will do. Based on the other comments, it seems like there might be more subtleties in getting this to behave nicely with the different SCMs.

  25. rbtools/commands/post.py (Diff revision 1)
     
     
    Show all issues

    Undo this change.

    1. Can you suggest a better name? This confused me when I was reading the code, because it's doing more than merely "checking" (which, to me, implies a read-only thing). It's actually overwriting some values, and it would be nice if that's readily apparent from the method name.

    2. I'd leave it alone for now. If you want, you can make changes like this in another review request.

    3. Sure, that's reasonable.

  26. rbtools/commands/post.py (Diff revision 1)
     
     
    Show all issues

    Undo this change.

  27. rbtools/commands/post.py (Diff revision 1)
     
     
    Show all issues

    Undo this change.

  28. rbtools/commands/post.py (Diff revision 1)
     
     
     
     
     
     
     
    Show all issues

    Why this change?

    1. Since get_user and get_repository_id involve API calls, I wanted to avoid doing them multiple times. My implementation of determine_review_request_id (inside stamp.py) calls the API's get_review_requests multiple times (some inside guess_existing_review_request and some not). Moving these functions out of guess_existing_review_request removed the "need" for them to be invoked twice.

  29. rbtools/commands/post.py (Diff revision 1)
     
     
    Show all issues

    Undo this.

  30. rbtools/commands/post.py (Diff revision 1)
     
     
    Show all issues

    Undo this change.

  31. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues

    Do we really need ALL perforce options in stamp? Why don't we need the options of other SCMs?

    1. In this case, rbt stamp supports only git and perforce, so there's no need to have the options for other SCMs available until someone extends the command's functionality to those SCMs.

      Regarding the specific options to supply, they appear to be global options pertaining to the setup of the perforce client. If users want a clear usage pattern among the different commands in rbt, it would make sense to make all the perforce options available in all the commands that interact with perforce. Since they are accessed in the run_p4 method itself, it seems likely that some users will want/need to have them set up for all their interactions with perforce.

    2. Okay, sounds good to me since they are required for interacting with p4.

  32. rbtools/commands/stamp.py (Diff revision 1)
     
     
     
     
     
     
    Show all issues

    See previous comments on docstrings.

    Also, if what we are determining is being returned, just say "Return ..." instead.

  33. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues

    No blank line here.

  34. rbtools/commands/stamp.py (Diff revision 1)
     
     
     
     
     
    Show all issues

    Can you build this using an {}-expression?

    1. Sure. I'll still have to insert changenum using bracket notation though, since it's not there in all cases.

    2. Yes thats fine.

  35. rbtools/commands/stamp.py (Diff revision 1)
     
     
     
    Show all issues

    Blank line here.

  36. rbtools/commands/stamp.py (Diff revision 1)
     
     
     
    Show all issues

    Blank line between tehse.

  37. rbtools/commands/stamp.py (Diff revision 1)
     
     
     
    Show all issues

    Can you add these to the {} expression I asked about above?

  38. rbtools/commands/stamp.py (Diff revision 1)
     
     
     
    Show all issues

    Blank line between these.

  39. rbtools/commands/stamp.py (Diff revision 1)
     
     
     
    Show all issues

    So if we've found multiple review requests, we don't use any of the results? What advantage does this have over the behaviour of the -u parameter we use elsewhere that will list out the review request it finds and ask if they are the correct one?

    Can the behaviour of the -u flag be reused?

    1. According to my reading of the ReviewBoard docs, there will never be more than one review request associated with a particular commit ID. So if there's not one, there's zero, and we can fall back to the next guessing strategy.

      Since I only use rbt with perforce, I wasn't acquainted with the -u option until very recently. More importantly, at my workplace, we invoke rbt directly from P4V (the perforce GUI), so there's no command line to let us choose the correct review anyway. The addition of this guessing strategy might actually break the git behavior; maybe it should be attempted only if the repository supports changesets?

      I'd really like to see "search for the stamp URL in the change description" added as a guessing strategy, but that could be a significant behavioral change so I didn't do it here.

    2. Ah yes. I missed the commit_id bit. There definitely is only going to be one review request at most.

      However, I think its a good idea to make our assumptions explicit with an assert, e.g.

      if review_requests:
          assert len(review_requests) == 1
      
          # ...
      

      We definitely don't want to break any existing behaviour. Updates to the guessing should probably be done in another review request, since they're a big change on their own.

    3. I want to keep the change-based guessing for perforce, because it keeps the behavior consistent with rbt post for perforce (not using -u). ReviewBoard finds the review ID corresponding to the specific changelist, and then automatically updates it. In the same way, rbt stamp will automatically find the same review request and automatically stamp.

      I've placed this feature behind a "repository_info.supports_changesets" flag, however, so the git behavior will remain the same.

    4. That seems OK.

  40. rbtools/commands/stamp.py (Diff revision 1)
     
     
     
    Show all issues

    Blank line between these.

  41. rbtools/commands/stamp.py (Diff revision 1)
     
     
     
    Show all issues

    Blank line between these.

  42. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues

    You're missing the "latest commit" bit.

    1. I took that out on purpose, because in Perforce there can be multiple pending changesets and they don't have a relative ordering. A changelist number MUST be specified, otherwise we can't infer which one is "latest".

      I'm also curious about the git implementation, which concatenates the messages from multiple commits and writes them (along with the review URL) all to the latest commit. I could see this getting confusing when rebasing/squashing.

    2. In this case the docstring has to be reworded. Perhaps "a commit message" instead of "the commit message" ?

    3. "a commit message" is vague, but this is a one-liner and it's well-documented at the class level, so I think we can get away with it.

  43. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues

    Undo this change.

  44. rbtools/commands/stamp.py (Diff revision 1)
     
     
    Show all issues

    Missing a period.

  45. rbtools/utils/commands.py (Diff revision 1)
     
     
    Show all issues

    See previous comment about docstrings.

  46. rbtools/utils/commands.py (Diff revision 1)
     
     
    Show all issues

    No blank line here.

  47. rbtools/utils/commands.py (Diff revision 1)
     
     
     
    Show all issues

    Blank line between these.

  48. rbtools/utils/commands.py (Diff revision 1)
     
     
     
     
     
    Show all issues

    Since we're not expecting to use the STAMP_STRING_FORMAT anywhere else, you can just do a % formatting expression with the "Reviewed at ..." string in there.

    1. Yep. I was using it in two places before, but then I wasn't. Note that I changed the way it checks to see if the stamp is already there. Before, it looked for the stamp string, but now it looks for the URL. This has the benefit (in my opinion) of allowing the new URL to be stamped if the code review is changed for some reason.

    2. If more functionality is added in the future surrounding the stamp string, such as guessing the review request based on the stamped URL, it would make sense to pull this back out into a constant. It also makes it more apparent that it's special and shouldn't ever be modified (then old commits would have a different stamp string than new ones, which could cause compatibility issues).

  49. rbtools/utils/commands.py (Diff revision 1)
     
     
     
    Show all issues

    Blank line between these.

  50. rbtools/utils/review_request.py (Diff revision 1)
     
     
     
    Show all issues

    Why do we need the review request and not just the ID? This is to save a round trip right?

    1. Yeah. In stamp, I'm returning the ID and the URL, otherwise I would have to call reviewboard again separately to get the URL.

      I am somewhat uncertain about returning the entire "review request" object though, when not all the fields will actually be filled out (callers might want to grab more info out of it and not be able to). Do you think it's good enough to mention the limitation in the docstring?

    2. Yeah this is some good info for it!

      Perhaps this should fill out all fields by default and you can request fields via an extra request_fields paramter that defaults to None ?

    3. I'm worried about that too: the method requires a certain base set (id, summary, description, draft) to do its own internal guessing, so we shouldn't let the caller specify a smaller set of fields than that. We could have guess_existing_review_request() take the union of those specified by the caller and those it always needs, but that leads to a more confusing implementation/behavior that I'd rather avoid. In this case I'd prefer to just make a note in the documentation that only the specific fields will be present.

      I'm specifically not mentioning in the docstring which fields are returned, because it offers the opportunity for the documentation to become out of sync with the code, which isn't much a concern in this case because it's an internal function.

  51. rbtools/utils/review_request.py (Diff revision 1)
     
     
     
    Show all issues

    Can you format these args better? guess_summary should be on the previous line.

  52. 
      
DR
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
  2. 
      
DR
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
  2. 
      
gmyers
  1. 
      
  2. rbtools/clients/__init__.py (Diff revision 3)
     
     
    Show all issues
    Typo --  compatibility.
    1. Good catch; thanks.

  3. 
      
DR
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
  2. 
      
brennie
  1. 
      
  2. rbtools/clients/errors.py (Diff revisions 2 - 4)
     
     
    Show all issues

    "A generic error..."

  3. rbtools/clients/perforce.py (Diff revisions 2 - 4)
     
     
     
     
     
     
    Show all issues

    Please ensure these are alphabetized.

    1. Aha. I was trying to match them to the order they appeared in errors.py.

  4. rbtools/commands/stamp.py (Diff revisions 2 - 4)
     
     
    Show all issues

    Period.

    Perhaps "Query the Review Board server" ?

    1. I was trying to keep this under 80 characters :) To that end, I've changed it to """Ask ReviewBoard for the review request ID for the tip revision."""

  5. rbtools/commands/stamp.py (Diff revisions 2 - 4)
     
     
    Show all issues

    Period.

  6. rbtools/commands/stamp.py (Diff revisions 2 - 4)
     
     
    Show all issues

    Period.

  7. rbtools/utils/commands.py (Diff revisions 2 - 4)
     
     
     
     
     
     
    Show all issues

    Can we put this in a comment above STMAMP_STRING_FORMAT ?

    1. Yeah, this would be best as a comment maybe in the form of:

      #: One-line summary
      #:
      #: Multi-line description
      

      This is, for Sphinx (our doc builder), the equivalent of a docstring below, but is a lot less confusing (I've always despised this about Python).

      Along with that, the wording needs some changes. We don't prefix summaries with "This is the ..." or anything like that, as that part is implied. rbt stamp is just one of the users of this; rbt patch and rbt land are others.

      Also, the RBTools compatibility isn't the issue, so much as the Review Board compatibility (Review Board's post-commit hooks for repositories expect "Reviewed at").

      Instead, how about:

      #: The format string used to specify a URL to a review request in commits.
      #:
      #: Commands that prepare a commit message for pushing, such as rbt stamp,
      #: rbt patch, and rbt land, must use this format to indicate the URL to the
      #: matching review request. Review Board will parse the commit messages when
      #: executing any post-receive hooks, looking for this string and a valid URL.
      

      Also, constants should go at the top, before classes and functions.

    2. Thanks for the explanation. I wanted to keep this constant here next to the function in which it's used, but over time that could diverge. I've replaced with your wording and moved to the top.

  8. 
      
DR
reviewbot
  1. Tool: PEP8 Style Checker
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
    
    Tool: Pyflakes
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
  2. 
      
DR
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
  2. 
      
DR
  1. I'm not sure what happened in the diff generation... I used the tip of mainline (plus my changes) to post the review. I have been rebasing/squashing my commits on a regular-ish basis between postings of the review, so hopefully this won't break the diffing/posting functionality.

    1. There is some wonkiness when viewing an interdiff between two revisions where the newer revision has been rebased. It is a known bug.

  2. 
      
brennie
  1. 
      
  2. rbtools/clients/perforce.py (Diff revisions 4 - 6)
     
     
    Show all issues

    "which is delimited"

  3. rbtools/clients/perforce.py (Diff revisions 4 - 6)
     
     
     
    Show all issues

    Blank line between these.

  4. rbtools/clients/perforce.py (Diff revisions 4 - 6)
     
     
    Show all issues

    Missing a period.

  5. rbtools/utils/review_request.py (Diff revisions 4 - 6)
     
     
    Show all issues

    Since you're only using the tip key of revisions, can we explicitly take the tip (and call it change_id) ?

    1. I like taking revisions because it makes it clear (by convention of the revisions variable being used throughout the project) what format we're expecting. Otherwise it would have to be explained that change_id is derived from revisions.tip, so why don't we just take revisions? Also, if we ever do want to look at base, we already have it.

  6. rbtools/utils/review_request.py (Diff revisions 4 - 6)
     
     
     
    Show all issues

    How about

    "The review request objects returned by this function will only contain some fields, namely:"

    followed by a list of the fields, either inline or in a reST list.

    1. What is a reST list?

      I would like to list the fields, but I would also not like to have the documentation risk becoming out of sync with the implementation. I thought of saying "will contain only some fields, specified by the only_fields variable", and then perhaps putting only_fields clearly at the top of the code.

    2. A re-structured list is formatted as follows:

      * item
      * item
      * item
      
    3. I've done the same for guess_existing_review_request and find_review_request_by_change_id, defining only_fields prominently at the top of the function and updating the documentation to note that this variable specifies the fields that will be returned.

      If you would prefer I duplicate the list in the documentation, let me know and I'll change it.

  7. rbtools/utils/review_request.py (Diff revisions 4 - 6)
     
     
    Show all issues

    How about "None will be returned instead." ?

    1. I thought the docstring was supposed to be written in imperative voice?

    2. Only the summary line, as far as I know.

    3. Changed to "None will be returned instead."

  8. rbtools/utils/review_request.py (Diff revisions 4 - 6)
     
     
     
     
    Show all issues

    Can you combine these two loggin calls?

  9. rbtools/utils/review_request.py (Diff revisions 4 - 6)
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Show all issues

    I think it would be easier to read if we didn't use kwargs this way since most of the keys in it will be passed no matter what. Since changenum is the only optional argument, can we do something like the following:

    optional_args = {}
    
    if change_id.isdigit():
        # ...
        optional_args['changenum'] = int(change_id)
    
    review_requests = api_root.get_review_requests(repository=repository_id,
                                                   from_user=user.username,
                                                   #...,
                                                   **optional_args)
    
  10. rbtools/utils/review_request.py (Diff revisions 4 - 6)
     
     
    Show all issues

    Missing a period.

  11. rbtools/utils/review_request.py (Diff revisions 4 - 6)
     
     
     
     
     
    Show all issues

    Can we remove this debugging call since its basically the same as the next one?

    1. Removed the second one, and changed the first to this:
      logging.debug('Found review request %s with status %s' % (review_request.id, status))

      I'm assuming we're not ever going to have a review request without an ID, unless something is wrong enough that we don't care if the program doesn't work anymore.

  12. rbtools/utils/review_request.py (Diff revisions 4 - 6)
     
     
    Show all issues

    Can we mention that this matches the tip revision so we know in the debug log what its referring to?

    1. Is that not apparent enough from the previous debug message that prints out the identity of the tip revision?

    2. Changed the log messages to make things more obvious, when viewed together.

  13. rbtools/commands/stamp.py (Diff revision 6)
     
     
    Show all issues

    This function doesn't just determine the review request ID, but also the URL. Since it is returning both, can we call it determine_review_request_id_and_url or determine_review_request ?

    1. Good call. Changed to determine_review_request.

  14. rbtools/commands/stamp.py (Diff revision 6)
     
     
    Show all issues

    This should also mention that its returning the URL.

    1. Removed the word "ID" from the single-line description. The multiline description details the tuple that is returned.

  15. rbtools/commands/stamp.py (Diff revision 6)
     
     
    Show all issues

    Missing a period.

  16. rbtools/commands/stamp.py (Diff revision 6)
     
     
     
    Show all issues

    You shouldn't seperate sentences in comments onto separate lines.

  17. rbtools/commands/stamp.py (Diff revision 6)
     
     
     
    Show all issues

    Should we also have a debugging message when we've found it if we're going to print it out when we attempt to find it?

    1. Yeah, good idea.

  18. 
      
DR
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
  2. rbtools/commands/stamp.py (Diff revision 7)
     
     
    Show all issues
    Col: 37
     E127 continuation line over-indented for visual indent
    
  3. 
      
brennie
  1. You're going to want to rebase this off of the latest master becuase of the changes to errors.py.

  2. 
      
DR
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
  2. rbtools/utils/review_request.py (Diff revision 8)
     
     
    Show all issues
     undefined name 'repository_name'
    
  3. 
      
reviewbot
  1. Tool: PEP8 Style Checker
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
  2. rbtools/commands/stamp.py (Diff revision 8)
     
     
    Show all issues
    Col: 37
     E127 continuation line over-indented for visual indent
    
  3. rbtools/utils/review_request.py (Diff revision 8)
     
     
    Show all issues
    Col: 16
     E225 missing whitespace around operator
    
  4. 
      
DR
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
  2. 
      
DR
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
  2. 
      
brennie
  1. Just a reminder to please mark old issues as dropped or fixed.

    1. I was hoping for you to comment on the two old ones I left open. If you're okay with my changes, then you can mark them as you feel appropriate.

  2. rbtools/clients/git.py (Diff revision 10)
     
     
    Show all issues

    This should use self.git instead of 'git'.

    1. I changed the two in my function. There are a lot of other functions that still execute(['git']).

  3. rbtools/clients/git.py (Diff revision 10)
     
     
    Show all issues

    revisions should line up with the ' in 'git'

  4. rbtools/clients/perforce.py (Diff revision 10)
     
     
    Show all issues

    input => input_string ?

  5. rbtools/clients/perforce.py (Diff revision 10)
     
     
     
    Show all issues

    Blank line between end of block and statement.

  6. rbtools/clients/perforce.py (Diff revision 10)
     
     
    Show all issues

    I don't know if this comment is necessary.

    1. It was helpful to me to know that communicate sets the returncode, which is something that's not necessarily intuitive if you're not familiar with Popen.

  7. rbtools/clients/perforce.py (Diff revision 10)
     
     
     
    Show all issues

    Blank line between end of block and statement.

  8. rbtools/commands/stamp.py (Diff revision 10)
     
     
    Show all issues

    Can we do from __future__ import unicode_literals here?

    1. Would that actively solve a problem in the scope of this change?

  9. 
      
DR
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        rbtools/commands/land.py
        rbtools/utils/commands.py
        rbtools/commands/stamp.py
        rbtools/commands/post.py
        rbtools/clients/__init__.py
        rbtools/clients/git.py
        rbtools/clients/perforce.py
        rbtools/utils/review_request.py
        rbtools/clients/errors.py
    
    
  2. 
      
brennie
  1. This all looks good to me, but I'm going to wait for someone more familiar with Perforce to sign off on it before landing it.

    1. Cool, thanks guys! Now how do I push this thing? I haven't forked the RBTools repository to my own Github account, although I can fork and push my change there if that's where you need to pull from.

    2. I'm working on landing it right now. You don't need to do anything.

  2. 
      
david
  1. Ship It!
  2. 
      
DR
Review request changed
Status:
Completed
Change Summary:
Pushed to release-0.7.x (f0dfac5)