Jump to content


P4Python - Create a pending changelist and reference its number

P4Python change

  • Please log in to reply
6 replies to this topic

#1 Gabor Maghera

Gabor Maghera

    Advanced Member

  • Sandbox Beta
  • PipPipPip
  • 192 posts
  • LocationElk Grove, CA

Posted 03 September 2013 - 11:01 PM

The P4Python example has an example for creating a pending change object with the fetch_change() method, which then can be supplied directly to run_submit().  Here it is:

from P4 import P4
p4 = P4()
p4.connect()
change = p4.fetch_change()
# Files were opened elsewhere and we want to
# submit a subset that we already know about.
myfiles = ['//depot/some/path/file1.c', '//depot/some/path/file1.h']
change._description = "My changelist\nSubmitted from P4Python\n"
change._files = myfiles # This attribute takes a Python list
p4.run_submit(change)

I am writing a script which will run some integrations, so updating the change with all the files which have been opened from the integration action is less than optimal.  The set of files which will be opened upon integrating is not as predictable as it is with editing files.  I would rather create an empty changelist and supply its changelist number to the run_integrate.

Here's my attempt at creating a change and accessing its change number:

from P4 import P4
p4 = P4()
p4.connect()
# Fetch change form to create a pending change
change = p4.fetch_change()
print "Printing the _change member of our change after it was fetched"
print "_change = " + change._change
# Save pending change, so it gets a number
change._description = "lorem ipsum"
result = p4.save_change(change).pop(0)
# Print command output
print "Command output: " + result
print "Printing the _change member of our change after it was saved. I'd expect a pending changelist number to be returned here."
print "_change = " + change._change

When I run this script, I get this output:

maghga at RANCAML-1B2DF93 in /Workspace/inform-converted
$ python change_number.py
Printing the _change member of our change after it was fetched
_change = new
Command output: Change 31483 created.
Printing the _change member of our change after it was saved. I'd expect a pending changelist number to be returned here.
_change = new


What surprises me is that after the change object is saved, its _change member (or the value corresponding to the 'Change' key) does not get updated to reflect the changelist number.  I worked around this by extracting the changelist number from the output of the command, but that seems indirect and fragile.  Is there a better way to do this?  Is it possible to supply the change object to the run_integrate command similar to how the example in the documentation does with run_submit?
--
Gabor

#2 P4Matt

P4Matt

    Advanced Member

  • Members
  • PipPipPip
  • 1383 posts

Posted 03 September 2013 - 11:30 PM

P4Python isn't as object-oriented as you're expecting. It's a relatively thin wrapper around the C++ API. When you call save_change you're doing the equivalent of a p4 change -i, with the form being created from the dictionary. As you saw in your example, the returned value is just the text you would get from the command line.

P4Python will let you use the native exception handling, but you'll need to parse the returned value from save_change to get the changelist number to use.

Just imagine you are scripting this from the command line; the process will be exactly the same. You can call 'p4 integrate' with the '-c' flag just like you would from the CLI. It would be something along the lines of "p4.run_integrate("-c", someChange, "//depot/foo/...", "//depot/bar/...")"

#3 David Yerkess

David Yerkess

    Advanced Member

  • Members
  • PipPipPip
  • 78 posts

Posted 12 January 2014 - 02:45 PM

i'm having problems on using P4Python and changelists. I need to create an empty changelist, add some files to be deleted and submit.
Following the classic examples, anything already in the default changelist would also be added.

After reading this post I came up with the following:

changespec = p4.fetch_change()
changespec["Files"] = ['']
changespec[ "Description" ] = "placeholder"
result = p4.save_change( changespec )
results = result[0].split( )
if results[0] == "Change" and results[2] == "created.":
changeId = results[1]
else:
changeId = "0"

Is there any better way to create an empty changelist and get the changelist number?

btw, I think this is my 4th Python script, so if you notice bad stuff, please let me know :P

#4 P4Matt

P4Matt

    Advanced Member

  • Members
  • PipPipPip
  • 1383 posts

Posted 13 January 2014 - 07:01 PM

I think that's as good as it gets. I'l drag P4Sven in here and see if he has any thoughts. He's WAAAAAAY better at Python than myself.

#5 P4Sven

P4Sven

    Advanced Member

  • Staff
  • 32 posts
  • LocationWokingham, UK

Posted 14 January 2014 - 10:14 PM

View PostDavid Yerkess, on 12 January 2014 - 02:45 PM, said:

i'm having problems on using P4Python and changelists. I need to create an empty changelist, add some files to be deleted and submit.
Following the classic examples, anything already in the default changelist would also be added.

After reading this post I came up with the following:

changespec = p4.fetch_change()
changespec["Files"] = ['']
changespec[ "Description" ] = "placeholder"
result = p4.save_change( changespec )
results = result[0].split( )
if results[0] == "Change" and results[2] == "created.":
changeId = results[1]
else:
changeId = "0"

Is there any better way to create an empty changelist and get the changelist number?

btw, I think this is my 4th Python script, so if you notice bad stuff, please let me know :P

Hi David,

If you want to submit the file instead of saving the change (which will still be a pending change),
you need to change the code slightly:

c = p4.fetch_change()
c._files = [ 'file1', 'file2' ]
c._description = "Delete some files"
result = p4.run_submit( c )

If you need the change id first to attach changes to, your code is basically correct:

import re

c = p4.fetch_change()
c._files = [ ]
c._description = "placeholder"
result = p4.save_change( changespec )
r = re.compile("Change ([1-9][0-9]*) created.")

m = r.match(result[0])
changeId = "0"
if m: changeId = m.group(1)

Bear in mind that the change id will most likely get renamed when you finally submit the change.

Cheers

Sven Erik

#6 David Yerkess

David Yerkess

    Advanced Member

  • Members
  • PipPipPip
  • 78 posts

Posted 15 January 2014 - 02:08 PM

Hi Sven,

In this case we want to create a pending changelist from a script (within an editor) and leave it to the user to confirm the submit.

"Bear in mind that the change id will most likely get renamed when you finally submit the change."
This is something I hadn't realized.
You mean I get an Id when I save, let's say 15786 and that remains valid until I submit.
When I submit 15786  is an Id that will never by used and i get a new Id, perhaps 15792, which is the next available Id at that moment?

Anyway as long as I can refer to that Id until it is submitted, that's fine.


Thanks,

David

#7 P4Matt

P4Matt

    Advanced Member

  • Members
  • PipPipPip
  • 1383 posts

Posted 15 January 2014 - 05:44 PM

Everything you said is correct; you can use that number until it is submitted, but it will be renumbered if needs be to make sure submitted changelists represent the order of the commits.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users