1#!/usr/bin/env python3 2 3r""" 4This module contains file functions such as file_diff. 5""" 6 7import os 8import re 9import time 10 11from gen_cmd import cmd_fnc_u 12 13robot_env = 1 14try: 15 from robot.libraries import DateTime 16 from robot.libraries.BuiltIn import BuiltIn 17except ImportError: 18 robot_env = 0 19 20 21def file_diff(file1_path, file2_path, diff_file_path, skip_string): 22 r""" 23 Compare the contents of two text files. The comparison uses the Unix 24 'diff' command. Differences can be selectively ignored by use of 25 the skip_string parameter. The output of diff command is written 26 to a user-specified file and is also written (logged) to the console. 27 28 Description of arguments: 29 file1_path File containing text data. 30 file2_path Text file to compare to file1. 31 diff_file_path Text file which will contain the diff output. 32 skip_string To allow for differences which may expected or immaterial, 33 skip_string parameter is a word or a string of comma 34 separated words which specify what should be ignored. 35 For example, "size,speed". Any line containing the word 36 size or the word speed will be ignored when the diff is 37 performed. This parameter is optional. 38 39 Returns: 40 0 if both files contain the same information or they differ only in 41 items specified by the skip_string. 42 2 if FILES_DO_NOT_MATCH. 43 3 if INPUT_FILE_DOES_NOT_EXIST. 44 4 if IO_EXCEPTION_READING_FILE. 45 5 if IO_EXCEPTION_WRITING_FILE. 46 6 if INPUT_FILE_MALFORMED 47 """ 48 49 FILES_MATCH = 0 50 FILES_DO_NOT_MATCH = 2 51 INPUT_FILE_DOES_NOT_EXIST = 3 52 IO_EXCEPTION_READING_FILE = 4 53 IO_EXCEPTION_WRITING_FILE = 5 54 INPUT_FILE_MALFORMED = 6 55 56 # The minimum size in bytes a file must be. 57 min_file_byte_size = 1 58 59 now = time.strftime("%Y-%m-%d %H:%M:%S") 60 61 if not os.path.exists(file1_path) or (not os.path.exists(file2_path)): 62 return INPUT_FILE_DOES_NOT_EXIST 63 try: 64 with open(file1_path, "r") as file: 65 initial = file.readlines() 66 with open(file2_path, "r") as file: 67 final = file.readlines() 68 except IOError: 69 file.close() 70 return IO_EXCEPTION_READING_FILE 71 except ValueError: 72 file.close() 73 return INPUT_FILE_MALFORMED 74 else: 75 file.close() 76 77 # Must have more than a trivial number of bytes. 78 if len(initial) < min_file_byte_size: 79 return INPUT_FILE_MALFORMED 80 81 if initial == final: 82 try: 83 file = open(diff_file_path, "w") 84 except IOError: 85 file.close() 86 line_to_print = ( 87 "Specified skip (ignore) string = " + skip_string + "\n\n" 88 ) 89 file.write(line_to_print) 90 line_to_print = ( 91 now 92 + " found no difference between file " 93 + file1_path 94 + " and " 95 + file2_path 96 + "\n" 97 ) 98 file.write(line_to_print) 99 file.close() 100 return FILES_MATCH 101 102 # Find the differences and write difference report to diff_file_path file 103 try: 104 file = open(diff_file_path, "w") 105 except IOError: 106 file.close() 107 return IO_EXCEPTION_WRITING_FILE 108 109 # Form a UNIX diff command and its parameters as a string. For example, 110 # if skip_string="size,capacity", command = 'diff -I "size" 111 # -I "capacity" file1_path file2_path'. 112 skip_list = filter(None, re.split(r"[ ]*,[ ]*", skip_string)) 113 ignore_string = " ".join([("-I " + '"' + x + '"') for x in skip_list]) 114 command = " ".join( 115 filter(None, ["diff", ignore_string, file1_path, file2_path]) 116 ) 117 118 line_to_print = now + " " + command + "\n" 119 file.write(line_to_print) 120 121 # Run the command and get the differences 122 rc, out_buf = cmd_fnc_u(command, quiet=0, print_output=0, show_err=0) 123 124 # Write the differences to the specified diff_file and console. 125 if robot_env == 1: 126 BuiltIn().log_to_console("DIFF:\n" + out_buf) 127 else: 128 print("DIFF:\n", out_buf) 129 130 file.write(out_buf) 131 file.close() 132 133 if rc == 0: 134 # Any differences found were on the skip_string. 135 return FILES_MATCH 136 else: 137 # We have at least one difference not in the skip_string. 138 return FILES_DO_NOT_MATCH 139