From fb933cc9f5c25189da9fa47dd089343f9946cef1 Mon Sep 17 00:00:00 2001 From: Rob McMullen Date: Thu, 4 May 2017 21:29:07 -0700 Subject: [PATCH] Removed special case argument hack to get "create -l" to work * added list of available templates to "create --help" --- README.rst | 37 ++++++++++++++++++---------- atrcopy/__init__.py | 59 +++++++++++++++++++++------------------------ 2 files changed, 51 insertions(+), 45 deletions(-) diff --git a/README.rst b/README.rst index f282ea2..e77541d 100644 --- a/README.rst +++ b/README.rst @@ -84,9 +84,10 @@ where the available commands include: * ``delete``: delete files from the disk image * ``vtoc``: show and manipulate the VTOC for images that support it -The ``DISK_IMAGE`` is always required which points to the path on your local -file system of the disk image. ``COMMAND`` is one of the commands listed -above, and the commands may be abbreviated as shown here:: +Except when using the ``--help`` option, the ``DISK_IMAGE`` is always required +which points to the path on your local file system of the disk image. +``COMMAND`` is one of the commands listed above, and the commands may be +abbreviated as shown here:: $ atrcopy --help usage: atrcopy DISK_IMAGE [-h] [-v] [--dry-run] COMMAND ... @@ -195,17 +196,27 @@ Several template disk images are included in the distribution, and these can be used to create blank disk images that subsequent uses of ``atrcopy`` can reference. -The available disk images can be viewed with:: +The available disk images can be viewed using the ``--help`` option:: - $ atrcopy create -l - Available templates: - dos2dd Atari 8-bit DOS 2 double density (180K), empty VTOC - dos2ed Atari 8-bit DOS 2 enhanced density (130K), empty VTOC - dos2ed+2.5 Atari 8-bit DOS 2 enhanced density (130K) DOS 2.5 system disk - dos2sd Atari 8-bit DOS 2 single density (90K), empty VTOC - dos2sd+2.0s Atari 8-bit DOS 2 single density (90K) DOS 2.0S system disk - dos33 Apple ][ DOS 3.3 (140K) standard RWTS, empty VTOC - dos33autobrun Apple ][ DOS 3.3 (140K) standard RWTS, boot to HGR & BRUN a file named AUTOBRUN + $ atrcopy create --help + usage: atrcopy DISK_IMAGE create [-h] [-f] TEMPLATE + + positional arguments: + TEMPLATE template to use to create new disk image; see below for list of + available built-in templates + + optional arguments: + -h, --help show this help message and exit + -f, --force replace disk image file if it exists + + available templates: + dos2dd Atari 8-bit DOS 2 double density (180K), empty VTOC + dos2ed Atari 8-bit DOS 2 enhanced density (130K), empty VTOC + dos2ed+2.5 Atari 8-bit DOS 2 enhanced density (130K) DOS 2.5 system disk + dos2sd Atari 8-bit DOS 2 single density (90K), empty VTOC + dos2sd+2.0s Atari 8-bit DOS 2 single density (90K) DOS 2.0S system disk + dos33 Apple ][ DOS 3.3 (140K) standard RWTS, empty VTOC + dos33autobrun Apple ][ DOS 3.3 (140K) standard RWTS, boot to HGR & BRUN a file named AUTOBRUN To create a new image, use:: diff --git a/atrcopy/__init__.py b/atrcopy/__init__.py index 228af11..21437b5 100644 --- a/atrcopy/__init__.py +++ b/atrcopy/__init__.py @@ -262,12 +262,14 @@ def get_template_path(rel_path="templates"): return template_path -def list_templates(): +def get_template_info(): import glob path = get_template_path() files = glob.glob(os.path.join(path, "*")) - print "Available templates:" + + lines = [] + lines.append("available templates:") for name in sorted(files): if name.endswith(".inf"): continue @@ -276,7 +278,12 @@ def list_templates(): description = fh.read().strip() except IOError: description = "" - print "%-14s %s" % (os.path.basename(name), description) + lines.append(" %-14s %s" % (os.path.basename(name), description)) + return os.linesep.join(lines) + os.linesep + + +def list_templates(): + print get_template_info() def get_template_data(template): @@ -358,10 +365,9 @@ def run(): "vtoc": ["v"], "segments": [], } - reverse_aliases = {z: k for k, v in command_aliases.iteritems() for z in v} - possible_commands = set(command_aliases.keys()).union(reverse_aliases.keys()) - allowed_without_diskimage = ["create"] - allowed_without_diskimage = set([c for c in possible_commands if c in allowed_without_diskimage or reverse_aliases.get(c, None) in allowed_without_diskimage]) + # reverse aliases does the inverse mapping of command aliases, including + # the identity mapping of "command" to "command" + reverse_aliases = {z: k for k, v in command_aliases.iteritems() for z in (v + [k])} skip_diskimage_summary = set(["crc"]) @@ -402,10 +408,9 @@ def run(): add_parser.add_argument("files", metavar="FILENAME", nargs="+", help="a file (or list of files) to copy to the disk image") command = "create" - create_parser = subparsers.add_parser(command, help="Create a new disk image", aliases=command_aliases[command]) + create_parser = subparsers.add_parser(command, help="Create a new disk image", aliases=command_aliases[command], epilog="", formatter_class=argparse.RawDescriptionHelpFormatter) create_parser.add_argument("-f", "--force", action="store_true", default=False, help="replace disk image file if it exists") - create_parser.add_argument("-l", "--list", action="store_true", default=False, help="list available built-in templates") - create_parser.add_argument("template", metavar="TEMPLATE", nargs="?", help="template to use to create new disk image, or without this argument will list available built-in templates") + create_parser.add_argument("template", metavar="TEMPLATE", nargs=1, help="template to use to create new disk image; see below for list of available built-in templates") command = "assemble" assembly_parser = subparsers.add_parser(command, help="Create a new binary file in the disk image", aliases=command_aliases[command]) @@ -453,44 +458,34 @@ def run(): if found_help == 0 or first_non_dash < 0: # put dummy argument so help for entire script will be shown args = ["--help"] - elif non_dash[0] in possible_commands: + elif non_dash[0] in reverse_aliases: # if the first argument without a leading dash looks like a # command instead of a disk image, show help for that command args = [non_dash[0], "--help"] - elif len(non_dash) > 0 and non_dash[1] in possible_commands: + elif len(non_dash) > 0 and non_dash[1] in reverse_aliases: # if the first argument without a leading dash looks like a # command instead of a disk image, show help for that command args = [non_dash[1], "--help"] else: # show script help args = ["--help"] + if reverse_aliases[args[0]] == "create": + create_parser.epilog = get_template_info() else: - if first_non_dash == 0 and num_non_dash == 1: - # check a special case like "atrcopy COMMAND -l" to allow some - # help or limited functionality without a disk image. This is - # allowed only when there are no global options and no other - # non-dashed arguments, otherwise it will proceed as if a disk - # image has been specified. - cmd = args[0] - if cmd in allowed_without_diskimage: - disk_image_name = None - else: - # not a special case, so process like no disk image is - # specified. Allow global options to come before or after disk - # image name - disk_image_name = args[first_non_dash] - args[first_non_dash:first_non_dash + 1] = [] - if num_non_dash == 1: - # If there is only a disk image but no command specified, - # use the default - args.append('list') + # Allow global options to come before or after disk image name + disk_image_name = args[first_non_dash] + args[first_non_dash:first_non_dash + 1] = [] + if num_non_dash == 1: + # If there is only a disk image but no command specified, + # use the default + args.append('list') else: disk_image_name = None # print "parsing: %s" % str(args) options = parser.parse_args(args) # print options - command = reverse_aliases.get(options.command, options.command) + command = reverse_aliases[options.command] # Turn off debug messages by default logging.basicConfig(level=logging.WARNING)