argparse/0000755000175000017500000000000014150166422012211 5ustar nileshnileshargparse/INSTALL0000644000175000017500000000467713205355054013261 0ustar nileshnileshInstalling System Requirements ============================== The ``argparse`` package requires that a Python interpreter be installed with the ``argparse`` and ``json`` (or ``simplejson``) modules. They are automatically included with recent Python implementations starting with versions 2.7 and 3.2. The package will not install Python for you and ``ArgumentParser`` will throw an error if it can not find a sufficient Python interpreter. This package is tested with the traditional implementation of Python aka CPython (either 2.7 or 3.2+ is fine) but probably works with other implementations (for example it has been lightly tested to work with PyPy). If you are using Linux or a Mac you probably already have CPython installed but it might be too old and you might want to upgrade using your distribution package manager. For more information on installing Python go to: http://www.python.org/download/ If you have Python 2.7 or 3.2 and higher the ``argparse`` and ``json`` modules are part of the standard library and should be automatically installed with the installation of the Python interpreter. If you have less than Python 2.7 you should probably upgrade or have your administrator do so. You can also have Python 2.7 installed alongside the older Python (as the binary ``python2.7``) However, if you have Python 2.6, Python 3.1, or Python 3.0 you you should be able to get by if you install the ``argparse`` module yourself: https://code.google.com/p/argparse/ If you have Python 2.5 in addition to installing the ``argparse`` module you will need to install the ``simplejson`` module as well: https://github.com/simplejson/simplejson Support for Non-ASCII characters ================================ If you want to use Unicode arguments with ``argparse`` you'll need to use Python 3.0+ instead of Python 2.5-2.7. You'll probably also need to use a terminal and/or shell that supports Unicode. Having ``argparse`` find Python =============================== You may specify the Python interpreter for ``argparse`` to use by either setting the ``python_cmd`` option:: options(python_cmd = "D:/NonstandardWindowsInstallation/Python27/python") or by passing the path to the ``python_cmd`` argument in the ``ArgumentParser`` function:: ArgumentParser(description="A simple Rscript", python_cmd="pypy") If these are not specified then by default ``ArgumentParser`` will use the package ``findpython`` to look for a suitable Python binary. argparse/exec/0000755000175000017500000000000013241455711013137 5ustar nileshnileshargparse/exec/display_file.R0000644000175000017500000000252413241455675015742 0ustar nileshnilesh#!/usr/bin/env Rscript # Copyright 2012-2013 Trevor L Davis # # This file is free software: you may copy, redistribute and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 2 of the License, or (at your # option) any later version. # # This file is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . suppressPackageStartupMessages(library("argparse")) parser <- ArgumentParser() parser$add_argument("-n", "--add_numbers", action="store_true", default=FALSE, help="Print line number at the beginning of each line [default]") parser$add_argument("file", nargs=1, help="File to be displayed") args <- parser$parse_args() file <- args$file if( file.access(file) == -1) { stop(sprintf("Specified file ( %s ) does not exist", file)) } else { file_text <- readLines(file) } if(args$add_numbers) { cat(paste(1:length(file_text), file_text), sep = "\n") } else { cat(file_text, sep = "\n") } argparse/exec/example.R0000644000175000017500000000455013241455711014721 0ustar nileshnilesh#!/usr/bin/env Rscript # Copyright 2012-2013 Trevor L Davis # Copyright 2008 Allen Day # # This file is free software: you may copy, redistribute and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 2 of the License, or (at your # option) any later version. # # This file is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . suppressPackageStartupMessages(library("argparse")) # create parser object parser <- ArgumentParser() # specify our desired options # by default ArgumentParser will add an help option parser$add_argument("-v", "--verbose", action="store_true", default=TRUE, help="Print extra output [default]") parser$add_argument("-q", "--quietly", action="store_false", dest="verbose", help="Print little output") parser$add_argument("-c", "--count", type="integer", default=5, help="Number of random normals to generate [default %(default)s]", metavar="number") parser$add_argument("--generator", default="rnorm", help = "Function to generate random deviates [default \"%(default)s\"]") parser$add_argument("--mean", default=0, type="double", help="Mean if generator == \"rnorm\" [default %(default)s]") parser$add_argument("--sd", default=1, type="double", metavar="standard deviation", help="Standard deviation if generator == \"rnorm\" [default %(default)s]") # get command line options, if help option encountered print help and exit, # otherwise if options not found on command line then set defaults, args <- parser$parse_args() # print some progress messages to stderr if "quietly" wasn't requested if ( args$verbose ) { write("writing some verbose output to standard error...\n", stderr()) } # do some operations based on user input if( args$generator == "rnorm") { cat(paste(rnorm(args$count, mean=args$mean, sd=args$sd), collapse="\n")) } else { cat(paste(do.call(args$generator, list(args$count)), collapse="\n")) } cat("\n") argparse/MD50000644000175000017500000000220714150166422012522 0ustar nileshnilesheb723b61539feef013de476e68b5c50a *COPYING f1b08b21f822c6b0d1a547640bc8bf64 *DESCRIPTION c7c606b8c101538e3f3b3e5411a43f02 *INSTALL 50ff6dd84014086baa6fe806e71ed194 *NAMESPACE faae383be9f2c8d0714f91a5781d3475 *NEWS.md 61c3247d2d34d9666b2bdeadc668cf96 *R/argparse.R 5c2f787908c5475b6e3235acf5791748 *README.md 9004ad7da37ee9bd2769dc66ab30401b *build/vignette.rds 608b06b335bc34bbf6473e2fff8a18f9 *exec/display_file.R 6da1e172f78bd815f407edf37addc102 *exec/example.R 6addaa6d5d6b86d9f4c4a8d624f9d89f *inst/COPYRIGHTS 65fabe4423cfaac1a331e0f8d6446ab2 *inst/doc/argparse.R b758caed2bbedcffc31fa28a06aa4eaa *inst/doc/argparse.Rmd 532cbd3b56ba40e0c54025d90e262f12 *inst/doc/argparse.html 5a0828e6a40a4347f20d4d632a68be34 *man/ArgumentParser.Rd d3c85c5ec20572f2c3a75d71c3c4e95c *man/figures/logo.png 0145680dd8506f7699a4061d09492dd4 *man/figures/logo.svg 9f097169ac01ec553d9ff33da5f47dfa *tests/run-all.R 530a459bd27091587abf9221fafec598 *tests/testthat/scripts/test_help.R 360f74a832a17b8ee3e782989466bf59 *tests/testthat/scripts/test_version.R 36de77aa6171ddd6fc4c9c9e15c5f048 *tests/testthat/test-argparse.R b758caed2bbedcffc31fa28a06aa4eaa *vignettes/argparse.Rmd argparse/NEWS.md0000644000175000017500000001142514147744075013326 0ustar nileshnileshargparse 2.1.3 ============== * Prevents extraneous error message from being included in usage message when using Python 3.10 (#36). Thanks @dariober for bug report. argparse 2.1.2 ============== * Fixes bug when using an argument with `action == "append"` and a non-`NULL` `default` value (#35). Thanks @miker985 for bug report. argparse 2.1.1 ============== * Parsers now support ``parse_known_args()`` (#34). Suggestion of David Lacalle Castillo (@WaterKnight1998). argparse 2.0.4 ============== * May now specify a named `formatter_class` argument (as a string) to a `subparsers$add_parser()` method. Thanks Regina (@oyxf) for bug report. * May now specify positional arguments in `ArgumentParser()`. argparse 2.0.3 ============== * Fixes bug when accidentally passing a positional argument to ``ArgumentParser()`` when using Python 3.9. Thanks Kurt Hornik for bug report. argparse 2.0.1 ============== * Improved passing of arguments to Python from R. In particular should fix bug in using ``add_help`` argument in ``ArgumentParser``. Thanks George Chlipala for bug report. * Removes ``getopt`` as a dependency. argparse 2.0.0 ============== * Now uses ``R6`` classes instead of ``proto`` classes (#25). The typical user shouldn't need to change any ``argparse`` code but I did make private the previously public ``python_code`` element of the object returned by ``ArgumentParser()``. * Parsers now support ``add_subparsers`` (#14). Suggestion of Zebulun Arendsee. * Parsers now support ``add_argument_group`` (#26). Suggestion of Dario Beraldi. * Parsers now support ``add_mutually_exclusive_group`` (#23). Suggestion of Vince Reuter. argparse 1.1.1 ============== * Better support for machines only running Python 2.7. * DESCRIPTION makes explicit that it requires version 1.0.0 of ``proto`` dependency. Thanks Christophe Poulet for bug report. argparse 1.1.0 ============== * Better support for Unicode arguments/options. Thanks Erick Rocha Fonseca for bug report. * Fix bug when setting ``type='integer'`` in ``add_argument``. Thanks Dominik Mueller for bug report and suggested solution. * The package ``proto`` has been moved from ``Depends`` to ``Imports`` in ``DESCRIPTION``. We now use ``jsonlite`` package instead of ``rjson`` to parse ``JSON``. * Better error message when accidentally trying to define a positional argument in ``ArgumentParser()`` Suggestion of Alex Reinhart. * Other error message output when an parsing error is detected have been tweaked slightly. argparse 1.0.7 ============== * Now supports showing program's version with ``action='version'``. Suggestion of Dario Beraldi. * Fix bug when setting ``required=FALSE`` in ``add_argument``. Thanks Claire D. McWhite for bug report. argparse 1.0.4 ============== * You can now pass in a character vector to the ``metavar`` argument of ``add_argument``. Thanks Paul Newell for bug report and a patch. * `add_argument` now throws a warning recommending using action "store_true" or "store_false" if type set to "logical" and action set to "store". Suggestion of Martí Duran Ferrer * You can now explicitly set a `NULL` default in `add_argument`. Previously one could only implicitly set a `NULL` default by not setting any default at all. Suggestion of Hyunsoo Kim. * Fixes parsing bug when using a very large argument list. Thanks Taylor Pospisil for bug report. * Parse error usage message now prints to standard error. User requested help message quit status is now zero. Thanks to PlasmaBinturong for report/request. * If Python script fails with error pass on error message to user. Thanks to Martí Duran Ferrer for report/request. argparse 1.0.1 ============== * Fix minor bug when running package tests on machines with both old and new versions of Python. Thanks Prof. Brian Ripley for bug report. argparse 1.0.0 ============== * Some support for ``choices`` argument in ``parser$add_argument``. Thanks Christopher Small for report/request. * Some support for ``formatter_class`` argument in ``ArgumentParser``. Thanks Costas Bouyioukos for report/request. * Package now looks for Python binaries with ``findpython::find_python_cmd`` which is a little bit more robust than the previous ``argparse::find_python_cmd``. * If ``interactive() == TRUE`` then ``parse_args`` will no longer ``quit(status=1)`` after printing a help message but will instead throw an error. ``argparse`` will continue to ``quit(status=1)`` after printing a help message for non-interactive Rscripts. argparse 0.5.3 ============== * Fix bug in ``parser$add_argument`` for case when we specify a default vector instead of scalar. Thanks Martin Diehl for bug report. * ``find_python_cmd`` will now also look for a ``python2.7`` binary. * Website moved to https://github.com/trevorld/argparse argparse/DESCRIPTION0000644000175000017500000000263414150166422013724 0ustar nileshnileshPackage: argparse Type: Package Title: Command Line Optional and Positional Argument Parser Version: 2.1.3 Authors@R: c(person("Trevor L", "Davis", role=c("aut", "cre"), email="trevor.l.davis@gmail.com"), person("Allen", "Day", role="ctb", comment="Some documentation and examples ported from the getopt package."), person("Python Software Foundation", role="ctb", comment="Some documentation from the optparse Python module."), person("Paul", "Newell", role="ctb")) Description: A command line parser to be used with Rscript to write "#!" shebang scripts that gracefully accept positional and optional arguments and automatically generate usage. License: GPL (>= 2) Copyright: See file (inst/)COPYRIGHTS. URL: https://github.com/trevorld/r-argparse BugReports: https://github.com/trevorld/r-argparse/issues LazyLoad: yes Imports: R6, findpython, jsonlite SystemRequirements: python (>= 3.2) Suggests: knitr (>= 1.15.19), rmarkdown, testthat VignetteBuilder: knitr RoxygenNote: 7.1.1 Encoding: UTF-8 NeedsCompilation: no Packaged: 2021-11-25 21:45:21 UTC; trevorld Author: Trevor L Davis [aut, cre], Allen Day [ctb] (Some documentation and examples ported from the getopt package.), Python Software Foundation [ctb] (Some documentation from the optparse Python module.), Paul Newell [ctb] Maintainer: Trevor L Davis Repository: CRAN Date/Publication: 2021-11-26 14:20:02 UTC argparse/README.md0000644000175000017500000001250014134315125013464 0ustar nileshnilesh# argparse: Command line optional and positional argument parser [![CRAN Status Badge](https://www.r-pkg.org/badges/version/argparse)](https://cran.r-project.org/package=argparse) [![R-CMD-check](https://github.com/trevorld/r-argparse/workflows/R-CMD-check/badge.svg)](https://github.com/trevorld/r-argparse/actions) [![Coverage Status](https://img.shields.io/codecov/c/github/trevorld/r-argparse.svg)](https://codecov.io/github/trevorld/r-argparse?branch=master) [![RStudio CRAN mirror downloads](https://cranlogs.r-pkg.org/badges/argparse)](https://cran.r-project.org/package=argparse) argparse hex sticker `argparse` is an R package which provides a command line parser to be used with Rscript to write "\#!" shebang scripts that gracefully accept positional and optional arguments and automatically generate usage. To install the latest version released on CRAN use the following command: > install.packages("argparse") To install the development version use the following command: > remotes::install_github("trevorld/r-argparse") ## dependencies The package has a Python dependency. It is easily satisfied if you have Python (version 3.2 or higher) on your PATH. Read the INSTALL file for more information if this doesn't describe you. Additionally this package depends on the R packages `R6`, `findpython`, and `jsonlite`. To run the unit tests you will need the suggested R package `testthat` and in order to build the vignette you will need the suggested R package `knitr` which in turn probably requires the system tool `pandoc`: sudo apt install pandoc ## examples > library("argparse") > parser <- ArgumentParser(description='Process some integers') > parser$add_argument('integers', metavar='N', type="integer", nargs='+', + help='an integer for the accumulator') > parser$add_argument('--sum', dest='accumulate', action='store_const', + const='sum', default='max', + help='sum the integers (default: find the max)') > parser$print_help() usage: PROGRAM [-h] [--sum] N [N ...] Process some integers positional arguments: N an integer for the accumulator optional arguments: -h, --help show this help message and exit --sum sum the integers (default: find the max) Default args for `ArgumentParser()$parse_args` are `commandArgs(TRUE)` which is what you'd want for an Rscript but not for interactive use: > args <- parser$parse_args(c("--sum", "1", "2", "3")) > accumulate_fn <- get(args$accumulate) > print(accumulate_fn(args$integers)) [1] 6 Beginning with version 2.0 `argparse` also supports argument groups: > parser = ArgumentParser(prog='PROG', add_help=FALSE) > group1 = parser$add_argument_group('group1', 'group1 description') > group1$add_argument('foo', help='foo help') > group2 = parser$add_argument_group('group2', 'group2 description') > group2$add_argument('--bar', help='bar help') > parser$print_help() usage: PROG [-h] [--bar BAR] foo optional arguments: -h, --help show this help message and exit group1: group1 description foo foo help group2: group2 description --bar BAR bar help as well as mutually exclusive groups: > parser = ArgumentParser(prog='PROG') > group = parser$add_mutually_exclusive_group() > group$add_argument('--foo', action='store_true') > group$add_argument('--bar', action='store_false') > parser$parse_args('--foo') $bar [1] TRUE $foo [1] TRUE > parser$parse_args('--bar') $bar [1] FALSE $foo [1] FALSE > parser$parse_args(c('--foo', '--bar')) Error in .stop(output, "parse error:") : parse error: usage: PROG [-h] [--foo | --bar] PROG: error: argument --bar: not allowed with argument --foo and even basic support for sub-commands!: > # create the top-level parser > parser = ArgumentParser(prog='PROG') > parser$add_argument('--foo', action='store_true', help='foo help') > subparsers = parser$add_subparsers(help='sub-command help') > # create the parser for the "a" command > parser_a = subparsers$add_parser('a', help='a help') > parser_a$add_argument('bar', type='integer', help='bar help') > # create the parser for the "b" command > parser_b = subparsers$add_parser('b', help='b help') > parser_b$add_argument('--baz', choices='XYZ', help='baz help') > # parse some argument lists > parser$parse_args(c('a', '12')) $bar [1] 12 $foo [1] FALSE > parser$parse_args(c('--foo', 'b', '--baz', 'Z')) $baz [1] "Z" $foo [1] TRUE > parser$print_help() usage: PROG [-h] [--foo] {a,b} ... positional arguments: {a,b} sub-command help a a help b b help optional arguments: -h, --help show this help message and exit --foo foo help > parser_a$print_help() usage: PROG a [-h] bar positional arguments: bar bar help optional arguments: -h, --help show this help message and exit > parser_b$print_help() usage: PROG b [-h] [--baz {X,Y,Z}] optional arguments: -h, --help show this help message and exit --baz {X,Y,Z} baz help argparse/COPYING0000755000175000017500000004313312207447620013256 0ustar nileshnilesh GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. argparse/man/0000755000175000017500000000000014127663327012776 5ustar nileshnileshargparse/man/ArgumentParser.Rd0000644000175000017500000000375614115717340016227 0ustar nileshnilesh% Generated by roxygen2: do not edit by hand % Please edit documentation in R/argparse.R \name{ArgumentParser} \alias{ArgumentParser} \title{Create a command line parser} \usage{ ArgumentParser(..., python_cmd = NULL) } \arguments{ \item{...}{Arguments cleaned and passed to Pythons argparse.ArgumentParser()} \item{python_cmd}{Python executable for \code{argparse} to use. Must have argparse and json modules (automatically included Python 2.7 and 3.2+). If you need Unicode argument support then you must use Python 3.0+. Default will be to use \code{findpython} package to find suitable Python binary.} } \value{ \code{ArgumentParser} returns a parser object which contains an \code{add_argument} function to add arguments to the parser, a \code{parse_args} function to parse command line arguments into a list, a \code{print_help} and \code{print_usage} function to print usage information. See code examples, package vignette, and corresponding python module for more information on how to use it. } \description{ \code{ArgumentParser} creates a parser object that acts as a wrapper to Python's argparse module } \examples{ if (argparse:::detects_python()) { parser <- ArgumentParser(description='Process some integers') parser$add_argument('integers', metavar='N', type = "integer", nargs='+', help='an integer for the accumulator') parser$add_argument('--sum', dest='accumulate', action='store_const', const='sum', default='max', help='sum the integers (default: find the max)') parser$print_help() # default args for ArgumentParser()$parse_args are commandArgs(TRUE) # which is what you'd want for an Rscript but not for interactive use args <- parser$parse_args(c("--sum", "1", "2", "3")) accumulate_fn <- get(args$accumulate) print(accumulate_fn(args$integers)) } } \references{ Python's \code{argparse} library, which this package is based on, is described here: \url{https://docs.python.org/3/library/argparse.html} } argparse/man/figures/0000755000175000017500000000000014127664170014437 5ustar nileshnileshargparse/man/figures/logo.png0000644000175000017500000000200614127664170016103 0ustar nileshnileshPNG  IHDR PLTEtRNSDP! pHYs  ~IDATxKn0 P_t)IQ#ybS訥إVÛ٥uKY={KQʕ @v.zqdi7O#Yi"eh_XY+#mm硱Y9h"V|o&Xi+ BSa{hjX4UVr27օ˛I[\̐uIJi.;1ˊ?d hn m':;k oH -BۉբE jѠEYsW-$eN"fi]2YV ¡<⩌X-d{X^aޓr=(7y `ރr`?kZSS ɖ إtth ӌ#v5` /_@+,ჀX,ػ!jXDKWF{6sTL!&G0A{Pn0A{PnI*i0ik*i0Ao 0+c#6tw#L0J#L0J#L0J]ejculEtvh)#iVa9-`vhq'qg8,!eh0 K>ZFNBXE|/Nv|h4-V0&Y5"i!\J5,w:V\EҜ\KXN4 ͊e-3tYlYf4{V8.Sb'k!͛U֬r4u#KբF*ZdQEdLҢ-D,jZش]uC2Hjed𥳐jyeܬ.-?te[ʍ v=Fvu;{ljٔU^2)Ĕ *u`IENDB`argparse/man/figures/logo.svg0000644000175000017500000000350714127664170016125 0ustar nileshnilesh argparse/vignettes/0000755000175000017500000000000014150001761014213 5ustar nileshnileshargparse/vignettes/argparse.Rmd0000644000175000017500000001112214115723707016474 0ustar nileshnilesh--- title: "argparse Command Line Argument Parsing" output: rmarkdown::html_vignette vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{argparse Command Line Argument Parsing} %\VignetteEncoding{UTF-8} --- argparse is a command line argument parser inspired by Python's "argparse" library. Use this with Rscript to write "#!"-shebang scripts that accept short and long flags/options and positional arguments, generate a usage statement, and set default values for options that are not specified on the command line. ```{r echo=FALSE} library("knitr") rscript_executable <- paste(file.path(R.home(), "bin", "Rscript"), "--vanilla") opts_knit$set(root.dir = system.file("exec", package = "argparse")) # to access the "Rscript files" opts_chunk$set(comment = NA, echo = FALSE) list_file_command <- "ls" chmod_command <- "chmod ug+x display_file.R example.R" path_command <- "export PATH=$PATH:`pwd`" run_command <- function(string) suppressWarnings(cat(system(string, intern = TRUE), sep = "\n")) ``` In our working directory we have two example R scripts, named "example.R" and "display_file.R" illustrating the use of the argparse package. **`r paste("bash$", list_file_command)`** ```{r} run_command(sprintf("%s", list_file_command)) command <- "display_file.R example.R" # to show file ``` In order for a \*nix system to recognize a "\#!"-shebang line you need to mark the file executable with the ``chmod`` command, it also helps to add the directory containing your Rscripts to your path: **`r paste("bash$", chmod_command)`** **`r paste("bash$", command)`** Here is what "example.R" contains: **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R --help" # same as system("Rscript example.R -h") ``` By default ``argparse`` will generate a help message if it encounters ``--help`` or ``-h`` on the command line. Note how ``%(default)s`` in the example program was replaced by the actual default values in the help statement that ``argparse`` generated. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R" # rely only on defaults ``` If you specify default values when creating your ``ArgumentParser`` then ``argparse`` will use them as expected. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R --mean=10 --sd=10 --count=3" ``` Or you can specify your own values. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R --quiet -c 4 --generator=\"runif\"" # same as above but "quiet" ``` If you remember from the example program that ``--quiet`` had ``action="store_false"`` and ``dest="verbose"``. This means that ``--quiet`` is a switch that turns the ``verbose`` option from its default value of ``TRUE`` to ``FALSE``. Note how the ``verbose`` and ``quiet`` options store their value in the exact same variable. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R --silent -m 5" # same as above but "quiet" ``` If you specify an illegal flag then \emph{argparse} will print out a usage message and an error message and quit. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R -c 100 -c 2 -c 1000 -c 7" # same as above but "quiet" ``` If you specify the same option multiple times then \emph{argparse} will use the value of the last option specified. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "display_file.R --help" ``` ``argparse`` can also parse positional arguments. Below we give an example program ``display_file.R``, which is a program that prints out the contents of a single file (the required positional argument, not an optional argument) and which accepts the normal help option as well as an option to add line numbers to the output. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "display_file.R --add_numbers display_file.R" ``` **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "display_file.R non_existent_file.txt" ``` **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "display_file.R" ``` **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) ``` argparse/build/0000755000175000017500000000000014150001761013302 5ustar nileshnileshargparse/build/vignette.rds0000644000175000017500000000033714150001761015644 0ustar nileshnileshmQK0mIL@W.!.6RR0ĝ'$37 D RӃ`1"ȆsTZ2Uq?n !L>nTz\4,rNJZ|l y3ŜI&x/L=n5boM̈́cf9zQ)~OUnw-)ggn'{argparse/tests/0000755000175000017500000000000014102555750013356 5ustar nileshnileshargparse/tests/testthat/0000755000175000017500000000000014150001761015205 5ustar nileshnileshargparse/tests/testthat/test-argparse.R0000644000175000017500000003432714147745406020143 0ustar nileshnilesh# Copyright (c) 2012-2021 Trevor L Davis # # This file is free software: you may copy, redistribute and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 2 of the License, or (at your # option) any later version. # # This file is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # This file incorporates work from the argparse module in Python 2.7.3. # # Copyright (c) 1990-2012 Python Software Foundation; All Rights Reserved # # See (inst/)COPYRIGHTS or http://docs.python.org/2/license.html for the full # Python (GPL-compatible) license stack. context("Unit tests") context("print_help") test_that("print_help works as expected", { skip_if_not(detects_python()) parser <- ArgumentParser(description = "Process some integers.") expect_output(parser$print_help(), "usage:") expect_output(parser$print_help(), "optional arguments:|options:") expect_output(parser$print_help(), "Process some integers.") expect_output(parser$print_usage(), "usage:") # Request/bug by PlasmaBinturong parser$add_argument("integers", metavar = "N", type = "integer", nargs = "+", help = "an integer for the accumulator") expect_error(capture.output(parser$parse_args(), "parse error")) if (!interactive()) skip("interactive() == FALSE") expect_error(capture.output(parser$parse_args("-h")), "help requested") }) context("convert_agument") test_that("convert_argument works as expected", { skip_if_not(detects_python()) expect_equal(convert_argument("foobar"), "'foobar'") expect_equal(convert_argument(14.9), "14.9") expect_equal(convert_argument(c(12.1, 14.9)), "(12.1, 14.9)") expect_equal(convert_argument(c("a", "b")), "('a', 'b')") }) context("convert_..._to_arguments") test_that("convert_..._to_arguments works as expected", { skip_if_not(detects_python()) # test in mode "add_argument" c.2a <- function(...) convert_..._to_arguments("add_argument", ...) waz <- "wazzup" expect_equal(c.2a(foo = "bar", hello = "world"), "foo='bar', hello='world'") expect_equal(c.2a(foo = "bar", waz), "foo='bar', 'wazzup'") expect_equal(c.2a(type = "character"), "type=str") expect_equal(c.2a(default = TRUE), "default=True") expect_equal(c.2a(default = 3.4), "default=3.4") expect_equal(c.2a(default = "foo"), "default='foo'") # test in mode "ArgumentParser" c.2a <- function(...) convert_..._to_arguments("ArgumentParser", ...) expect_match(c.2a(argument_default = FALSE), "argument_default=False") expect_match(c.2a(argument_default = 30), "argument_default=30") expect_match(c.2a(argument_default = "foobar"), "argument_default='foobar'") expect_match(c.2a(foo = "bar"), "^prog='PROGRAM'|^prog='test-argparse.R'") expect_match(c.2a(formatter_class = "argparse.ArgumentDefaultsHelpFormatter"), "formatter_class=argparse.ArgumentDefaultsHelpFormatter") }) context("add_argument") test_that("add_argument works as expected", { skip_if_not(detects_python()) parser <- ArgumentParser() parser$add_argument("integers", metavar = "N", type = "integer", nargs = "+", help = "an integer for the accumulator") parser$add_argument("--sum", dest = "accumulate", action = "store_const", const = "sum", default = "max", help = "sum the integers (default: find the max)") arguments <- parser$parse_args(c("--sum", "1", "2")) f <- get(arguments$accumulate) expect_output(parser$print_help(), "sum the integers") expect_equal(arguments$accumulate, "sum") expect_equal(arguments$integers, c(1, 2)) expect_equal(f(arguments$integers), 3) expect_error(parser$add_argument("--foo", type = "boolean")) # Bug found by Martin Diehl parser$add_argument("--label", type = "character", nargs = 2, dest = "label", action = "store", default = c("a", "b"), help = "label for X and Y axis") suppressWarnings(parser$add_argument("--bool", type = "logical", nargs = 2, dest = "bool", action = "store", default = c(FALSE, TRUE))) arguments <- parser$parse_args(c("--sum", "1", "2")) expect_equal(arguments$label, c("a", "b")) expect_equal(arguments$bool, c(FALSE, TRUE)) # Frustration of Martí Duran Ferrer expect_warning(parser$add_argument("--bool", type = "logical", action = "store")) # Bug/Feature request found by Hyunsoo Kim p <- ArgumentParser() p$add_argument("--test", default = NULL) expect_equal(p$parse_args()$test, NULL) # Feature request of Paul Newell parser <- ArgumentParser() parser$add_argument("extent", nargs = 4, type = "double", metavar = c("e1", "e2", "e3", "e4")) expect_output(parser$print_usage(), "usage: PROGRAM \\[-h\\] e1 e2 e3 e4") # Bug report by Claire D. McWhite parser <- ArgumentParser() parser$add_argument("-o", "--output_filename", required = FALSE, default = "outfile.txt") expect_equal(parser$parse_args()$output_filename, "outfile.txt") parser <- ArgumentParser() parser$add_argument("-o", "--output_filename", required = TRUE, default = "outfile.txt") expect_error(parser$parse_args()) }) context("version") test_that("version flags works as expected", { skip_if_not(detects_python()) # Feature request of Dario Beraldi parser <- ArgumentParser() parser$add_argument("-v", "--version", action = "version", version = "1.0.1") if (interactive()) { expect_error(parser$parse_args("-v"), "version requested:\n1.0.1") expect_error(parser$parse_args("--version"), "version requested:\n1.0.1") } # empty list parser <- ArgumentParser() el <- parser$parse_args() expect_true(is.list(el)) expect_equal(length(el), 0) }) context("parse_known_args()") test_that("parse_known_args() works as expected", { skip_if_not(detects_python()) parser <- ArgumentParser() parser$add_argument("-o", "--output_filename", default = "outfile.txt") a_r <- parser$parse_known_args(c("-o", "foobar.txt", "-n", "4")) expect_equal(a_r[[1]]$output_filename, "foobar.txt") expect_equal(a_r[[2]], c("-n", "4")) }) context("ArgumentParser") test_that("ArgumentParser works as expected", { skip_if_not(detects_python()) parser <- ArgumentParser(prog = "foobar", usage = "%(prog)s arg1 arg2") parser$add_argument("--hello", dest = "saying", action = "store_const", const = "hello", default = "bye", help = "%(prog)s's saying (default: %(default)s)") expect_output(parser$print_help(), "foobar arg1 arg2") expect_output(parser$print_help(), "foobar's saying \\(default: bye\\)") expect_error(ArgumentParser(python_cmd = "foobar")) skip_if_not(interactive(), "Skip passing -h if not interactive()") # Bug report by George Chlipala expect_error(ArgumentParser()$parse_args("-h"), "help requested") expect_error(ArgumentParser(add_help = TRUE)$parse_args("-h"), "help requested") expect_error(ArgumentParser(add_help = FALSE)$parse_args("-h"), "unrecognized arguments") }) test_that("parse_args() works as expected", { skip_if_not(detects_python()) parser <- ArgumentParser("foobar", usage = "%(prog)s arg1 arg2") parser$add_argument("--hello", dest = "saying", action = "store", default = "foo", choices = c("foo", "bar"), help = "%(prog)s's saying (default: %(default)s)") expect_equal(parser$parse_args("--hello=bar"), list(saying = "bar")) expect_error(parser$parse_args("--hello=what")) # Unhelpful error message found by Martí Duran Ferrer parser <- ArgumentParser() parser$add_argument("M", required = TRUE, help = "Test") expect_error(parser$parse_args(), "python error") # bug reported by Dominik Mueller p <- argparse::ArgumentParser() p$add_argument("--int", type = "integer") p$add_argument("--double", type = "double") p$add_argument("--character", type = "character") input <- "1" args <- p$parse_args(c("--int", input, "--double", input, "--character", input)) expect_equal(class(args$int), "integer") expect_equal(class(args$double), "numeric") expect_equal(class(args$character), "character") expect_equal(args$int, as.integer(1.0)) expect_equal(args$double, 1.0) expect_equal(args$character, "1") # Bug found by Taylor Pospisil skip_on_os("windows") # Didn't work on Github Actions Windows skip_on_cran() # Once gave an error on win-builder parser <- ArgumentParser() parser$add_argument("--lotsofstuff", type = "character", nargs = "+") args <- parser$parse_args(c("--lotsofstuff", rep("stuff", 1000))) expect_equal(args$lotsofstuff, rep("stuff", 1000)) # Bug found by @miker985 test_that("we can action = 'append' with a default list", { parser <- argparse::ArgumentParser() parser$add_argument("--test-dim", dest = "dims", action = "append", default = c("year", "sex", "age")) args <- parser$parse_args(c("--test-dim", "race")) expect_equal(args$dims, c("year", "sex", "age", "race")) }) }) # Bug found by Erick Rocha Fonseca context("Unicode arguments/options") test_that("Unicode support works if Python and OS sufficient", { skip_if_not(detects_python()) skip_on_os("windows") # Didn't work on win-builder skip_on_cran() # Didn't work on Debian Clang did_find_python3 <- findpython::can_find_python_cmd(minimum_version = "3.0", required_modules = c("argparse", "json|simplejson"), silent = TRUE) if (!did_find_python3) skip("Need at least Python 3.0 for Unicode support") p <- ArgumentParser(python_cmd = attr(did_find_python3, "python_cmd")) p$add_argument("name") expect_equal(p$parse_args("\u8292\u679C"), list(name = "\u8292\u679C")) # 芒果 }) test_that("Unicode attempt throws error if Python or OS not sufficient", { skip_if_not(detects_python()) skip_on_os("windows") # Didn't work on AppVeyor skip_on_cran() # Didn't work on Debian Clang did_find_python2 <- findpython::can_find_python_cmd(maximum_version = "2.7", required_modules = c("argparse", "json|simplejson"), silent = TRUE) if (!did_find_python2) skip("Need Python 2 to guarantee throws Unicode error") p <- ArgumentParser(python_cmd = attr(did_find_python2, "python_cmd")) p$add_argument("name") expect_error(p$parse_args("\u8292\u679C"), "Non-ASCII character detected.") # 芒果 }) # Mutually exclusive groups is a feature request by Vince Reuter context("Mutually exclusive groups") test_that("mutually exclusive groups works as expected", { skip_if_not(detects_python()) parser <- ArgumentParser(prog = "PROG") group <- parser$add_mutually_exclusive_group() group$add_argument("--foo", action = "store_true") group$add_argument("--bar", action = "store_false") arguments <- parser$parse_args("--foo") expect_true(arguments$bar) expect_true(arguments$foo) arguments <- parser$parse_args("--bar") expect_false(arguments$bar) expect_false(arguments$foo) expect_error(parser$parse_args(c("--foo", "--bar")), "argument --bar: not allowed with argument --foo") parser <- ArgumentParser(prog = "PROG") group <- parser$add_mutually_exclusive_group(required = TRUE) group$add_argument("--foo", action = "store_true") group$add_argument("--bar", action = "store_false") expect_error(parser$parse_args(character()), " one of the arguments --foo --bar is required") }) # argument groups is a feature request by Dario Beraldi context("Add argument group") test_that("add argument group works as expected", { skip_if_not(detects_python()) parser <- ArgumentParser(prog = "PROG", add_help = FALSE) group1 <- parser$add_argument_group("group1", "group1 description") group1$add_argument("foo", help = "foo help") group2 <- parser$add_argument_group("group2", "group2 description") group2$add_argument("--bar", help = "bar help") expect_output(parser$print_help(), "group1 description") expect_output(parser$print_help(), "group2 description") }) # subparser support is a feature request by Zebulun Arendsee context("Supparser support") test_that("sub parsers work as expected", { skip_if_not(detects_python()) # create the top-level parser parser <- ArgumentParser(prog = "PROG") parser$add_argument("--foo", action = "store_true", help = "foo help") subparsers <- parser$add_subparsers(help = "sub-command help") # create the parser for the "a" command parser_a <- subparsers$add_parser("a", help = "a help") parser_a$add_argument("bar", type = "integer", help = "bar help") # create the parser for the "b" command parser_b <- subparsers$add_parser("b", help = "b help") parser_b$add_argument("--baz", choices = "XYZ", help = "baz help") # parse some argument lists arguments <- parser$parse_args(c("a", "12")) expect_equal(arguments$bar, 12) expect_equal(arguments$foo, FALSE) arguments <- parser$parse_args(c("--foo", "b", "--baz", "Z")) expect_equal(arguments$baz, "Z") expect_equal(arguments$foo, TRUE) expect_output(parser$print_help(), "sub-command help") expect_output(parser_a$print_help(), "usage: PROG a") expect_output(parser_b$print_help(), "usage: PROG b") }) context("Paths that quit()") test_that("Paths that quit()", { skip_if_not(detects_python()) skip_on_os("windows") cmd <- file.path(R.home(), "bin/Rscript") skip_if(Sys.which(cmd) == "") expect_equal(system2(cmd, c("scripts/test_version.R", "--version"), stdout = TRUE), "1.0.1") help <- system2(cmd, c("scripts/test_help.R", "--help"), stdout = TRUE, stderr = TRUE) expect_equal("usage: scripts/test_help.R [-h]", help[1]) expect_equal(" -h, --help show this help message and exit", help[4]) }) argparse/tests/testthat/scripts/0000755000175000017500000000000014102555744016710 5ustar nileshnileshargparse/tests/testthat/scripts/test_help.R0000644000175000017500000000007114102555027021012 0ustar nileshnileshlibrary("argparse") p <- ArgumentParser() p$parse_args() argparse/tests/testthat/scripts/test_version.R0000644000175000017500000000020214102554207021542 0ustar nileshnileshlibrary("argparse") p <- ArgumentParser() p$add_argument("-v", "--version", action = "version", version = "1.0.1") p$parse_args() argparse/tests/run-all.R0000644000175000017500000000005413210072125015037 0ustar nileshnileshlibrary("testthat") test_check("argparse") argparse/R/0000755000175000017500000000000014147747752012433 5ustar nileshnileshargparse/R/argparse.R0000644000175000017500000003606414147743044014361 0ustar nileshnilesh# Copyright (c) 2012-2021 Trevor L. Davis # # This file is free software: you may copy, redistribute and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 2 of the License, or (at your # option) any later version. # # This file is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # This file incorporates work from the argparse module in Python 2.7.3. # # Copyright (c) 2001-2012 Python Software Foundation; All Rights Reserved # # See (inst/)COPYRIGHTS or http://docs.python.org/2/license.html for the full # Python (GPL-compatible) license stack. #' Create a command line parser #' #' \code{ArgumentParser} creates a parser object that acts as #' a wrapper to Python's argparse module #' #' @param ... Arguments cleaned and passed to Pythons argparse.ArgumentParser() #' @param python_cmd Python executable for \code{argparse} to use. #' Must have argparse and json modules (automatically included Python 2.7 and 3.2+). #' If you need Unicode argument support then you must use Python 3.0+. #' Default will be to use \code{findpython} package to find suitable Python binary. #' @return \code{ArgumentParser} returns a parser object which contains #' an \code{add_argument} function to add arguments to the parser, #' a \code{parse_args} function to parse command line arguments into #' a list, a \code{print_help} and \code{print_usage} function to print #' usage information. See code examples, package vignette, #' and corresponding python module for more information on how to use it. #' #' @references Python's \code{argparse} library, which this package is based on, #' is described here: \url{https://docs.python.org/3/library/argparse.html} #' #' @import jsonlite #' @import R6 #' @export #' @examples #' #' if (argparse:::detects_python()) { #' parser <- ArgumentParser(description='Process some integers') #' parser$add_argument('integers', metavar='N', type = "integer", nargs='+', #' help='an integer for the accumulator') #' parser$add_argument('--sum', dest='accumulate', action='store_const', #' const='sum', default='max', #' help='sum the integers (default: find the max)') #' parser$print_help() #' # default args for ArgumentParser()$parse_args are commandArgs(TRUE) #' # which is what you'd want for an Rscript but not for interactive use #' args <- parser$parse_args(c("--sum", "1", "2", "3")) #' accumulate_fn <- get(args$accumulate) #' print(accumulate_fn(args$integers)) #' } ArgumentParser <- function(..., python_cmd = NULL) { # nolint python_cmd <- find_python_cmd(python_cmd) assert_python_cmd(python_cmd) initial_python_code <- c("import argparse", "try:", " import json", "except ImportError:", " import simplejson as json", "", sprintf("parser = argparse.ArgumentParser(%s)", convert_..._to_arguments("ArgumentParser", ...)), "") Parser$new(Code$new(python_cmd, initial_python_code), "parser") } Code <- R6Class("Code", # nolint public = list( append = function(new_code) { private$code <- c(private$code, new_code) }, run = function(new_code) { code <- c(private$code, new_code) suppressWarnings(system2(private$cmd, input = code, stdout = TRUE, stderr = TRUE)) }, initialize = function(cmd, code = character(0)) { private$cmd <- cmd private$code <- code } ), private = list(code = NULL, cmd = NULL) ) Group <- R6Class("Group", # nolint public = list( initialize = function(python_code, name) { private$python_code <- python_code private$name <- name }, add_argument = function(...) { private$python_code$append(sprintf("%s.add_argument(%s)", private$name, convert_..._to_arguments("add_argument", ...))) return(invisible(NULL)) } ), private = list(python_code = NULL, name = NULL) ) Subparsers <- R6Class("Subparsers", # nolint public = list( initialize = function(python_code, name) { private$python_code <- python_code private$name <- name }, add_parser = function(...) { parser_name <- paste0(private$name, "_subparser", private$n_subparsers) private$n_subparsers <- private$n_subparsers + 1 private$python_code$append(sprintf("%s = %s.add_parser(%s)", parser_name, private$name, convert_..._to_arguments("ArgumentParser", ...))) Parser$new(private$python_code, parser_name) } ), private = list(python_code = NULL, name = NULL, n_subparsers = 0) ) Parser <- R6Class("Parser", # nolint public = list( parse_args = function(args = commandArgs(TRUE)) { new_code <- c(sprintf("args = %s.parse_args([%s])", private$name, paste(sprintf("'%s'", args), collapse = ", ")), "print(json.dumps(args.__dict__, sort_keys=True))") output <- private$python_code$run(new_code) parse_args_output(output) }, parse_known_args = function(args = commandArgs(TRUE)) { new_code <- c(sprintf("args_remainder = %s.parse_known_args([%s])", private$name, paste(sprintf("'%s'", args), collapse = ", ")), "print(json.dumps((args_remainder[0].__dict__, args_remainder[1])))") output <- private$python_code$run(new_code) parse_args_output(output) }, print_help = function() { cat(private$python_code$run(sprintf("%s.print_help()", private$name)), sep = "\n") invisible(NULL) }, print_usage = function() { cat(private$python_code$run(sprintf("%s.print_usage()", private$name)), sep = "\n") invisible(NULL) }, add_argument = function(...) { private$python_code$append(sprintf("%s.add_argument(%s)", private$name, convert_..._to_arguments("add_argument", ...))) invisible(NULL) }, add_argument_group = function(...) { group_name <- paste0(private$name, "_group", private$n_groups) private$n_groups <- private$n_groups + 1 private$python_code$append(sprintf("%s = %s.add_argument_group(%s)", group_name, private$name, convert_..._to_arguments("add_argument", ...))) Group$new(private$python_code, group_name) }, add_mutually_exclusive_group = function(required = FALSE) { group_name <- paste0(private$name, "_mutually_exclusive_group", private$n_mutually_exclusive_groups) private$n_mutually_exclusive_groups <- private$n_mutually_exclusive_groups + 1 private$python_code$append(sprintf("%s = %s.add_mutually_exclusive_group(%s)", group_name, private$name, ifelse(required, "required=True", ""))) Group$new(private$python_code, group_name) }, add_subparsers = function(...) { subparsers_name <- paste0(private$name, "_subparsers") private$python_code$append(sprintf("%s = %s.add_subparsers(%s)", subparsers_name, private$name, convert_..._to_arguments("add_argument", ...))) Subparsers$new(private$python_code, subparsers_name) }, initialize = function(python_code, name) { private$python_code <- python_code private$name <- name } ), private = list(python_code = NULL, name = NULL, n_mutually_exclusive_groups = 0, n_groups = 0) ) parse_args_output <- function(output) { if (grepl("^usage:", output[1])) { has_positional_arguments <- any(grepl("^positional arguments:", output)) has_optional_arguments <- any(grepl("^optional arguments:|^options:", output)) if (has_positional_arguments || has_optional_arguments) { .print_message_and_exit(output, "help requested:") } else { .stop(output, "parse error:") } } else if (grepl("^Traceback", output[1])) { .stop(output, "Error: python error") } else if (any(grepl("^SyntaxError: Non-ASCII character", output))) { message <- paste("Non-ASCII character detected.", "If you wish to use Unicode arguments/options", "please upgrade to Python 3.2+", "Please see file INSTALL for more details.") .stop(message, "non-ascii character error:") } else if (any(grepl("^SyntaxError: positional argument follows keyword argument", output)) || grepl("^SyntaxError: non-keyword arg after keyword arg", output[2])) { message <- "Positional argument following keyword argument." .stop(message, "syntax error:") } else if (grepl("^\\{|^\\[", output)) { args <- jsonlite::fromJSON(paste(output, collapse = "")) return(args) } else { # presumably version number request .print_message_and_exit(output, "version requested:") } } # @param argument argument to be converted from R to Python convert_argument <- function(argument, as_list = FALSE) { if (is.character(argument)) argument <- shQuote(argument, type = "sh") if (is.numeric(argument)) argument <- as.character(argument) if (is.logical(argument)) argument <- ifelse(argument, "True", "False") if (is.null(argument)) argument <- "None" if (as_list) { argument <- sprintf("[%s]", paste(argument, collapse = ", ")) } else if (length(argument) > 1) { argument <- sprintf("(%s)", paste(argument, collapse = ", ")) } argument } get_python_type <- function(type, proposed_arguments) { python_type <- switch(type, character = "str", double = "float", integer = "int", logical = "bool", stop(paste(sprintf("type %s not supported,", type), "supported types:", "'logical', 'integer', 'double' or 'character'"))) # warn if type set to "logical" and action set to "store" if (python_type == "bool" && any(grepl("action='store'", proposed_arguments))) warning("You almost certainly want to use action='store_true' or action='store_false' instead") sprintf("type=%s", python_type) } should_as_list <- function(name, argument_list) { if (name == "default" && (argument_list[["action"]] %||% "store") == "append") { TRUE } else { FALSE } } `%||%` <- function(x, y) if (is.null(x)) y else x # nolint # @param mode Either "add_argument" or "ArgumentParser" convert_..._to_arguments <- function(mode, ...) { # nolint argument_list <- list(...) argument_names <- names(argument_list) if (is.null(argument_names)) argument_names <- rep_len("", length(argument_list)) equals <- ifelse(argument_names == "", "", "=") proposed_arguments <- c() for (ii in seq_along(argument_list)) { name <- argument_names[ii] equal <- equals[ii] as_list <- should_as_list(name, argument_list) argument <- convert_argument(argument_list[[ii]], as_list) proposed_arguments <- append(proposed_arguments, paste0(name, equal, argument)) } # Make sure types are what Python wants if (mode == "add_argument" && any(grepl("type=", proposed_arguments))) { ii <- grep("type=", proposed_arguments) type <- argument_list[[ii]] proposed_arguments[ii] <- get_python_type(type, proposed_arguments) } # Don't put quotes around formatter_class argument if (mode == "ArgumentParser" && any(grepl("formatter_class=", proposed_arguments))) { ii <- grep("formatter_class=", proposed_arguments) formatter_class <- argument_list[[ii]] proposed_arguments[ii] <- sprintf("formatter_class=%s", formatter_class) } # Set right default prog name if not specified, if possible # Do last to not screw up other fixes with prog insertion if (mode == "ArgumentParser" && needs_prog(argument_names)) { prog <- get_Rscript_filename() if (is.na(prog)) prog <- "PROGRAM" proposed_arguments <- c(sprintf("prog='%s'", prog), proposed_arguments) } return(paste(proposed_arguments, collapse = ", ")) } needs_prog <- function(argument_names) { if (length(argument_names) == 0L) { TRUE } else if (argument_names[1L] == "") { FALSE } else if (any(argument_names == "prog")) { FALSE } else { TRUE } } # Manually copied over from getopt to eliminate it as a dependency get_Rscript_filename <- function() { # nolint prog <- sub("--file=", "", grep("--file=", commandArgs(), value = TRUE)[1]) if (.Platform$OS.type == "windows") { prog <- gsub("\\\\", "\\\\\\\\", prog) } prog } # Internal function to check python cmd is okay # @param python_cmd Python cmd to use assert_python_cmd <- function(python_cmd) { if (!findpython::is_python_sufficient(python_cmd, required_modules = c("argparse", "json | simplejson"))) { stop(paste(sprintf("python executable %s either is not installed,", python_cmd), "is not on the path, or does not have argparse, json modules", "please see INSTALL file")) } } detects_python <- function() { python_cmd <- try(find_python_cmd()) !inherits(python_cmd, "try-error") } # Internal function to find python cmd # @param python_cmd Python cmd to use find_python_cmd <- function(python_cmd = NULL) { if (is.null(python_cmd)) { python_cmd <- getOption("python_cmd") } if (is.null(python_cmd)) { required_modules <- c("argparse", "json | simplejson") did_find_python3 <- findpython::can_find_python_cmd(minimum_version = "3.0", required_modules = required_modules, silent = TRUE) if (did_find_python3) { python_cmd <- attr(did_find_python3, "python_cmd") } else { python_cmd <- findpython::find_python_cmd(required_modules = required_modules) } } python_cmd } .stop <- function(message, r_note) { stop(paste(r_note, paste(message, collapse = "\n"), sep = "\n")) } # Internal function to print message .print_message_and_exit <- function(message, r_note) { if (interactive()) { .stop(message, r_note) } else { cat(message, sep = "\n") quit(status = 0) } } argparse/inst/0000755000175000017500000000000014150001761013160 5ustar nileshnileshargparse/inst/doc/0000755000175000017500000000000014150001761013725 5ustar nileshnileshargparse/inst/doc/argparse.R0000644000175000017500000000552214150001761015660 0ustar nileshnilesh## ----echo=FALSE--------------------------------------------------------------- library("knitr") rscript_executable <- paste(file.path(R.home(), "bin", "Rscript"), "--vanilla") opts_knit$set(root.dir = system.file("exec", package = "argparse")) # to access the "Rscript files" opts_chunk$set(comment = NA, echo = FALSE) list_file_command <- "ls" chmod_command <- "chmod ug+x display_file.R example.R" path_command <- "export PATH=$PATH:`pwd`" run_command <- function(string) suppressWarnings(cat(system(string, intern = TRUE), sep = "\n")) ## ----------------------------------------------------------------------------- run_command(sprintf("%s", list_file_command)) command <- "display_file.R example.R" # to show file ## ----------------------------------------------------------------------------- run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R --help" # same as system("Rscript example.R -h") ## ----------------------------------------------------------------------------- run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R" # rely only on defaults ## ----------------------------------------------------------------------------- run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R --mean=10 --sd=10 --count=3" ## ----------------------------------------------------------------------------- run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R --quiet -c 4 --generator=\"runif\"" # same as above but "quiet" ## ----------------------------------------------------------------------------- run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R --silent -m 5" # same as above but "quiet" ## ----------------------------------------------------------------------------- run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R -c 100 -c 2 -c 1000 -c 7" # same as above but "quiet" ## ----------------------------------------------------------------------------- run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "display_file.R --help" ## ----------------------------------------------------------------------------- run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "display_file.R --add_numbers display_file.R" ## ----------------------------------------------------------------------------- run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "display_file.R non_existent_file.txt" ## ----------------------------------------------------------------------------- run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "display_file.R" ## ----------------------------------------------------------------------------- run_command(sprintf("%s %s 2>&1", rscript_executable, command)) argparse/inst/doc/argparse.html0000644000175000017500000004064414150001761016427 0ustar nileshnilesh argparse Command Line Argument Parsing

argparse Command Line Argument Parsing

argparse is a command line argument parser inspired by Python’s “argparse” library. Use this with Rscript to write “#!”-shebang scripts that accept short and long flags/options and positional arguments, generate a usage statement, and set default values for options that are not specified on the command line.

In our working directory we have two example R scripts, named “example.R” and “display_file.R” illustrating the use of the argparse package.

bash$ ls

display_file.R
example.R

In order for a *nix system to recognize a “#!”-shebang line you need to mark the file executable with the chmod command, it also helps to add the directory containing your Rscripts to your path:

bash$ chmod ug+x display_file.R example.R

bash$ display_file.R example.R

Here is what “example.R” contains:

bash$ display_file.R example.R

#!/usr/bin/env Rscript
# Copyright 2012-2013 Trevor L Davis <trevor.l.davis@gmail.com>
# Copyright 2008 Allen Day
#  
#  This file is free software: you may copy, redistribute and/or modify it  
#  under the terms of the GNU General Public License as published by the  
#  Free Software Foundation, either version 2 of the License, or (at your  
#  option) any later version.  
#  
#  This file is distributed in the hope that it will be useful, but  
#  WITHOUT ANY WARRANTY; without even the implied warranty of  
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  
#  General Public License for more details.  
#  
#  You should have received a copy of the GNU General Public License  
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.  
suppressPackageStartupMessages(library("argparse"))

# create parser object
parser <- ArgumentParser()

# specify our desired options 
# by default ArgumentParser will add an help option 
parser$add_argument("-v", "--verbose", action="store_true", default=TRUE,
    help="Print extra output [default]")
parser$add_argument("-q", "--quietly", action="store_false", 
    dest="verbose", help="Print little output")
parser$add_argument("-c", "--count", type="integer", default=5, 
    help="Number of random normals to generate [default %(default)s]",
    metavar="number")
parser$add_argument("--generator", default="rnorm", 
    help = "Function to generate random deviates [default \"%(default)s\"]")
parser$add_argument("--mean", default=0, type="double",
    help="Mean if generator == \"rnorm\" [default %(default)s]")
parser$add_argument("--sd", default=1, type="double",
        metavar="standard deviation",
    help="Standard deviation if generator == \"rnorm\" [default %(default)s]")
                                        
# get command line options, if help option encountered print help and exit,
# otherwise if options not found on command line then set defaults, 
args <- parser$parse_args()

# print some progress messages to stderr if "quietly" wasn't requested
if ( args$verbose ) { 
    write("writing some verbose output to standard error...\n", stderr()) 
}

# do some operations based on user input
if( args$generator == "rnorm") {
    cat(paste(rnorm(args$count, mean=args$mean, sd=args$sd), collapse="\n"))
} else {
    cat(paste(do.call(args$generator, list(args$count)), collapse="\n"))
}
cat("\n")

By default argparse will generate a help message if it encounters --help or -h on the command line. Note how %(default)s in the example program was replaced by the actual default values in the help statement that argparse generated.

bash$ example.R –help

usage: example.R [-h] [-v] [-q] [-c number] [--generator GENERATOR] [--mean MEAN]
                 [--sd standard deviation]

options:
  -h, --help            show this help message and exit
  -v, --verbose         Print extra output [default]
  -q, --quietly         Print little output
  -c number, --count number
                        Number of random normals to generate [default 5]
  --generator GENERATOR
                        Function to generate random deviates [default "rnorm"]
  --mean MEAN           Mean if generator == "rnorm" [default 0]
  --sd standard deviation
                        Standard deviation if generator == "rnorm" [default 1]

If you specify default values when creating your ArgumentParser then argparse will use them as expected.

bash$ example.R

writing some verbose output to standard error...

0.810728115060181
1.09206646727706
1.70378608013885
0.201355429503964
-0.00504818748381247

Or you can specify your own values.

bash$ example.R –mean=10 –sd=10 –count=3

writing some verbose output to standard error...

18.7400775590623
15.9739894736902
23.9043389427129

If you remember from the example program that --quiet had action="store_false" and dest="verbose". This means that --quiet is a switch that turns the verbose option from its default value of TRUE to FALSE. Note how the verbose and quiet options store their value in the exact same variable.

bash$ example.R –quiet -c 4 –generator=“runif”

0.0368707608431578
0.252408046973869
0.470769245177507
0.661251338431612

If you specify an illegal flag then will print out a usage message and an error message and quit.

bash$ example.R –silent -m 5

Error in .stop(output, "parse error:") : parse error:
usage: example.R [-h] [-v] [-q] [-c number] [--generator GENERATOR] [--mean MEAN]
                 [--sd standard deviation]
example.R: error: unrecognized arguments: --silent -m 5
Calls: <Anonymous> -> parse_args_output -> .stop
Execution halted

If you specify the same option multiple times then will use the value of the last option specified.

bash$ example.R -c 100 -c 2 -c 1000 -c 7

writing some verbose output to standard error...

0.521819620099909
-1.00136095587277
-0.516707752141829
-0.136643072496566
-0.000388440250166777
-0.118239108707788
1.28510853122564

argparse can also parse positional arguments. Below we give an example program display_file.R, which is a program that prints out the contents of a single file (the required positional argument, not an optional argument) and which accepts the normal help option as well as an option to add line numbers to the output.

bash$ display_file.R –help

usage: display_file.R [-h] [-n] file

positional arguments:
  file               File to be displayed

options:
  -h, --help         show this help message and exit
  -n, --add_numbers  Print line number at the beginning of each line [default]

bash$ display_file.R –add_numbers display_file.R

1 #!/usr/bin/env Rscript
2 # Copyright 2012-2013 Trevor L Davis <trevor.l.davis@gmail.com>
3 #  
4 #  This file is free software: you may copy, redistribute and/or modify it  
5 #  under the terms of the GNU General Public License as published by the  
6 #  Free Software Foundation, either version 2 of the License, or (at your  
7 #  option) any later version.  
8 #  
9 #  This file is distributed in the hope that it will be useful, but  
10 #  WITHOUT ANY WARRANTY; without even the implied warranty of  
11 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  
12 #  General Public License for more details.  
13 #  
14 #  You should have received a copy of the GNU General Public License  
15 #  along with this program.  If not, see <http://www.gnu.org/licenses/>.  
16 suppressPackageStartupMessages(library("argparse"))
17 
18 parser <- ArgumentParser()
19 parser$add_argument("-n", "--add_numbers", action="store_true", default=FALSE,
20     help="Print line number at the beginning of each line [default]")
21 parser$add_argument("file", nargs=1, help="File to be displayed")
22 
23 args <- parser$parse_args()
24 
25 file <- args$file
26 
27 if( file.access(file) == -1) {
28     stop(sprintf("Specified file ( %s ) does not exist", file))
29 } else {
30     file_text <- readLines(file)
31 }
32 
33 if(args$add_numbers) {
34     cat(paste(1:length(file_text), file_text), sep = "\n")
35 } else {
36     cat(file_text, sep = "\n")
37 }

bash$ display_file.R non_existent_file.txt

Error: Specified file ( non_existent_file.txt ) does not exist
Execution halted

bash$ display_file.R

Error in .stop(output, "parse error:") : parse error:
usage: display_file.R [-h] [-n] file
display_file.R: error: the following arguments are required: file
Calls: <Anonymous> -> parse_args_output -> .stop
Execution halted
argparse/inst/doc/argparse.Rmd0000644000175000017500000001112214115723707016206 0ustar nileshnilesh--- title: "argparse Command Line Argument Parsing" output: rmarkdown::html_vignette vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{argparse Command Line Argument Parsing} %\VignetteEncoding{UTF-8} --- argparse is a command line argument parser inspired by Python's "argparse" library. Use this with Rscript to write "#!"-shebang scripts that accept short and long flags/options and positional arguments, generate a usage statement, and set default values for options that are not specified on the command line. ```{r echo=FALSE} library("knitr") rscript_executable <- paste(file.path(R.home(), "bin", "Rscript"), "--vanilla") opts_knit$set(root.dir = system.file("exec", package = "argparse")) # to access the "Rscript files" opts_chunk$set(comment = NA, echo = FALSE) list_file_command <- "ls" chmod_command <- "chmod ug+x display_file.R example.R" path_command <- "export PATH=$PATH:`pwd`" run_command <- function(string) suppressWarnings(cat(system(string, intern = TRUE), sep = "\n")) ``` In our working directory we have two example R scripts, named "example.R" and "display_file.R" illustrating the use of the argparse package. **`r paste("bash$", list_file_command)`** ```{r} run_command(sprintf("%s", list_file_command)) command <- "display_file.R example.R" # to show file ``` In order for a \*nix system to recognize a "\#!"-shebang line you need to mark the file executable with the ``chmod`` command, it also helps to add the directory containing your Rscripts to your path: **`r paste("bash$", chmod_command)`** **`r paste("bash$", command)`** Here is what "example.R" contains: **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R --help" # same as system("Rscript example.R -h") ``` By default ``argparse`` will generate a help message if it encounters ``--help`` or ``-h`` on the command line. Note how ``%(default)s`` in the example program was replaced by the actual default values in the help statement that ``argparse`` generated. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R" # rely only on defaults ``` If you specify default values when creating your ``ArgumentParser`` then ``argparse`` will use them as expected. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R --mean=10 --sd=10 --count=3" ``` Or you can specify your own values. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R --quiet -c 4 --generator=\"runif\"" # same as above but "quiet" ``` If you remember from the example program that ``--quiet`` had ``action="store_false"`` and ``dest="verbose"``. This means that ``--quiet`` is a switch that turns the ``verbose`` option from its default value of ``TRUE`` to ``FALSE``. Note how the ``verbose`` and ``quiet`` options store their value in the exact same variable. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R --silent -m 5" # same as above but "quiet" ``` If you specify an illegal flag then \emph{argparse} will print out a usage message and an error message and quit. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "example.R -c 100 -c 2 -c 1000 -c 7" # same as above but "quiet" ``` If you specify the same option multiple times then \emph{argparse} will use the value of the last option specified. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "display_file.R --help" ``` ``argparse`` can also parse positional arguments. Below we give an example program ``display_file.R``, which is a program that prints out the contents of a single file (the required positional argument, not an optional argument) and which accepts the normal help option as well as an option to add line numbers to the output. **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "display_file.R --add_numbers display_file.R" ``` **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "display_file.R non_existent_file.txt" ``` **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) command <- "display_file.R" ``` **`r paste("bash$", command)`** ```{r} run_command(sprintf("%s %s 2>&1", rscript_executable, command)) ``` argparse/inst/COPYRIGHTS0000644000175000017500000003214114102536147014607 0ustar nileshnileshFormat: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Files: * Copyright: 2012-2021 Trevor L Davis License: GPL-2+ File: exec/example.R Copyright: 2008 Allen Day 2012-2013 Trevor L Davis License: GPL-2+ File: R/argparse.R Copyright: 1990-2009 Python Software Foundation 2012-2021 Trevor L Davis License: GPL-2+ and Python-2.7.3 Comment: The FSF considers recent Python licenses (post Python version 2.1.1) to be GPL-compatible (http://www.gnu.org/licenses/license-list.html#Python). Note that the "Python License" the FSF has on their website (http://directory.fsf.org/wiki?title=License:Python2.0.1) is the full Python license stack which includes the historical modified CNRI and BEOPEN licenses and not merely the PSF License Agreement at the top. In 2001 ago the FSF negotiated with CNRI to change the wording of an earlier Python license (https://www.gnu.org/licenses/license-list.html#PythonOld, http://directory.fsf.org/wiki/License:Python1.6b1) because it had an overly strong "governed in Virginia" clause but later Python license stacks have a version of the CNRI license with a weakened enough clause to satisfy the FSF lawyers as being GPL-compatible. File: tests/test-argparse.R Copyright: 1990-2009 Python Software Foundation 2012-2021 Trevor L Davis License: GPL-2+ and Python-2.7.3 Comment: The FSF considers recent Python licenses (post Python version 2.1.1) to be GPL-compatible (http://www.gnu.org/licenses/license-list.html#Python). Note that the "Python License" the FSF has on their website (http://directory.fsf.org/wiki?title=License:Python2.0.1) is the full Python license stack which includes the historical modified CNRI and BEOPEN licenses and not merely the PSF License Agreement at the top. In 2001 ago the FSF negotiated with CNRI to change the wording of an earlier Python license (https://www.gnu.org/licenses/license-list.html#PythonOld, http://directory.fsf.org/wiki/License:Python1.6b1) because it had an overly strong "governed in Virginia" clause but later Python license stacks have a version of the CNRI license with a weakened enough clause to satisfy the FSF lawyers as being GPL-compatible. License: GPL-2+ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this package; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA . The full text of the GNU General Public License version 2 can be found in the file COPYING (source) or `R_HOME/share/licenses/GPL-2' (installed). License: Python-2.7.3 PSF LICENSE AGREEMENT FOR PYTHON 2.7.3 . 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using Python 2.7.3 software in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 2.7.3 alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright © 2001-2009 Python Software Foundation; All Rights Reserved" are retained in Python 2.7.3 alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python 2.7.3 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 2.7.3. 4. PSF is making Python 2.7.3 available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.7.3 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.7.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.7.3, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By copying, installing or otherwise using Python 2.7.3, Licensee agrees to be bound by the terms and conditions of this License Agreement. . BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 . BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 . 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization ("Licensee") accessing and otherwise using this software in source or binary form and its associated documentation ("the Software"). 2. Subject to the terms and conditions of this BeOpen Python License Agreement, BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use the Software alone or in any derivative version, provided, however, that the BeOpen Python License is retained in the Software, alone or in any derivative version prepared by Licensee. 3. BeOpen is making the Software available to Licensee on an "AS IS" basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 5. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 6. This License Agreement shall be governed by and interpreted in all respects by the law of the State of California, excluding conflict of law provisions. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between BeOpen and Licensee. This License Agreement does not grant permission to use BeOpen trademarks or trade names in a trademark sense to endorse or promote products or services of Licensee, or any third party. As an exception, the "BeOpen Python" logos available at http://www.pythonlabs.com/logos.html may be used according to the permissions granted on that web page. 7. By copying, installing or otherwise using the software, Licensee agrees to be bound by the terms and conditions of this License Agreement. . CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 . 1. This LICENSE AGREEMENT is between the Corporation for National Research Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191 ("CNRI"), and the Individual or Organization ("Licensee") accessing and otherwise using Python 1.6.1 software in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, CNRI hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6.1 alone or in any derivative version, provided, however, that CNRI's License Agreement and CNRI's notice of copyright, i.e., "Copyright © 1995-2001 Corporation for National Research Initiatives; All Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version prepared by Licensee. Alternately, in lieu of CNRI's License Agreement, Licensee may substitute the following text (omitting the quotes): "Python 1.6.1 is made available subject to the terms and conditions in CNRI's License Agreement. This Agreement together with Python 1.6.1 may be located on the Internet using the following unique, persistent identifier (known as a handle): 1895.22/1013. This Agreement may also be obtained from a proxy server on the Internet using the following URL: http://hdl.handle.net/1895.22/1013." 3. In the event Licensee prepares a derivative work that is based on or incorporates Python 1.6.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 1.6.1. 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. This License Agreement shall be governed by the federal intellectual property law of the United States, including without limitation the federal copyright law, and, to the extent such U.S. federal law does not apply, by the law of the Commonwealth of Virginia, excluding Virginia's conflict of law provisions. Notwithstanding the foregoing, with regard to derivative works based on Python 1.6.1 that incorporate non-separable material that was previously distributed under the GNU General Public License (GPL), the law of the Commonwealth of Virginia shall govern this License Agreement only as to issues arising under or with respect to Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between CNRI and Licensee. This License Agreement does not grant permission to use CNRI trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By clicking on the "ACCEPT" button where indicated, or by copying, installing or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and conditions of this License Agreement. . ACCEPT . CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 . Copyright © 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands. All rights reserved. . Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. . STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. argparse/NAMESPACE0000644000175000017500000000014114134314512013421 0ustar nileshnilesh# Generated by roxygen2: do not edit by hand export(ArgumentParser) import(R6) import(jsonlite)