1
votes

I'm trying to set up a script to read the output generated by Ant. My context is that I'm working with Salesforce code deployment and retrieval. Those are all done with Ant commands, and the results are usually displayed on the screen (and I can get a return code too).

Getting the code when the build succeeds is easy. However, when the build fails, looks like ant returns two separate 'pieces' of output data. Python's subprocess.check_output gets only the first part, though. And I need the second piece as well, because it is where all the deployment errors are registered.

Examples:

<18digitcodehere> in place of the original code, for security reasons.

Success

[sf:retrieve] Request for a retrieve submitted successfully.
[sf:retrieve] Request ID for the current retrieve task: <18digitcodehere>
[sf:retrieve] Waiting for server to finish processing the request...
[sf:retrieve] Request Status: Pending
[sf:retrieve] Request Status: Succeeded
[sf:retrieve] Finished request <18digitcodehere> successfully.

Failure

First part:

[sf:deploy] Request for a deploy submitted successfully.
[sf:deploy] Request ID for the current deploy task: 0Af1a0000081rk1CAA
[sf:deploy] Waiting for server to finish processing the request...
[sf:deploy] Request Status: Pending
[sf:deploy] Request Status: Pending
[sf:deploy] Request Status: Failed

Second part:

This one contains the errors I want to read. And it is not displayed...

BUILD FAILED                                                                        
<mySystempath>\build.xml:125:                                     
*********** DEPLOYMENT FAILED ***********                                           
Request ID: <18digitcodehere>

All Component Failures:                                                             
1.  labels/CustomLabels.labels (Something) -- Error: Not in package.xml           
2.  labels/CustomLabels.labels (AnotherThing) -- Error: Not in package.xml              
3.  labels/CustomLabels.labels (Thinggy) -- Error: Not in package.xml        
4.  labels/CustomLabels.labels (YetAnotherThing) -- Error: Not in package.xml
...

My current script is something like this:

import subprocess, re

try:
    result = subprocess.check_output(['ant', 'validatedeployment'], universal_newlines=True, shell=True)
    # I can get the code using some regex magic here

except subprocess.CalledProcessError as e:
    # the exception is thrown when the result is different from 0, I believe
    # but here I get the first part of the output, but not the second part

So right now I can get the information if the build succeeds (in which all I need to get is 'success' in the message, basically), and when the build fails I get that it failed, but don't get the real reason why it failed.

Any tips?

1

1 Answers

1
votes

Ant writes error messages to stderr, not stdout.

By default, Python's subprocess.check_output doesn't capture stderr.

To capture stderr, use the following:

subprocess.check_output(
    ['ant', 'validatedeployment'],
    universal_newlines=True,
    shell=True,
    stderr=subprocess.STDOUT # add this line
)