0

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).

9
  • It says Python can't find this "g++" command that you want it to calll Commented Jan 18, 2023 at 11:20
  • how can it be???? i follow this way stackoverflow.com/questions/58422804/… Commented Jan 18, 2023 at 11:25
  • 1
    Rather than having your Python script try to compile your C++ code at runtime, I'd suggest just compiling your C++ code separately and having your Python script call the resulting executable. Alternatively, just implement the whole thing in Python; your C++ code isn't doing anything that you couldn't do more easily in Python. Commented Jan 18, 2023 at 15:33
  • 1
    Also, you can do your whole changelist creation and submit process much more easily in a single line: p4.run_submit("-d", "Update information", versionfile). That will automatically create the changelist with the description and file that you provide and submit it all in one shot. Commented Jan 18, 2023 at 15:43
  • 1
    Also: your C++ code is trying to read the depot path of the file as if it were a file on your local disk. That won't work. Commented Jan 18, 2023 at 15:45

1 Answer 1

0

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] + "2023\n" 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.

Sign up to request clarification or add additional context in comments.

2 Comments

thank you very much, it solves my problem. Because I am a newbie with python, I did not know that I can do my work in .cpp with python also. That leads me now to read more about python. :) Have a nice day!
Python replaced C++ as my favorite language about six years ago; it's a bit of a mental shift going from one to the other but things like what you're doing here are just so much easier in Python than in C++ that it's worth putting in the effort to make that shift.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.