Skip to content

Commit

Permalink
Finished version 1.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
matejak committed Jul 8, 2016
1 parent a9de0f8 commit 1626c91
Show file tree
Hide file tree
Showing 20 changed files with 234 additions and 128 deletions.
4 changes: 2 additions & 2 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
1.2.0a (2016-07-20)
-------------------
1.2.0 (2016-07-08)
------------------

New features:

Expand Down
8 changes: 4 additions & 4 deletions bin/argbash.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/bin/bash

VERSION=2.0.0a
VERSION=1.2.0
# DEFINE_SCRIPT_DIR()
# ARG_POSITIONAL_SINGLE([input],[The input template file])
# _ARG_POSITIONAL_SINGLE([input],[The input template file])
# ARG_OPTIONAL_SINGLE([output],[o],[Name of the output file (pass '-' for stdout)],[-])
# ARG_OPTIONAL_BOOLEAN([standalone],[],[Whether the parsing code is in a standalone file.])
# ARG_OPTIONAL_REPEATED([search],[I],[Directories to search for the wrapped scripts (directory of the template will be added to the end of the list)],["."])
Expand All @@ -12,7 +12,7 @@ VERSION=2.0.0a

# ARGBASH_GO()
# needed because of Argbash --> m4_ignore([
### START OF CODE GENERATED BY ARGBASH v2.0.0a one line above ###
### START OF CODE GENERATED BY ARGBASH v1.2.0 one line above ###
# Argbash is a bash code generator used to get arguments parsing right.
# Argbash is FREE SOFTWARE, know your rights: https://github.com/matejak/argbash
# THE DEFAULTS INITIALIZATION --- POSITIONALS
Expand Down Expand Up @@ -84,7 +84,7 @@ test ${#POSITIONALS[@]} -lt 1 && { ( echo "FATAL ERROR: Not enough positional ar
test ${#POSITIONALS[@]} -gt 1 && { ( echo "FATAL ERROR: There were spurious positional arguments --- we expect exactly 1, but got ${#POSITIONALS[@]} (the last one was: '${POSITIONALS[@]: -1}')."; print_help ) >&2; exit 1; }
for (( ii = 0; ii < ${#POSITIONALS[@]}; ii++))
do
eval "${POSITIONAL_NAMES[$ii]}=\"${POSITIONALS[$ii]}\"" || { echo "Error during argument parsing, possibly an argbash bug." >&2; exit 1; }
eval "${POSITIONAL_NAMES[$ii]}=\"${POSITIONALS[$ii]}\"" || { echo "Error during argument parsing, possibly an Argbash bug." >&2; exit 1; }
done
# OTHER STUFF GENERATED BY Argbash
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
Expand Down
8 changes: 6 additions & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = []
extensions = [
'sphinx.ext.mathjax',
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
Expand Down Expand Up @@ -122,7 +124,9 @@
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
html_theme_options = {
"fixed_sidebar": True,
}

# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
Expand Down
2 changes: 1 addition & 1 deletion doc/example.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The source code for the minimal example could look like this:
Here, we can notice multiple notable things:

#. Definitions of arguments are placed before the script body.
From Bash point of view, they are commented out, so the "template" can be a syntactically valid script.
From ``bash`` point of view, they are commented out, so the "template" can be a syntactically valid script.

#. You access the values of argument ``foo-bar`` as ``$_ARG_FOO_BAR`` etc. (this is covered more in-depth in :ref:`parsing_results`).

Expand Down
82 changes: 53 additions & 29 deletions doc/guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Here, the argument ``-l`` is optional of a boolean type (it is either on or off)
The common pattern is that optional arguments are not required, being there just for the case you need them.

The ``/home`` argument is a positional one.
In case of ``ls``, the positional argument has a default --- running ``ls`` without parameters is the same as running ``ls .``.
In case of ``ls``, the positional argument has a default --- running ``ls`` without parameters is the same as running ``ls "."``.
``ls`` itself accepts an arbitrary number of positional arguments and it treats them all in the same way.

On the other hand, the ``grep`` command requires at least one positional argument.
Expand All @@ -37,12 +37,13 @@ As of this version, ``Argbash`` lets you choose from:
* single-value optional arguments,
* boolean optional arguments,
* action optional arguments (i.e. the ``--version`` and ``--help`` type of args) and
* repeatable arguments that "remember" being repeated multiple times (e.g. ``--verbose``).
* incremental arguments that "remember" how many times they have been repeated (e.g. ``--verbose``) and
* repeatable arguments that sequentially store their values into an array (e.g. ``-I``).

Plus, there are convenience macros that don't relate to argument parsing, but they might help you to write better scripts.
Plus, there are convenience macros that don't relate to argument parsing, but they might help you to write better scripts and a helper that enables you to easily wrap other ``Argbash``-aware scripts without fuss.

Take a look at the API and place the declarations either to your script or in a separate file.
Let yourself be inspired by the ``resources/examples/simple.m4`` example (Bash syntax highlighting is recommended, despite the extension).
Let yourself be inspired by the ``resources/examples/simple.m4`` example (``bash`` syntax highlighting is recommended, despite the extension).

Then, run the following command to your file:

Expand All @@ -58,44 +59,54 @@ Argbash API
Nomenclature
++++++++++++

We have positional and optional arguments sorted out, so let's define some other terms now:
We have positional and optional arguments sorted out, so let's define some other terms now keeping the example of ``ls -l --sort time /home``:

* Option:
The string that identifies optional arguments on the command-line, can have a short (dash and a letter, e.g. ``-l``) or long (double dash and string, e.g. ``--sort``) form.

* Value:
In connection with optional arguments, value of an argument is the string that follows it (provided that the argument expects a value to be given).
Concerning positional arguments, it is simply the string on the command-line (whose location matches the location in which we expect the given positional argument).
So in our example, the values are ``time`` and ``home``.

* Name:
Both positional and optional arguments have a name.
In case of optional argument, the name is what appears before the double dash, e.g. name of ``--project-path`` is ``project-path``.
The long or short string (e.g. ``--project-path``, ``-p``) itself is called option.
In case of optional argument, the name is what appears after the long option's the double dash, e.g. name of ``--project-path`` is ``project-path``.
The argument's name is used in help and later in your script when you access argument's value.
Names of positional arguments are much less visible to the script's user --- one can see them only in the help message.

* Argument:
On command-line, options are followed by arguments.
An argument is the high-level concept.
On command-line, arguments are identified by options (which themselves may or may be not followed by values).
Although this is confusing, it is a common way of putting it.
Let's take ``ls -l --sort time`` again as an example :
In our example, we have

* ``-l`` --- this option doesn't accept any arguments
* ``--sort`` --- this option accepts exactly one argument (in this case, its value was ``time``).
If you don't provide one, you will get an error.
* ``-l`` --- this argument has only the option, but never accepts values.
* ``--sort`` --- this argument accepts exactly one value (in this case, the string ``time``).
If you don't provide a value, you will get an error.

``Argbash`` exposes values of passed arguments as variables.
``Argbash`` exposes values of passed arguments as environmental variables.

* Default:
In case of positional and boolean arguments, you may specify their default values.

.. note::

General notice:
There is no way of how to find out whether an argument was passed or not just by lookint at the value of the corresponding variable in the script.
``Bash`` doesn't distinguish between empty variables and variables containing an empty string.
There is no way of how to find out whether an argument was passed or not just by looking at the value of the corresponding environmental variable in the script.
``bash`` doesn't distinguish between empty variables and variables containing an empty string.
Also note that it is perfectly possible to pass an empty string as an argument value.

So let's get back to argument types.
Below, is a list of argument types and macros that you have to write to support those.
Place those macros in your files as Bash comments.
Place those macros in your files as ``bash`` comments.

Syntax
++++++

Put macro parameters in square brackets.
Parameters marked as optional can be left out blank:

The following code leaves second and last parameters blank.
Values of first and third parameters are ``verbose`` and ``Turn on verbose mode`` respectively.

Expand All @@ -113,13 +124,13 @@ Positional arguments

The argument is mandatory, unless you specify a default.

If you leave the default blank, it is understood that you don't want one.
If you leave the default blank, it is understood that you don't want one (and that the argument is mandatory).
If you really want to have an explicit default of empty string, pass a quoted empty string (i.e. ``""`` or ``''``).

* Multi-value positional argument (with optional defaults):
::

ARG_POSITIONAL_MULTI([argument-name], [help message], [number of arguments], ..., [default for the second to last (i.e. penultimate) argument (optional)], [default for the last argument (optional)])
ARG_POSITIONAL_MULTI([argument-name], [help message], [number of arguments], ..., [default for the second-to-last (i.e. penultimate) argument (optional)], [default for the last argument (optional)])

Given that your argument accepts :math:`n` values, you can specify :math:`m` defaults, :math:`(m \leq n)` for last :math:`m` values.

Expand All @@ -129,7 +140,7 @@ Positional arguments
If you pass ``val1`` and ``val2``, you will be able to retrieve ``val1``, ``val2`` and ``baz``.
If you pass nothing, or more than three values, an error will occur.

Arguments are available as a bash array (first element has index of 0).
Arguments are available as a ``bash`` array (first element has index of 0).

* End of optional arguments and beginning of positional ones (the double-dash ``--``):
::
Expand All @@ -139,8 +150,8 @@ Positional arguments
You are encouraged to add this to your script if you use both positional and optional arguments.

This pattern is known for example from the ``grep`` command.
The idea is that you specify optional arguments first and then, whatever argument follows it on the com-line, it is considered to be a positional one.
If your script accepts a ``--help`` optional argument and you want it to be recognized as positional, using the double-dash is the only way.
The idea is that you specify optional arguments first and then, whatever argument follows it, it is considered to be a positional one no matter how it looks.
For example, if your script accepts a ``--help`` optional argument and you want it to be recognized as positional, using the double-dash is the only way.

Optional arguments
++++++++++++++++++
Expand Down Expand Up @@ -168,6 +179,14 @@ Optional arguments
The argument accepts no values on command-line, but it tracks a numerical value internally.
That one increases with every argument occurence.

* Repeated optional arguments:
::

ARG_OPTIONAL_REPEATED([argument-name-long], [argument-name-short (optional)], [help message], [default (optional)])

The default default is an empty array.
The argument can be repeated multiple times, but instead of the later specifications overriding earlier ones (s.a. ``ARG_OPTIONAL_SINGLE`` does), arguments are gradually appended to an array.

* Action optional arguments (i.e. the ``--version`` and ``--help`` type of comments):
::

Expand Down Expand Up @@ -200,13 +219,13 @@ Special arguments
ARG_VERBOSE([short arg name])

Default default is 0, so you can use a ``test $_ARG_VERBOSE -ge 1`` pattern in your script.

Convenience macros
++++++++++++++++++

Plus, there are convenience macros:

* Add a line where the directory where the script is running is stored to a variable:
* Add a line where the directory where the script is running is stored in an environmental variable:
::

DEFINE_SCRIPT_DIR([variable name (optional, default is SCRIPT_DIR)])
Expand All @@ -219,7 +238,9 @@ Plus, there are convenience macros:

INCLUDE_PARSING_CODE([filename], [SCRIPT_DIR variable name (optional, default is SCRIPT_DIR)])

You have to use ``DEFINE_SCRIPT_DIR`` before, but you will be told so if you don't.
In order to make use of ``INCLUDE_PARSING_CODE``, you have to use ``DEFINE_SCRIPT_DIR`` on preceding lines, but you will be told so if you don't.

.. _argbash_wrap:

* Point to a script that uses ``Argbash`` (or to its template), and your script will inherit its arguments (unless you exclude some of them).

Expand All @@ -237,6 +258,7 @@ Plus, there are convenience macros:

* The list of long options is a list of first arguments to functions such as ``ARG_POSITIONAL_SINGLE``, ``ARG_OPTIONAL_SINGLE``, ``ARG_OPTIONAL_BOOLEAN``, etc.
Therefore, don't include leading double dash to any of the list items that represent blacklisted optional arguments.
To blacklist the double dash positional argument feature, add the ``--`` symbol to the list.

* Flags is a string that may contain some characters.
If a flag is set, a class of arguments is excluded from the file.
Expand Down Expand Up @@ -266,7 +288,9 @@ Plus, there are convenience macros:
test $_ARG_BAR = on && MAYBE_BAR='--bar'
./process-single.sh --some-opt "$_ARG_SOME_OPT" $MAYBE_BAR

The stem to array name conversion is the same as with :ref:`argument names:parsing_results` except the prefix ``_ARGS_`` is prepended.
The stem to array name conversion is the same as with `argument names`__ except the prefix ``_ARGS_`` is prepended.

__ parsing_results_

Action macro
++++++++++++
Expand All @@ -284,15 +308,15 @@ The macro doesn't take any parameters.
Using parsing results
+++++++++++++++++++++

The key is that parsing results are saved in variables that relate to argument (long) names.
The key is that parsing results are saved in environmental variables that relate to argument (long) names.
The argument name is transliterated like this:

#. All letters are made upper-case
#. Dashes are transliterated to underscores (``-`` --> ``_``)
#. Dashes are transliterated to underscores (``-`` becomes ``_``)
#. ``_ARG_`` is prepended to the string.

So given that you have an argument ``--input-file`` that expects a value, you can access it via BASH variable ``_ARG_INPUT_FILE``.
So given that you have an argument ``--input-file`` that expects a value, you can access it via environmental variable ``_ARG_INPUT_FILE``.
#. Boolean arguments have values either ``on`` or ``off``.

If (a boolean argument) ``--quiet`` is passed, value of ``_ARG_QUIET`` is set to ``on``.

Conversely, if ``--no-quiet`` is passed, value of ``_ARG_QUIET`` is set to ``off``.
6 changes: 3 additions & 3 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ Argbash documentation
Argbash
-------

``Argbash`` (`<https://github.com/matejak/argbash>`_) is a ``Bash`` code generator that can assist you in writing scripts that accept arguments.
You declare arguments that your script should use in few lines and then, you run ``Argbash`` on those declarations to get a parsing code that can be used on all platforms that have ``Bash`` (Linux, OSX, MS Windows, ...).
``Argbash`` (`<https://github.com/matejak/argbash>`_) is a ``bash`` code generator that can assist you in writing scripts that accept arguments.
You declare arguments that your script should use in few lines and then, you run ``Argbash`` on those declarations to get a parsing code that can be used on all platforms that have ``bash`` (Linux, OSX, MS Windows, ...).
``Argbash`` is free software, you are free to use it, share it, modify it and share the modifications with the world, since it is published under the 3-clause BSD linense.

:Authors:
- `Matěj Týč <https://github.com/matejak>`_

:Copyright:
- 2014-2015, Matěj Týč
- 2014-2016, Matěj Týč

Requirements
++++++++++++
Expand Down
2 changes: 1 addition & 1 deletion doc/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Installation is simple, but as it is described in the quickstart, you don't need

``Argbash`` directly depends on two pieces of software:

* ``Bash >= 3.0`` --- this is obvious.
* ``bash >= 3.0`` --- this is obvious.
* ``autoconf >= 2.63`` --- ``Argbash`` is written in a ``m4`` language extension called ``m4sugar``, which is contained in ``autoconf``.

* ``GNU Make >= 4.0`` --- the project uses Makefiles to perform a wide variety of tasks, although it is more of interest to ``Argbash`` developers than to end-users.
Expand Down
15 changes: 7 additions & 8 deletions doc/others.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ Here follows a list of influences and/or alternatives:

* Python ``argparse``: The main inspiration: https://docs.python.org/3/library/argparse.html

* Pros: Works really well
* Cons: It is Python, we are Bash.
* Argbash: We handle the boolean options better.
* Pros: Works really well + it has more features.
* Cons: It is Python, we are ``bash``.
* Argbash: We handle the boolean options better, we have the :ref:`awesome wrapping functionality <argbash_wrap>`.

* Bash --- ``shflags``: The Bash framework for argument parsing: https://github.com/kward/shflags
* ``bash`` --- ``shflags``: The ``bash`` framework for argument parsing: https://github.com/kward/shflags

* Pros: It works great on Linux.
* Cons: Doesn't work with Windows Bash, doesn't support long options on OSX.
* Cons: Doesn't work with Windows ``bash``, doesn't support long options on OSX.
* Argbash: We work the same on all platforms that have ``bash``.

* ``getopt``: Eternal utility for parsing command-line.
Expand All @@ -21,8 +21,7 @@ Here follows a list of influences and/or alternatives:
* Pros: The GNU version can work with long and short optional arguments.
* Cons: Its use is `discouraged <http://bash.cumulonim.biz/BashFAQ(2f)035.html#getopts>`_ --- it seems to have some issues, you still need to deal with positional arguments by other means.

* ``getopts``: Bash builtin for parsing command-line.
* ``getopts``: ``bash`` builtin for parsing command-line.

* Pros: Being included with Bash, it behaves the same on all platforms.
* Pros: Being included with ``bash``, it behaves the same on all platforms.
* Cons: Supports only short optional arguments.

Loading

0 comments on commit 1626c91

Please sign in to comment.