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
- check out the file (in order to edit it)
- call UpdateContent.cpp to change the content of that file
- 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.
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).
CodePudding user response:
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.