@@ -163,6 +163,19 @@ class Writer(ABC):
163163 """
164164 pass
165165
166+ def clear_wraparound (self ):
167+ """
168+ Clear the wraparound (if one exists). This isn't relevant to all types
169+ of Writers but is very meaningful for redacted writers. The safest
170+ way to interact with this method is to only call it at the end of a
171+ file since the rest of the algorithm functions properly as-is. The
172+ issue arises if there is no trailing newline or no newlines in the file
173+ at all. This is why calling this hook at the END of the logical file
174+ makes the most sense. You can see it being called for CollectFileTask
175+ as well as the base Task (that handles process -> logfile type tasks).
176+ """
177+ pass
178+
166179
167180class FSyncedFile (Writer ):
168181 SYNC_BYTES = 16 * 1024 * 1024
@@ -594,6 +607,11 @@ class RedactStream(Writer):
594607 def write_passthrough (self , chunk : ReadableBuffer ):
595608 return write_readable_buffer (chunk , self ._inner )
596609
610+ def clear_wraparound (self ):
611+ if self ._wraparound :
612+ self ._inner .write (self .process_line ('' .join (self ._wraparound )))
613+ self ._wraparound .clear ()
614+
597615 def flush (self ):
598616 return self ._inner .flush ()
599617
@@ -632,6 +650,10 @@ class DoubleStream(Writer):
632650 self ._first .flush ()
633651 self ._second .flush ()
634652
653+ def clear_wraparound (self ):
654+ self ._first .clear_wraparound ()
655+ self ._second .clear_wraparound ()
656+
635657
636658@unique
637659class Platform (Enum ):
@@ -791,6 +813,14 @@ class Task:
791813 stdout .close ()
792814
793815 outstream .flush ()
816+
817+ # due to the fact that we overload usage of builtin containers like
818+ # BytesIO we need to double check if the method is defined on the
819+ # object or not before calling it.
820+ # TODO: handle in a more graceful / OOP way. See: MB-63307
821+ if "clear_wraparound" in dir (outstream ):
822+ outstream .clear_wraparound ()
823+
794824 return code
795825
796826 def will_run (self ):
@@ -951,6 +981,7 @@ class CollectFileTask(AllOsTask):
951981 break
952982 outstream .write (res )
953983 outstream .flush ()
984+ outstream .clear_wraparound ()
954985 return 0
955986 except FileNotFoundError :
956987 log (f"File doesn't exist: { self .output_file } -- " , new_line = False )
0 commit comments