Mercurial > hgrepos > Python > apps > py-cutils
comparison cutils/treesum.py @ 367:8a8a43e8369d
treesum: FIX: Handle line endings on Windows with redirected stdout properly
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Thu, 10 Apr 2025 01:54:09 +0200 |
| parents | 5fffacc390eb |
| children | bfe1160fbfd3 |
comparison
equal
deleted
inserted
replaced
| 366:5fffacc390eb | 367:8a8a43e8369d |
|---|---|
| 564 if opts.output is None or opts.output == "-": | 564 if opts.output is None or opts.output == "-": |
| 565 if hasattr(sys.stdout, "buffer"): | 565 if hasattr(sys.stdout, "buffer"): |
| 566 out_cm = cm.nullcontext(sys.stdout.buffer) | 566 out_cm = cm.nullcontext(sys.stdout.buffer) |
| 567 else: | 567 else: |
| 568 out_cm = cm.nullcontext(sys.stdout) | 568 out_cm = cm.nullcontext(sys.stdout) |
| 569 is_stdout = True | |
| 569 else: | 570 else: |
| 570 if opts.append_output: | 571 if opts.append_output: |
| 571 out_cm = open(opts.output, "ab") | 572 out_cm = open(opts.output, "ab") |
| 572 else: | 573 else: |
| 573 out_cm = open(opts.output, "wb") | 574 out_cm = open(opts.output, "wb") |
| 575 is_stdout = False | |
| 574 | 576 |
| 575 fnmatcher = fnmatch.FnMatcher.build_from_commandline_patterns( | 577 fnmatcher = fnmatch.FnMatcher.build_from_commandline_patterns( |
| 576 opts.fnmatch_filters) | 578 opts.fnmatch_filters) |
| 577 | 579 |
| 578 if opts.output_style in ("tagged", "tag"): | 580 if opts.output_style in ("tagged", "tag"): |
| 582 else: | 584 else: |
| 583 raise NotImplementedError("`output_style'") | 585 raise NotImplementedError("`output_style'") |
| 584 | 586 |
| 585 with out_cm as outfp: | 587 with out_cm as outfp: |
| 586 writer = writerstyle(outfp, | 588 writer = writerstyle(outfp, |
| 589 is_stdout=is_stdout, | |
| 587 size_only=opts.size_only, | 590 size_only=opts.size_only, |
| 588 print_size=opts.print_size, | 591 print_size=opts.print_size, |
| 589 use_base64=opts.base64, | 592 use_base64=opts.base64, |
| 590 grouping_separator=opts.grouping_separator, | 593 grouping_separator=opts.grouping_separator, |
| 591 size_column_width=opts.size_column_width, | 594 size_column_width=opts.size_column_width, |
| 1326 separator for your OS as bytes""" | 1329 separator for your OS as bytes""" |
| 1327 | 1330 |
| 1328 DEFAULT_GROUPING_SEPARATOR = "" | 1331 DEFAULT_GROUPING_SEPARATOR = "" |
| 1329 """Disable the thousands separator in case no subclass redefines it""" | 1332 """Disable the thousands separator in case no subclass redefines it""" |
| 1330 | 1333 |
| 1331 def __init__(self, outfp, size_only=False, print_size=False, | 1334 def __init__(self, outfp, is_stdout=False, |
| 1335 size_only=False, print_size=False, | |
| 1332 use_base64=False, grouping_separator=None, | 1336 use_base64=False, grouping_separator=None, |
| 1333 size_column_width=None): | 1337 size_column_width=None): |
| 1334 # Poor man's abstract abstract class implemenetation | 1338 # Poor man's abstract abstract class implemenetation |
| 1335 assert self.__class__ is not WriterBase | 1339 assert self.__class__ is not WriterBase |
| 1336 | 1340 |
| 1337 self._outfp = outfp | 1341 self._outfp = outfp |
| 1342 try: | |
| 1343 self._outfp_is_tty = self._outfp.isatty() | |
| 1344 except: # noqa: E722 bare except | |
| 1345 self._outfp_is_tty = None | |
| 1346 self._is_windows = sys.platform == "win32" | |
| 1347 self._is_stdout = is_stdout | |
| 1338 self.size_only = size_only | 1348 self.size_only = size_only |
| 1339 self.print_size = print_size | 1349 self.print_size = print_size |
| 1340 self.use_base64 = use_base64 | 1350 self.use_base64 = use_base64 |
| 1341 self.grouping_separator = (grouping_separator | 1351 self.grouping_separator = (grouping_separator |
| 1342 if grouping_separator is not None | 1352 if grouping_separator is not None |
| 1383 | 1393 |
| 1384 :param bytes line: The line to write to (without line ending) | 1394 :param bytes line: The line to write to (without line ending) |
| 1385 | 1395 |
| 1386 """ | 1396 """ |
| 1387 self.write(line) | 1397 self.write(line) |
| 1388 self.write(self.LS) | 1398 if self._is_windows: |
| 1399 if self._is_stdout: | |
| 1400 if self._outfp_is_tty: | |
| 1401 # Windows handles this correctly in its terminal | |
| 1402 self.write(self.LS) | |
| 1403 else: | |
| 1404 # | |
| 1405 # Simulate a CR-LF for the CRC but write a LF only. | |
| 1406 # This will be converted to a CR-LF on Windows by | |
| 1407 # the runtime libs. | |
| 1408 # | |
| 1409 self._crc.update(b'\r') | |
| 1410 self.write(b'\n') | |
| 1411 else: | |
| 1412 self.write(self.LS) | |
| 1413 else: | |
| 1414 self.write(self.LS) | |
| 1389 | 1415 |
| 1390 def write(self, data): | 1416 def write(self, data): |
| 1391 """Write `data` into the output file and update the CRC accordingly. | 1417 """Write `data` into the output file and update the CRC accordingly. |
| 1392 | 1418 |
| 1393 :param bytes data: The data to write to and to update the CRC with | 1419 :param bytes data: The data to write to and to update the CRC with |
