view cutils/dos2unix.py @ 177:089c40240061

Add an alternate implementation for generating directory tree digests: - Do not use something like os.walk() but use os.scandir() directly. - Recursively generate the subdirectory digests only when needed and in the right order. This fixes that the order of subdirectories in the output did not match the application order of its directory digests. The new implementation also should make filtering (that will be implemented later) easier. NOTE: The tree digests of the old and the new implementation are identical.
author Franz Glasner <fzglas.hg@dom66.de>
date Sat, 11 Jan 2025 17:41:28 +0100
parents dfe7bb0579e2
children 48430941c18c
line wrap: on
line source

# -*- coding: utf-8 -*-
# :-
# :Copyright: (c) 2020-2025 Franz Glasner
# :License:   BSD-3-Clause
# :-
r"""Pure Python implementation of `dos2unix`.

"""

from __future__ import print_function, absolute_import

from . import (__version__, __revision__)


__all__ = []


import argparse
import io
import sys


def main(argv=None):
    aparser = argparse.ArgumentParser(
        description="Python implementation of dos2unix",
        fromfile_prefix_chars='@')
    aparser.add_argument(
        "--version", "-V", action="version",
        version="%s (rv:%s)" % (__version__, __revision__))
    aparser.add_argument(
        "--keepdate", "-k", action="store_true",
        help="Keep the date stamp of output file same as input file.")
    aparser.add_argument(
        "--oldfile", "-o", action="store_false", dest="newfile", default=False,
        help="Old file mode. Convert the file and write output to it."
             " The program defaults to run in this mode."
             " Wildcard names may be used. ")
    aparser.add_argument(
        "--newfile", "-n", action="store_true", dest="newfile", default=False,
        help="New file mode. Convert the infile and write output to outfile."
             " File names must be given in pairs and wildcard names should"
             " NOT be used or you WILL lose your files.")
    aparser.add_argument(
        "--quiet", "-q", action="store_true",
        help="Quiet mode. Suppress all warning and messages.")

    aparser.add_argument(
        "files", nargs="+", metavar="FILE")

    opts = aparser.parse_args(args=argv)

    if opts.keepdate:
        raise NotImplementedError("--keepdate, -k")

    return dos2unix(opts)


def gen_opts(files=[], newfile=False, keepdate=False, quiet=True):
    if keepdate:
        raise NotImplementedError("--keepdate, -k")

    if newfile and (len(files) % 2):
        raise ValueError("need pairs of files")

    opts = argparse.Namespace(files=files,
                              newfile=newfile,
                              keepdate=keepdate,
                              quiet=quiet)
    return opts


def dos2unix(opts):
    if opts.newfile:
        return _convert_copy(opts)
    else:
        return _convert_inplace(opts)


def _convert_inplace(opts):
    lines = []
    for filename in opts.files:
        with io.open(filename, "rt", encoding="iso-8859-1") as source:
            for line in source:
                lines.append(line.encode("iso-8859-1"))
        with open(filename, "wb") as dest:
            for line in lines:
                dest.write(line)


def _convert_copy(opts):
    if len(opts.files) % 2:
        print("ERROR: need pairs of files", file=sys.stderr)
        return 64  # :manpage:`sysexits(3)` EX_USAGE
    idx = 0
    while idx < len(opts.files):
        with io.open(opts.files[idx], "rt", encoding="iso-8859-1") as source:
            with open(opts.files[idx+1], "wb") as dest:
                for line in source:
                    dest.write(line.encode("iso-8859-1"))
        idx += 2


if __name__ == "__main__":
    sys.exit(main())