@@ -432,8 +432,13 @@ def _argument_parser():
432
432
dest = "compress" ,
433
433
const = False ,
434
434
help = "Decompress the file instead of compressing." )
435
- parser .add_argument ("-c" , "--stdout" , action = "store_true" ,
436
- help = "write on standard output" )
435
+ output_group = parser .add_mutually_exclusive_group ()
436
+ output_group .add_argument ("-c" , "--stdout" , action = "store_true" ,
437
+ help = "write on standard output" )
438
+ output_group .add_argument ("-o" , "--output" ,
439
+ help = "Write to this output file" )
440
+ parser .add_argument ("-f" , "--force" , action = "store_true" ,
441
+ help = "Overwrite output without prompting" )
437
442
# -b flag not taken by either gzip or igzip. Hidden attribute. Above 32K
438
443
# diminishing returns hit. _compression.BUFFER_SIZE = 8k. But 32K is about
439
444
# ~6% faster.
@@ -448,31 +453,46 @@ def main():
448
453
449
454
compresslevel = args .compresslevel or _COMPRESS_LEVEL_TRADEOFF
450
455
451
- # Determine input file
452
- if args .compress and args .file is None :
453
- in_file = sys .stdin .buffer
454
- elif args .compress and args .file is not None :
455
- in_file = io .open (args .file , mode = "rb" )
456
- elif not args .compress and args .file is None :
457
- in_file = IGzipFile (mode = "rb" , fileobj = sys .stdin .buffer )
458
- elif not args .compress and args .file is not None :
459
- base , extension = os .path .splitext (args .file )
460
- if extension != ".gz" and not args .stdout :
461
- sys .exit (f"filename doesn't end in .gz: { args .file !r} . "
462
- f"Cannot determine output filename." )
463
- in_file = open (args .file , "rb" )
464
-
465
- # Determine output file
466
- if args .compress and (args .file is None or args .stdout ):
467
- out_file = IGzipFile (mode = "wb" , compresslevel = compresslevel ,
468
- fileobj = sys .stdout .buffer )
469
- elif args .compress and args .file is not None :
470
- out_file = open (args .file + ".gz" , mode = "wb" ,
471
- compresslevel = compresslevel )
472
- elif not args .compress and (args .file is None or args .stdout ):
473
- out_file = sys .stdout .buffer
474
- elif not args .compress and args .file is not None :
475
- out_file = io .open (base , "wb" )
456
+ if args .output :
457
+ out_filepath = args .output
458
+ elif args .stdout :
459
+ out_filepath = None # to stdout
460
+ elif args .file is None :
461
+ out_filepath = None # to stout
462
+ else :
463
+ if args .compress :
464
+ out_filepath = args .file + ".gz"
465
+ else :
466
+ out_filepath , extension = os .path .splitext (args .file )
467
+ if extension != ".gz" and not args .stdout :
468
+ sys .exit (f"filename doesn't end in .gz: { args .file !r} . "
469
+ f"Cannot determine output filename." )
470
+ if out_filepath is not None and not args .force :
471
+ if os .path .exists (out_filepath ):
472
+ yes_or_no = input (f"{ out_filepath } already exists; "
473
+ f"do you wish to overwrite (y/n)?" )
474
+ if yes_or_no not in {"y" , "Y" , "yes" }:
475
+ sys .exit ("not overwritten" )
476
+
477
+ if args .compress :
478
+ if args .file is None :
479
+ in_file = sys .stdin .buffer
480
+ else :
481
+ in_file = io .open (args .file , mode = "rb" )
482
+ if out_filepath is not None :
483
+ out_file = open (out_filepath , "wb" , compresslevel = compresslevel )
484
+ else :
485
+ out_file = IGzipFile (mode = "wb" , fileobj = sys .stdout .buffer ,
486
+ compresslevel = compresslevel )
487
+ else :
488
+ if args .file :
489
+ in_file = open (args .file , mode = "rb" )
490
+ else :
491
+ in_file = IGzipFile (mode = "rb" , fileobj = sys .stdin .buffer )
492
+ if out_filepath is not None :
493
+ out_file = io .open (out_filepath , mode = "wb" )
494
+ else :
495
+ out_file = sys .stdout .buffer
476
496
477
497
global READ_BUFFER_SIZE
478
498
READ_BUFFER_SIZE = args .buffer_size
0 commit comments