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

gnase
  • 580
  • 2
  • 10
  • 25
  • It says Python can't find this "g++" command that you want it to calll – user253751 Jan 18 '23 at 11:20
  • how can it be???? i follow this way https://stackoverflow.com/questions/58422804/how-can-i-run-a-hello-world-c-code-using-python – gnase Jan 18 '23 at 11:25
  • do you understand how the code works or did you copy-paste it? – user253751 Jan 18 '23 at 11:27
  • To tell the truth, I do not really understand the code. I guess `subprocess.call(["g++", cmd])` will compile my cpp program, and then `subprocess.call("./UpdateContent.out")` will run it. – gnase Jan 18 '23 at 11:30
  • the first step would be to understand it – user253751 Jan 18 '23 at 11:30
  • If I am wrong, could you give me a hint how I can do it? – gnase Jan 18 '23 at 11:32
  • 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. – Samwise Jan 18 '23 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. – Samwise Jan 18 '23 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. – Samwise Jan 18 '23 at 15:45

1 Answers1

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.

Samwise
  • 68,105
  • 3
  • 30
  • 44
  • 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! – gnase Jan 18 '23 at 16:45
  • 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. – Samwise Jan 18 '23 at 18:40