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

P4: Add support for json output #38

Open
wants to merge 17 commits into
base: dev
Choose a base branch
from
Open

P4: Add support for json output #38

wants to merge 17 commits into from

Conversation

jasugun
Copy link
Contributor

@jasugun jasugun commented Sep 12, 2022

Simple json output support for p4 commands.
A few handful functions:

  • reconcile current workspace in default cl
  • submit current default cl
  • get a file current revision in the workspace
  • print file content by revision

Simple json output support for p4 commands.
A few handful functions:
- reconcile current workspace in default cl
- submit current default cl
- get a file current revision in the workspace
- print file content by revision
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated
command = self._get_p4_command('submit', '-f', 'revertunchanged')
# descriptions could be too long for perforce limitations
command_length = len(' '.join(command))
perforce_cmd_max_characters_limit = 4096
Copy link
Member

Choose a reason for hiding this comment

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

Is this a real Perforce limitation or a windows commandline one ?
If it's a windows one, you can look into the p4 -x global option which allow providing arg in a file to by-pass this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think the -x option can help us there.
My understanding from reading the docs it taht the p4 -x file_with_stuff.txt submit -m submit -d message would submit the list of files in file_with_stuff. This provides no workarround to the commandline length since we cannot pass the submit description as a file containing the desc.

4096 seems to be a bogus number (got it from pergit), 8191 seems to be the number for a cmd env.
I found no mention of a limiation to the submit description in the perforce documentation however.

What do you think?
Should we try and not limit the message length?
Or maybe expose it as an optionnal param for users of this function to handle?

Copy link
Member

Choose a reason for hiding this comment

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

Just tried with a p4 -x test.txt print
with test.txt:

-q
//path/to/file

and it worked as expected.
I think it's worth looking into and always using a file for submit to avoid escape hell to handle quotes and such in the description text.

nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated
command = self._get_p4_command('submit', '-f', 'revertunchanged')
# descriptions could be too long for perforce limitations
command_length = len(' '.join(command))
perforce_cmd_max_characters_limit = 4096
Copy link
Member

Choose a reason for hiding this comment

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

Just tried with a p4 -x test.txt print
with test.txt:

-q
//path/to/file

and it worked as expected.
I think it's worth looking into and always using a file for submit to avoid escape hell to handle quotes and such in the description text.

nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
nimp/utils/p4.py Outdated Show resolved Hide resolved
# anything under that seems to be fine, whatever happened to this 1024 bytes limit...
# couldn't find more info on this subject in the perforce documentation
description_limit = 120000
submit_args.extend(['-d', description[:description_limit]])
Copy link
Member

Choose a reason for hiding this comment

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

Since the -x arg expect a file with one arg per line.
Should we escape the line endings (\n, \r\n, etc) from the desc?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right.
Removing \n solves the issue. I haven't found way a to esacpe them though, while conserving line breaks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We're now using the utils.p4.submit(description=p4_desc):

  • It should avoid the escaping hell issue by just updating the default changelist spec before submitting.
  • I'll test some commit messages from our monorepo though to be sure nothing weird happens

The p4 print function can output the contents of path/to/pattern*
We want this to be a handy function to print a given file data.
It lets us submit default cl from sractch as well as submitting knwon
changelists (while still being able to update cl desc)
For better compatibility across systems
Any backslash would be interpreted as a regex. Use replacing method
rather than re.sub to preserve initial desc.

def print_file_data(self, file, revision=None):
''' wrapper for p4 print command '''
revision = f"#{revision}" if revision is not None else ''
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 it'd be better to leave this up to called as you can use the @file_rev pattern with print

output = [json.loads(json_element) for json_element in output.splitlines() if json_element]
for output_chunk in output:
if 'data' in output_chunk:
data = output_chunk['data']
Copy link
Member

Choose a reason for hiding this comment

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

Missing the pattern where print split the file content into multiple {'data': ...} blocks for some reason

if use_ztag:
command += ['-z', 'tag']
if use_json_format:
command.append('-Mj')
Copy link
Member

Choose a reason for hiding this comment

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

It's recommended to always use -ztag with -Mj

matches = re.findall(pattern, cl_spec)
if not matches:
# It's possible that there is no following field
pattern = re.compile(rf'{spec_field}:{os.linesep}\t(.*)({os.linesep}{os.linesep})', re.DOTALL)
Copy link
Member

Choose a reason for hiding this comment

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

This could be achieved with a $ to the possible_following_fields like such ({possible_following_fields}|$)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants