@@ -60,12 +60,15 @@ def search_command(terms: List[str]):
6060from cfbs .cfbs_json import CFBSJson
6161from cfbs .cfbs_types import CFBSCommandExitCode , CFBSCommandGitResult
6262from cfbs .masterfiles .analyze import most_relevant_version
63+ from cfbs .masterfiles .download import download_single_version
6364from cfbs .updates import ModuleUpdates , update_module
6465from 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" )
11321135def 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 ("\n File" , 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 = "\n Choose 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
0 commit comments