RB Patch

Review Request #3440 — Created Oct. 21, 2012 and submitted

Information

RBTools
master

Reviewers

RB Patch will download a patch based off a specific review request ID and apply the patch on the local machine.

TODO:
- I keep getting an error when post-review'ing my mercurial changes (after a hg commit). http://pastie.org/5455551 which prevents me from fully testing Mercurial, though it should work.
- All testing performed on dev server for controlled experiments.

- Tested when user uses a specific revision id (--diff-revision)
- Tested when user specifices own pX argument (--px)

** GIT **
Steps performed:
1. Made a new review request (with commit A)
2. Made some changes to local files
3. Git commit those changes (commit B) and updated the request to create a diff (between B and A)
4. On local drive, reverted to commit A
5. Ran 'rb patch <r>' and viewed the results and affected files.

I did this for a positive and negative test.

** Mercurial **
Similar to Git. I am assuming there's no need for pX logic here, just like Git's apply patch.

** SVN **
Steps performed:
1. Made a new review request (with commit A)
2. Made some changes to local file(s)*
3. post-review a request to create a diff (between B and A)
4. On local drive, reverted to commit A
5. Ran 'rb patch <r>' and viewed the results and affected files.

One or more file changes:
- one file change (/trunk/file1.txt)
- multiple file changes (/trunk/file1.txt and /trunk/file2.txt) and files in different subdirectories (e.g. /trunk/file1.txt, /trunk/a/file2.txt, /trunk/a/b/file3.txt)

Sample directory cases #1:
server: /trunk/a/b/c/file.txt
local checked out: /../b (I just checked out from /trunk/a/b)
patch applied from /b/, /b/c/ <-- all succeeded


Sample directory cases #2:
server: /trunk/a/b/c/file.txt
local checked out: /trunk (I just checked out from /trunk)
patch applied from trunk, /trunk/a/, trunk/a/b/, trunk/a/b/c/ <-- all succeeded

-- 

Tested again with new changes made in rb-general branch (removal of extra options).
Description From Last Updated

Imports should be order like this: Standard Library imports (e.g. os, sys, etc.) ===BLANK LINE=== Third Party imports ===BLANK LINE=== …

SM smacleod

This is imported twice.

SM smacleod

This should be removed when not debugging.

SM smacleod

docstrings should contain a one line summary, followed by a blank line, and then further description.

SM smacleod

You'll want to get rid of these options. The user should be passing the review request id and diff revision …

SM smacleod

You shouldn't need these options for patch.

SM smacleod

This option isn't required. Although, maybe the command should give the option of creating a change list (A different, but …

SM smacleod

This option isn't needed.

SM smacleod

Clear out the options which should be removed, as you remove them.

SM smacleod

This won't be needed for patch.

SM smacleod

This red block means there is trailing whitespace. You should view the diff before publishing and check for these.

SM smacleod

You never initialize self.tool, so this will fail.

SM smacleod

ridorigcwd isn't an option. It looks like you've prepended 'self.options.rid' to the line. Also, this variable (or origcwd) are never …

SM smacleod

The comment explaining why this is set should probably be restored.

SM smacleod

These might be better off factored out, and have server_url passed into the method.

SM smacleod

You don't need this pass here.

SM smacleod

Same thing as my previous comment on docstrings.

SM smacleod

You should consolidate your calls to things like get_review_requests, and git_item. Each of these calls causes a HTTP request to …

SM smacleod

\ isn't needed to continue on the next line when you are inside an open parentheses.

SM smacleod

This return statement is a little cluttered. Could you try and break this out and make it a little more …

SM smacleod

'with' isn't introduced until python 2.5, and we need to support 2.4, so you'll have to change this. Also, rbtools.utils.filesystem …

SM smacleod

You'll want to use rbtools.utils.process.execute here instead of executing the command yourself. for examples, take a look at the ./rbtools/clients/*.py …

SM smacleod

You'll need the tool since you'll be passing the patch to it. The actual code for applying your patch to …

SM smacleod

The patch should be removed, but you'll want to use the temp files stuff I mentioned previously.

SM smacleod

Trailing whitespace.

SM smacleod

Do I have all the ingredients/args to derive the pX number here?

JS jsintal

A more concise way to write this is: p_num = p or self._get_p_number(patch_file)

daviddavid

Leftover debug output?

daviddavid

This should check the return value, no?

daviddavid

Will fix in next submit

JS jsintal

If statements in python don't need parentheses. Also, a good way to check for falsiness is "if not p:"

daviddavid

I think a much better way to do this would be to make execute() return the process return code, and …

daviddavid

I don't think any of these options are necessary

daviddavid

Some trailing whitespace.

daviddavid

I'm not sure if get_root should be in the base class (yet), but this should definitely be moved out into …

daviddavid

No parentheses needed, and can check using "not"

daviddavid

will fix excess space

JS jsintal

Should I make this a helper function?!

JS jsintal

Leftover debug stuff

daviddavid

We should definitely delete it, especially in the success case.

daviddavid

I made a helper in base class to get cookie, is this okay?

JS jsintal

Alphabetical: import re import sys (I had think about it for a sec to make sure, haha)

SL slchen

Should this and other occurrences of this start on the 1st line: """Returns... ?

SL slchen

r before s.

mike_conleymike_conley

This might look better: diffs = self.root_resource \ .get_review_requests() \ .get_item(request_id) \ .get_diffs()

mike_conleymike_conley
SM
  1. Looking over the plan you've laid out in your comments, no issues come to mind.
    
    This diff is including your changes for 'rb diff', which I assume means you've based your branch for 'rb patch' off of your other branch. To fix this, you should run post-review with '--parent=<name_of_rb_diff_branch>' when you post your next diff.
    1. Do I still include the --tracking-branch=api ?
  2. 
      
JS
JS
JS
SM
  1. It appears that the 'rb diff' changes were shown in the latest diff. Make sure to use '--parent=rbdiff' when updating the request so the changes are hidden.
  2. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Show all issues
    Imports should be order like this:
    
    Standard Library imports (e.g. os, sys, etc.)
    ===BLANK LINE===
    Third Party imports
    ===BLANK LINE===
    Local Imports (e.g. 'rbtools...')
    
    Also, imports should be order alphabetically within the three categories.
  3. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
    Show all issues
    This is imported twice.
  4. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
    Show all issues
    This should be removed when not debugging.
  5. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
     
    Show all issues
    docstrings should contain a one line summary, followed by a blank line, and then further description.
  6. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
     
     
     
     
    Show all issues
    You'll want to get rid of these options. The user should be passing the review request id  and diff revision as arguments, not options.
    
    Right now the command would be called like this:
    rb patch -r <request_id> [--diff-revision=<diff_revision>]
    
    We want to call the command like this:
    rb patch <request_id> [<diff_revision>]
  7. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
     
     
     
     
     
     
     
     
     
    Show all issues
    You shouldn't need these options for patch.
  8. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
     
    Show all issues
    This option isn't required. Although, maybe the command should give the option of creating a change list (A different, but similar option).
    1. Could you expound on 'change list' option? 
  9. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
     
     
     
     
     
     
     
     
    Show all issues
    This option isn't needed.
    1. scan_usable_client -> get_repository_info complains about the lack of this option, so I'll include in the next revision for now.
  10. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Show all issues
    Clear out the options which should be removed, as you remove them.
  11. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Show all issues
    This won't be needed for patch.
  12. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
    Show all issues
    This red block means there is trailing whitespace. You should view the diff before publishing and check for these.
  13. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
    Show all issues
    You never initialize self.tool, so this will fail.
  14. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
     
    Yeah, I've been trying to decide how I want to handle this.
  15. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
    Show all issues
    ridorigcwd isn't an option. It looks like you've prepended 'self.options.rid' to the line.
    
    Also, this variable (or origcwd) are never referenced again.
  16. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
    Show all issues
    The comment explaining why this is set should probably be restored.
  17. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
    Show all issues
    These might be better off factored out, and have server_url passed into the method.
  18. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
    Show all issues
    You don't need this pass here.
  19. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
     
    Show all issues
    Same thing as my previous comment on docstrings.
  20. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
    Show all issues
    You should consolidate your calls to things like get_review_requests, and git_item. Each of these calls causes a HTTP request to the server, which is just returning the same data in this case.
  21. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
    Show all issues
    \ isn't needed to continue on the next line when you are inside an open parentheses. 
  22. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
    Show all issues
    This return statement is a little cluttered. Could you try and break this out and make it a little more readable.
  23. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
    Show all issues
    'with' isn't introduced until python 2.5, and we need to support 2.4, so you'll have to change this.
    
    Also, rbtools.utils.filesystem has functions for creating temporary files etc. You should use those instead of just writing in the working directory.
  24. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
     
    Show all issues
    You'll want to use rbtools.utils.process.execute here instead of executing the command yourself.
    
    for examples, take a look at the ./rbtools/clients/*.py files. 
  25. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
    Show all issues
    You'll need the tool since you'll be passing the patch to it. The actual code for applying your patch to the tree should live inside the clients.
    
    The base class will handle the default of calling out to 'patch', but sub classes can override this and use things such as 'git apply'
  26. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
     
    Show all issues
    The patch should be removed, but you'll want to use the temp files stuff I mentioned previously.
  27. rbtools/commands/rbpatch.py (Diff revision 4)
     
     
    Show all issues
    Trailing whitespace.
  28. 
      
JS
JS
JS
JS
david
  1. 
      
  2. rbtools/clients/__init__.py (Diff revision 8)
     
     
     
     
     
    Show all issues
    A more concise way to write this is:
    
    p_num = p or self._get_p_number(patch_file)
  3. rbtools/clients/__init__.py (Diff revision 8)
     
     
     
     
    Show all issues
    Leftover debug output?
    1. I was thinking of letting the user see the command being executed, as well as the output of that command. Let me know if  that's okay.
  4. rbtools/clients/__init__.py (Diff revision 8)
     
     
    Show all issues
    This should check the return value, no?
  5. rbtools/clients/git.py (Diff revision 8)
     
     
    Show all issues
    If statements in python don't need parentheses. Also, a good way to check for falsiness is "if not p:"
  6. rbtools/clients/git.py (Diff revision 8)
     
     
    Show all issues
    I think a much better way to do this would be to make execute() return the process return code, and check if it's non-zero.
    1. execute is returning 'data' which looks like just string data. How can I detect the return code? I'm currently looking at the method in process.py and I do not see the option.
    2. I've set ignore_errors=True in the execute() method, however, I still can't get the return int value. 
      
      Is that value actually 'rc' derived from p.wait() in the process.py:execute code? If that's the case, would I need to return rc as well? I don't want to have to modify the process.py:execute code.
  7. rbtools/commands/rbpatch.py (Diff revision 8)
     
     
     
     
     
     
     
     
    Show all issues
    I don't think any of these options are necessary
    1. Indeed they are not needed, but I've had SCM related code complain about these options not being present. I will need to investigate further.
  8. rbtools/commands/rbpatch.py (Diff revision 8)
     
     
     
     
     
    Show all issues
    Some trailing whitespace.
  9. rbtools/commands/rbpatch.py (Diff revision 8)
     
     
     
    Show all issues
    I'm not sure if get_root should be in the base class (yet), but this should definitely be moved out into a helper function.
    1. I am guessing I should move:
      "os.umask(0077)
      cookie_file = os.path.join(get_home_path(), ".post-review-cookies.txt")"
      to function in the base command class?
  10. rbtools/commands/rbpatch.py (Diff revision 8)
     
     
    Show all issues
    No parentheses needed, and can check using "not"
  11. rbtools/commands/rbpatch.py (Diff revision 8)
     
     
    Show all issues
    Leftover debug stuff
  12. rbtools/commands/rbpatch.py (Diff revision 8)
     
     
    Show all issues
    We should definitely delete it, especially in the success case.
  13. 
      
JS
JS
  1. 
      
  2. rbtools/clients/__init__.py (Diff revisions 8 - 9)
     
     
    Show all issues
    Do I have all the ingredients/args to derive the pX number here?
    1. I think so - though I can't say I'm familiar with too many SCMs outside of SVN, Git and Mercurial.
  3. rbtools/clients/git.py (Diff revisions 8 - 9)
     
     
    Show all issues
    Will fix in next submit
  4. rbtools/commands/rbpatch.py (Diff revisions 8 - 9)
     
     
    Show all issues
    will fix excess space
  5. rbtools/commands/rbpatch.py (Diff revisions 8 - 9)
     
     
    Show all issues
    Should I make this a helper function?!
    1. Naw - at least, IMO, I don't think another level of indirection buys us anything here.
  6. rbtools/commands/__init__.py (Diff revision 9)
     
     
    Show all issues
    I made a helper in base class to get cookie, is this okay?
    1. Sounds like the right call for now. As David points out, we might end up tossing get_root in there as well down the line.
  7. 
      
JS
mike_conley
  1. When do you think you'll be ready to take this out of WIP so that we can do a deep review?
    1. Tomorrow by 5pm for sure, hopefully sooner. 
  2. 
      
JS
JS
JS
JS
JS
JS
SL
  1. 
      
  2. rbtools/clients/__init__.py (Diff revision 16)
     
     
     
    Show all issues
    Alphabetical:
    
    import re
    import sys
    
    
     (I had think about it for a sec to make sure, haha)
  3. rbtools/clients/__init__.py (Diff revision 16)
     
     
     
    Show all issues
    Should this and other occurrences of this start on the 1st line:
    
    """Returns...
    
    ?
    1. It seems like the entire file was written like that. So, I'll stay consistent for now. Hope that's okay.
  4. 
      
JS
JS
JS
mike_conley
  1. This is looking really good - only two nits this time. One more pass, and I think this has my ship-it.
  2. rbtools/clients/__init__.py (Diff revision 19)
     
     
     
    Show all issues
    r before s.
  3. rbtools/commands/rbpatch.py (Diff revision 19)
     
     
     
    Show all issues
    This might look better:
    
    diffs = self.root_resource \
                .get_review_requests() \
                .get_item(request_id) \
                .get_diffs()
  4. 
      
JS
mike_conley
  1. I think I'm good with this. Thanks John!
  2. 
      
JS
SM
  1. Ship It!
  2. 
      
JS
Review request changed
Status:
Completed
Change Summary:
Pushed to api (0c55b87e540689f7c6e188e8796456b5ae169901).