How to call .cpp function inside p4python script?

Question:

My job: I want to create a python script that changes the content of a file automatically and then commit the change in Perforce.

Because the file at first is read-only. So I need to create a python script which

  1. check out the file (in order to edit it)
  2. call UpdateContent.cpp to change the content of that file
  3. commit the change

UpdateContent.cpp

#include <iostream>
#include <string>
#include <stream>
#include <vector>

using namespace std;

const string YearKeyword = "YEAR";
const string ResourceInfoFileName = "//depot/Include/Version.h";

int main()
{   
    fstream ReadFile;
    ReadFile.open(ResourceInfoFileName);
    if (ReadFile.fail())
    {
        cout << "Error opening file: " << ResourceInfoFileName << endl;
        return 1;
    }
    vector<string> lines; // a vector stores content of all the lines of the file
    string line;  // store the content of each line of the file
    while (getline(ReadFile, line))  // read each line of the file
    {
        if (line.find(YearKeyword) != string::npos)
        {
            line.replace(line.size() - 5, 4, "2023");  // update current year
        }
        lines.push_back(line);  // move the content of that line into the vector
    }
    ReadFile.close();

    // after storing the content (after correcting) of the file into vector, we write the content back to the file
    ofstream WriteFile;
    WriteFile.open(ResourceInfoFileName);
    if (WriteFile.fail())
    {
        cout << "Error opening file: " << ResourceInfoFileName << endl;
        return 1;
    }
    for (size_t i = 0; i < lines.size() ; i++)
    {
        WriteFile << lines[i] << endl;
    }
    WriteFile.close();

    return 0;
}

UpdateResource.py

from P4 import P4, P4Exception
import subprocess

p4 = P4()

print('User ', p4.user, ' connecting to ', p4.port)
print('Current workspace is ', p4.client)

try:
    p4.connect()
    versionfile = '//depot/Include/Version.h'
    p4.run( "edit", versionfile )

    cmd = "UpdateContent.cpp"
    subprocess.call(["g++", cmd])   // **THIS IS ERROR POSITION (line 24)**      
    subprocess.call("./UpdateContent.out")

    change = p4.fetch_change()
    change._description = "Update information"
    change._files = versionfile
    p4.run_submit( change )

    p4.disconnect()
    print('Disconnected from server.')
except P4Exception:
    for e in p4.errors:
        print(e)
print('Script finished')

I put both UpdateResource.py and UpdateContent.cpp in the same directory in N drive (N:/ResourceTools/), the file Version.h which needs to be changed is in another directory.
I receive this message when I run the script.

enter image description here

I am newbie with python, where am I wrong?
I guess because of this line const string ResourceInfoFileName = "//depot/Include/Version.h"; in the .cpp file (maybe).

Asked By: gnase

||

Answers:

The error you’re hitting looks like a failure to install g++ on your local system.

From the Perforce/P4Python side, the easiest solution is to ditch the C++ code entirely and instead add the file modification logic to your Python script so you don’t need to compile a C++ app on the side (and worry about the environment your Python script is running in including a suitable compiler). File I/O is really easy in Python so you can do the entire job of your UpdateContent.cpp app in four lines of Python code.

from P4 import P4

depot_path = '//depot/Include/Version.h'

p4 = P4()
print(f'User {p4.user} connecting to {p4.port}')
print(f'Current workspace is {p4.client}')
with p4.connect() as p4:
    local_path = p4.run_have(depot_path)[0]['path']
    p4.run_edit(local_path)

    with open(local_path) as f:
        lines = [line[:-5] + "2023n" if "YEAR" in line else line for line in f]
    with open(local_path, "w") as f:
        f.writelines(lines)

    p4.run_submit('-d', 'Update information', local_path)

print('Disconnected from server.')
print('Script finished')

Note that I copied the implementation of your C++ code that assumes the year is the last four characters of the line that contains the YEAR keyword; you could potentially make this more intelligent very easily with (e.g.) a regex or the str.replace method.

Answered By: Samwise
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.