Skip to content

Commit d6838f5

Browse files
authored
Merge pull request #280 from jakub-nt/CFE-4560
CFE-4560: Implement Step 3 of `cfbs convert`
2 parents 162a41d + 945b643 commit d6838f5

File tree

7 files changed

+319
-153
lines changed

7 files changed

+319
-153
lines changed

cfbs/commands.py

Lines changed: 117 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,15 @@ def search_command(terms: List[str]):
6060
from cfbs.cfbs_json import CFBSJson
6161
from cfbs.cfbs_types import CFBSCommandExitCode, CFBSCommandGitResult
6262
from cfbs.masterfiles.analyze import most_relevant_version
63+
from cfbs.masterfiles.download import download_single_version
6364
from cfbs.updates import ModuleUpdates, update_module
6465
from cfbs.utils import (
6566
CFBSNetworkError,
6667
CFBSUserError,
6768
CFBSValidationError,
69+
cfbs_dir,
6870
cfbs_filename,
71+
display_diff,
6972
is_cfbs_repo,
7073
read_json,
7174
CFBSExitError,
@@ -1131,7 +1134,7 @@ def analyze_command(
11311134
@cfbs_command("convert")
11321135
def convert_command(non_interactive=False, offline=False):
11331136
def cfbs_convert_cleanup():
1134-
os.unlink(cfbs_filename())
1137+
rm(cfbs_filename(), missing_ok=True)
11351138
rm(".git", missing_ok=True)
11361139

11371140
def cfbs_convert_git_commit(
@@ -1172,14 +1175,18 @@ def cfbs_convert_git_commit(
11721175
)
11731176

11741177
print("Analyzing '" + path_string + "'...")
1175-
analyzed_files, _ = analyze_policyset(
1176-
path=dir_name,
1177-
is_parentpath=False,
1178-
reference_version=None,
1179-
masterfiles_dir=dir_name,
1180-
ignored_path_components=None,
1181-
offline=offline,
1182-
)
1178+
try:
1179+
analyzed_files, _ = analyze_policyset(
1180+
path=dir_name,
1181+
is_parentpath=False,
1182+
reference_version=None,
1183+
masterfiles_dir=dir_name,
1184+
ignored_path_components=None,
1185+
offline=offline,
1186+
)
1187+
except:
1188+
print("Analyzing the policy set failed, aborting conversion.")
1189+
raise
11831190

11841191
current_index = CFBSConfig.get_instance().index
11851192
default_version = current_index.get_module_object("masterfiles")["version"]
@@ -1205,7 +1212,20 @@ def cfbs_convert_git_commit(
12051212
print("Initializing a new CFBS project...")
12061213
# since there should be no other files than the masterfiles-name directory, there shouldn't be a .git directory
12071214
assert not is_git_repo()
1208-
r = init_command(masterfiles="no", non_interactive=non_interactive, use_git=True)
1215+
try:
1216+
r = init_command(
1217+
masterfiles="no", non_interactive=non_interactive, use_git=True
1218+
)
1219+
except CFBSGitError:
1220+
cfbs_convert_cleanup()
1221+
print(
1222+
"A Git operation failed during initialization of a new CFBS project, aborting conversion."
1223+
)
1224+
raise
1225+
except:
1226+
print("Initializing a new CFBS project failed, aborting conversion.")
1227+
cfbs_convert_cleanup()
1228+
raise
12091229
# the cfbs-init should've created a Git repository
12101230
assert is_git_repo()
12111231
if r != 0:
@@ -1215,19 +1235,33 @@ def cfbs_convert_git_commit(
12151235

12161236
print("Adding masterfiles %s to the project..." % masterfiles_version)
12171237
masterfiles_to_add = ["masterfiles@%s" % masterfiles_version]
1218-
r = add_command(masterfiles_to_add, added_by="cfbs convert")
1238+
try:
1239+
r = add_command(masterfiles_to_add, added_by="cfbs convert")
1240+
except:
1241+
print(
1242+
"Adding the masterfiles module to the project failed, aborting conversion."
1243+
)
1244+
cfbs_convert_cleanup()
1245+
raise
12191246
if r != 0:
1220-
print("Adding the masterfiles module failed, aborting conversion.")
1247+
print(
1248+
"Adding the masterfiles module to the project failed, aborting conversion."
1249+
)
12211250
cfbs_convert_cleanup()
12221251
return r
12231252

12241253
print("Adding the policy files...")
12251254
local_module_to_add = [path_string]
1226-
r = add_command(
1227-
local_module_to_add,
1228-
added_by="cfbs convert",
1229-
explicit_build_steps=["copy ./ ./"],
1230-
)
1255+
try:
1256+
r = add_command(
1257+
local_module_to_add,
1258+
added_by="cfbs convert",
1259+
explicit_build_steps=["copy ./ ./"],
1260+
)
1261+
except:
1262+
print("Adding the policy files module failed, aborting conversion.")
1263+
cfbs_convert_cleanup()
1264+
raise
12311265
if r != 0:
12321266
print("Adding the policy files module failed, aborting conversion.")
12331267
cfbs_convert_cleanup()
@@ -1285,7 +1319,7 @@ def cfbs_convert_git_commit(
12851319
if prompt_user_yesno(
12861320
non_interactive, "Delete files from other versions? (Recommended)"
12871321
):
1288-
print("Deleting %s files." % len(files_to_delete))
1322+
print("Deleting %s files..." % len(files_to_delete))
12891323
for file_d in files_to_delete:
12901324
rm(os.path.join(dir_name, file_d))
12911325

@@ -1299,7 +1333,71 @@ def cfbs_convert_git_commit(
12991333
print(
13001334
"The next conversion step is to handle files which have custom modifications."
13011335
)
1302-
print("This is not implemented yet.")
1336+
if not prompt_user_yesno(non_interactive, "Do you want to continue?"):
1337+
raise CFBSExitError("User did not proceed, exiting.")
1338+
print("The following files have custom modifications:")
1339+
modified_files = analyzed_files.modified
1340+
for modified_file in modified_files:
1341+
print("-", modified_file)
1342+
for i, modified_file in enumerate(modified_files, start=1):
1343+
# program failures in the middle of this loop would be very user-unfriendly,
1344+
# so we will catch exceptions and continue the conversion when handling errors
1345+
print("\nFile", i, "diff -", modified_file + ":")
1346+
mpf_dir_path = os.path.join(cfbs_dir(), "masterfiles")
1347+
mpf_version_dir_path = os.path.join(
1348+
mpf_dir_path, masterfiles_version, "tarball", "masterfiles"
1349+
)
1350+
mpf_filepath = os.path.join(mpf_version_dir_path, modified_file)
1351+
display_diffs = True
1352+
if not os.path.exists(mpf_version_dir_path):
1353+
try:
1354+
download_single_version(mpf_dir_path, masterfiles_version)
1355+
except Exception as e:
1356+
print(
1357+
"Downloading original masterfiles failed (%s), continuing conversion without displaying file diffs."
1358+
% str(e)
1359+
)
1360+
display_diffs = False
1361+
if display_diffs:
1362+
try:
1363+
display_diff(mpf_filepath, os.path.join(dir_name, modified_file))
1364+
except:
1365+
log.warning(
1366+
"Displaying a diff between your file and the default file failed, continuing without displaying a diff..."
1367+
)
1368+
if i == 1:
1369+
if display_diffs:
1370+
print(
1371+
"Above you can see the differences between your file and the default file."
1372+
)
1373+
print(
1374+
"As much as possible, we recommend getting rid of these custom modifications."
1375+
)
1376+
print(
1377+
"Usually, the same thing can be achieved by adding a variable to def.json, or through adding your own policy file (inside 'services/')."
1378+
)
1379+
prompt_str = "\nChoose an option:\n"
1380+
prompt_str += "1) Drop modifications - They are not important, or can be achieved in another way.\n"
1381+
prompt_str += "2) Keep modified file - File is kept as is, and can be handled later. Can make future upgrades more complicated.\n"
1382+
prompt_str += "3) (Not implemented yet) Keep patch file - "
1383+
prompt_str += "File is converted into a patch file (diff) that hopefully will apply to future versions as well.\n"
1384+
1385+
response = prompt_user(non_interactive, prompt_str, ["1", "2"], "1")
1386+
1387+
if response == "1":
1388+
print("Deleting './%s'..." % modified_file)
1389+
rm(os.path.join(dir_name, modified_file))
1390+
commit_message = "Deleted './%s'" % modified_file
1391+
print("Creating Git commit - %s..." % commit_message)
1392+
try:
1393+
cfbs_convert_git_commit(commit_message)
1394+
except:
1395+
log.warning("Git commit failed, continuing without committing...")
1396+
if response == "2":
1397+
print("Keeping file as is, nothing to do.")
1398+
1399+
print("Conversion finished successfully.")
1400+
13031401
return 0
13041402

13051403

cfbs/git.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def ls_remote(remote, branch):
4949

5050

5151
def is_git_repo(path=None):
52-
"""Is the given path a Git repository?)
52+
"""Is the given path a Git repository?
5353
5454
:param:`path` defaults to CWD (if `None`)
5555

cfbs/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ def _main() -> int:
145145
"clean",
146146
"update",
147147
"input",
148+
"convert",
148149
):
149150
raise CFBSUserError(
150151
"The option --non-interactive is not for cfbs %s" % (args.command)

0 commit comments

Comments
 (0)