setprogramoptions


Namesetprogramoptions JSON
Version 0.5.0.3 PyPI version JSON
download
home_pagehttps://github.com/sandialabs/SetProgramOptions
SummaryProgram options configuration file reader using ConfigParserEnhanced.
upload_time2023-10-29 05:00:12
maintainer
docs_urlNone
authorWilliam McLendon
requires_python>=3.6,<4.0
licenseLICENSE
keywords utility bash configuration configparserenhanced configparser
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            <!-- Github Badges -->
[![SetProgramOptions Testing](https://github.com/sandialabs/SetProgramOptions/actions/workflows/test-driver-core.yml/badge.svg)](https://github.com/sandialabs/SetProgramOptions/actions/workflows/test-driver-core.yml)
[![Documentation Status](https://readthedocs.org/projects/setprogramoptions/badge/?version=latest)](https://setprogramoptions.readthedocs.io/en/latest/?badge=latest)

> **DEPRECATION NOTICE:**  This package was forked by the original author and
> is now maintained under the name `ActiveConfigProgramOptions`:
>
> * [GitLab](https://gitlab.com/semantik-software/code/python/ActiveConfigProgramOptions)
> * [PyPI](https://pypi.org/project/activeconfigprogramoptions/)
> * [Docs](https://semantik-software.gitlab.io/code/python/ActiveConfigProgramOptions)
>
> Users of `SetProgramOptions` should switch to the new package.

SetProgramOptions
=================
The `SetProgramOptions` package extends [`ConfigParserEnhanced`][5] to enable the
processing of **.ini** files that specify **command line program options**.

As a subclass of ConfigParserEnhanced, SetProgramOptions supports all
the _operations_ that [`ConfigParserEnhanced`][5] supports and adds some of its
own. The following table notes the new **operations** that SetProgramOptions adds:

| Operation    | Format                                        | Defined By                  |
| ------------ | --------------------------------------------- | --------------------------- |
| `use`        | `use <section>`                               | [`ConfigParserEnhanced`][5] |
| `opt-set`    | `opt-set Param1 [Param2..ParamN] [: <VALUE>]` | `SetProgramOptions`         |
| `opt-remove` | `opt-remove Param [SUBSTR]`                   | `SetProgramOptions`         |

Generally speaking, when we parse a section from a .ini file, the following
steps are taken:

1. Parse the section, resolving any `use` operations to fully parse the DAG
   generated by the section and its dependents.
2. This generates a *list of actions* that are specified in the configuration
   file. Any `remove` operations encountered will execute their removal search
   during parsing to ensure they only remove matches that are _previously_ defined.
3. Once parsed, a _generator_ can be invoked to process the actions-list and generate
   the requested back-end format. Currently, SetProgramOptions only generates output
   for *bash* scripts but this can easily be extended to support other formats such
   as Windows batch or Powershell files, or other kinds of shell commands.
   Subclasses can also be extended to include their own generator types as well.

Supported Operations
--------------------

### `use`
The `use` operation is inherited from [`ConfigParserEnhanced`][5]. Please see its documentation
on this command and its use.

### `opt-set`
Sets a generic _command line_ style option.

The format of this is `opt-set Param1 [Param2] [Param3] ... [ParamN] : [VALUE]`

In a _bash_ context, this operation attempts to generate an option for some command
that will be executed.
`SetProgramOptions` will concactenate the _Params_ together and then append `=VALUE`
if a VALUE field is present.
For example, `opt-set Foo Bar : Baz` will become `FooBar=Baz`.


### `opt-remove`
_Removes_ existing entries that have been processed up to the point the `opt-remove` is
encountered that match a pattern.

The format of this is `opt-remove Param [SUBSTR]`

When a _remove_ is encountered, `SetProgramOptions` will search through all processed
options and will delete any that contain any _Param-i_ that matches `Param`.
By default the parameters much be an _exact match_ of `Param`, but if the optional
`SUBSTR` parameter is provided then `SetProgramOptions` will treat `Param` as a
substring and will remove all existing options if _any parameter contains Param_.


SetProgramOptions Config Files
------------------------------
A **.ini** file that can be processed by `SetProgramOptions` can be formatted like this:
```ini
[COMMAND_LS]
opt-set ls
```
This is perhaps the most simple thing we could do.
Using `gen_option_list('COMMAND_LS', generator="bash")`
this operation would generate the command `ls` when processed.

A more complex section which creates a CMake command call might look like this:
```ini
[COMMAND_CMAKE]
opt-set cmake
opt-set -G : Ninja
opt-set -D CMAKE_CXX_FLAGS : "-O3"
```
and this would generate the command `cmake -G=Ninja -DCMAKE_CXX_FLAGS="-O3"` when
processed for _bash_ output.


### Variable Expansion within VALUE fields
Variables can be added to the VALUE fields in handled instructions, but they have their
own format that must be used:
```
${VARNAME|VARTYPE}
```
- `VARNAME` is the variable name that you might expect for a bash style environment variable
  that might be defined like this: `export VARNAME=VALUE`.
- `VARTYPE` is the **type** of the variable that is being declared. For `SetProgramOptions`
  the only recognized type is `ENV` which defines _environment variables_. Subclasses such
  as `SetProgramOptionsCMake` define their own types.

We do not provide a **default** type for this because we wish it to be _explicit_ that this
is a pseudo-type and do not want it to be confused with some specific variable type since that
meaning can change depending on the kind of generator being used. For example, `${VARNAME}`
is an _environment variable_ within a bash context but in a CMake fragment file it would be
an _internal CMake variable_ and `$ENV{VARNAME}` would be an _environment variable_.
By not providing a default we force type consideration to be made explicitly during the creation
of the .ini file.


Linked Projects
---------------
- [ConfigParserEnhanced][5] - required by SetProgramOptions - [RTD][7], [GitHub][2]


SetProgramOptions Examples
--------------------------

### Example 1

#### [example-01.ini][8]
```ini
[BASH_VERSION]
opt-set bash
opt-set --version

[LS_COMMAND]
opt-set ls

[LS_LIST_TIME_REVERSED]
opt-set "-l -t -r"

[LS_CUSTOM_TIME_STYLE]
opt-set --time-style : "+%Y-%m-%d %H:%M:%S"

[MY_LS_COMMAND]
use LS_COMMAND
use LS_LIST_TIME_REVERSED
use LS_CUSTOM_TIME_STYLE
```

#### [example-01.py][9]

```python
#!/usr/bin/env python3
import setprogramoptions

filename = "example-01.ini"
section  = "MY_LS_COMMAND"

# Create SetProgramOptions instance
popts = setprogramoptions.SetProgramOptions(filename)

# Parse section
popts.parse_section(section)

# Generate the list of bash options for the command
bash_options = popts.gen_option_list(section, generator="bash")

# Print out the commands
print(" ".join(bash_options))
```

generates the output:

```bash
ls -l -t -r --time-style="+%Y-%m-%d %H:%M:%S"
```

### Example 2

We can utilize the `use` operation to create a more complex configuration file
that provides some sort of common sections and then point-of-use sections that
would generate customized configurations for a particular use:

```ini
[CMAKE_COMMAND]
opt-set cmake
opt-set -G : Ninja

[CMAKE_OPTIONS_COMMON]
opt-set -D CMAKE_CXX_FLAGS : "-fopenmp"

[CMAKE_OPTIONS_APPLICATION]
opt-set -D MYAPP_FLAG1 : "foo"
opt-set -D MYAPP_FLAG2 : "bar"

[APPLICATION_PATH_TO_SOURCE]
opt-set /path/to/source/.

[APPLICATION_CMAKE_PROFILE_01]
use CMAKE_COMMAND
use CMAKE_OPTIONS_COMMON
use CMAKE_OPTIONS_APPLICATION
use APPLICATION_PATH_TO_SOURCE

[APPLICATION_CMAKE_PROFILE_02]
use APPLICATION_PROFILE_01
opt-remove MYAPP_FLAG2
```

This example follows a pattern that larger projects might wish to use
when there are many configurations that may be getting tested.
Here, we set up some common option groups and then create aggregation sections
that will include the other sections to compose a full command line.

Using this .ini file, if we generate _bash_ output for section
`APPLICATION_CMAKE_PROFILE_01` the resulting command generated would be:
`cmake -G=Ninja -DCMAKE_CXX_FLAGS="-fopenmp" -DMYAPP_FLAG1="foo" -DMYAPP_FLAG2="bar" /path/to/source/.`

Alternatively, we can generate _bash_ output for section
`APPLICATION_CMAKE_PROFILE_02` which first clones `APPLICATION_CMAKE_PROFILE_01`
and then _removes_ all entries containing the parameter `MYAPP_FLAG2` using the
`opt-remove` operation.
This will result in a generated comand
`cmake -G=Ninja -DCMAKE_CXX_FLAGS="-fopenmp" -DMYAPP_FLAG1="foo" /path/to/source/.`.

This example shows how the `opt-remove` operation will fully
remove occurrences that contain that substring from the list
of actions.

This example shows some of the capabilities that `SetProgramOptions`
provides for managing many build configurations within a single .ini
file.



SetProgramOptionsCMake
======================
`SetProgramOptionsCMake` is a subclass of `SetProgramOptions` that adds additional
operations and generators to handle processing [CMake][6] options:
- Adds `opt-set-cmake-var`.
- Adds `cmake_fragment` generator.
- Adds `CMAKE` type to variables.

New operations defined in `SetProgramOptionsCMake`:

| Operation           | Format                                                           | Defined By               |
| ------------------- | ---------------------------------------------------------------- | ------------------------ |
| `opt-set-cmake-var` | `opt-set-cmake-var VARNAME [TYPE] [FORCE] [PARENT_SCOPE]: VALUE` | `SetProgramOptionsCMake` |


Supported Operations
--------------------
### `opt-set-cmake-var`
This adds a CMake variable program option. These have a special syntax in _bash_ that looks like `-DVARNAME:TYPE=VALUE` where the `:TYPE`
is an optional parameter. If the *type* is left out then CMake assumes the value is a _STRING_.

We may not wish to generate bash only output though. For CMake files, we might wish to generate a _cmake fragment_ file which is
basically a snippet of CMake that can be loaded during a CMake call using the `-S` option: `cmake -S cmake_fragment.cmake`. The
syntax within a CMake fragment file is the same as in a CMake script itself.

If the back-end generator is creating a CMake fragment file, the _set_ command generated will use [CMake set syntax].
This looks something like `set(<variable> <value>)` but can also contain additional options. These extra options can
be provided in the `opt-set-cmake-var` operation in the .ini file:

- `FORCE` -
    - By default, a `set()` operation does not overwrite entries in a CMake file. This can be added to
      _force_ the value to be saved.
    - This is only applicable to generating _cmake fragment_ files.
- `PARENT_SCOPE` - If provided, this option instructs CMake to set the variable in the scope that is above the current scope.
    - This is only applicable to generating _cmake fragment_ files.
- `TYPE` - Specifies the _TYPE_ the variable can be.
    - This is a _positional_ argument and must always come after _VARNAME_.
    - Valid options for this are `STRING` (default), `BOOL`, `PATH`, `INTERNAL`, `FILEPATH`.
    - Adding a _TYPE_ option implies that the _CACHE_ and _docstring_ parameters will be added to a `set()` command
      in a CMake fragment file according to the syntax: `set(<variable> <value> CACHE <type> <docstring> [FORCE])`
      as illustrated on the [CMake `set()` documentation][1].
    - This is applicable to both _cmake fragment_ and _bash_ generation.


SetProgramOptionsCMake Config Files
-----------------------------------
Here is an example of what a .ini file may look like using the
CMake operations provided by this class:

```ini
[SECTION_A]
opt-set cmake
opt-set-cmake-var MYVARIABLENAME  : VALUE
opt-set-cmake-var MYVARIABLENAME2 PARENT_SCOPE : VALUE
```

### Handling CMake Variables
A _CMake variable_ in this context would be an _internal variable_ that is known to CMake.
Because this is not a variable that would be known outside of the context of `.cmake` files,
this kind of variable is only applicable when generating CMake fragment files.

It is necessary to provide a CMake variant for variable expansions because the CMake
syntax for variables is different than that used by Bash, and CMake fragments have
a specialized syntax for *environment* variables as well. In CMake fragment files:
- environment variables are written as `$ENV{VARNAME}`
- internal CMake variables are written as: `${VARNAME}`

We saw variables in `SetProgramOptions` follow the syntax: `${VARNAME|ENV}` where
`ENV` specifies the kind of variable we're declaring. We extend this in
`SetProgramOptionsCMake` by adding a `${VARNAME|CMAKE}` variation which
indicates that the variable is expected to be an _internal_ cmake variable
and is more suited towards being used within a CMake fragment file since
it has no meaning at the command line.

You can still use a _CMake_ variable expansion entry when generating _bash_
output but there is a catch. The variable *must* be resolvable to something
that is **not** a CMake variable through its transitive closure.
This is achieved by caching the _last known value_ of a variable as we process
a .ini file and provided that the value ultimately resolves to either a string
or an environment variable we can still use it.
If it cannot be resolved to something that isn't a CMake variable then an
exception should be generated.

For example, if we have a .ini file that sets up `CMAKE_CXX_FLAGS` to include `-O0` in a
common section like this:

```ini
[COMMON]
opt-set-cmake-var CMAKE_CXX_FLAGS STRING FORCE: "-O0"
```
and then we have a later section that adds an OpenMP flag to it like this:
```.ini
[ADD_OPENMP]
use COMMON
opt-set-cmake-var CMAKE_CXX_FLAGS STRING FORCE: "${CMAKE_CXX_FLAGS|CMAKE} -fopenmp"
```
This is valid since `${CMAKE_CXX_FLAGS|CMAKE}` will get replaced with `-O0` so the
resulting `CMAKE_CXX_FLAGS` variable would be set to `-O0 -fopenmp` after processing.
If we generate _bash_ output for the `ADD_OPENMP` section we'll get
a `-D` option that looks like `-DCMAKE_CXX_FLAGS:STRING="-O0 -fopenmp"`.

But what if we have a .ini file with a CMake variable that can't be resolved to
something that is not a CMake flag, such as:
```ini
[COMMON]
opt-set-cmake-var FOO : ${SOME_CMAKE_VAR|CMAKE}
```
If we tried to process this and write out the resulting script using the _bash_ generator
an exception should be raised citing that we don't know what to do with that unresolved
CMake variable. This would be the equivalent to a bash option `-DFOO=<SOME_CMAKE_VAR>`
and bash can't handle that because it has no idea what it should put in that cmake var
field.

Note: if the same CMake option is provided in multiple lines they will all be included
in the generated output. In that case, the behaviour will match what will occur if
one called cmake directly with the same option multiple times. In that case, the
_last one wins_ since all `-D` options are treated as though they both have `FORCE`
and `CACHE` flags set.



SetProgramOptionsCMake Examples
-------------------------------

### Example

This example shows a configuration file that can be used to generate
build files using Ninja or Makefile. In the .ini file we set up some
common sections that contain the arguments and then the point-of-use
sections ( `MYPROJ_CONFIGURATION_NINJA` and `MYPROJ_CONFIGURATION_MAKEFILES` )
can compose their command lines by importing the argument definition sections
via `use`.

#### example-02.ini
```ini
#
# example-02.ini
#
[CMAKE_COMMAND]
opt-set cmake

[CMAKE_GENERATOR_NINJA]
opt-set -G : Ninja

[CMAKE_GENERATOR_MAKEFILES]
opt-set -G : "Unix Makefiles"

[MYPROJ_OPTIONS]
opt-set-cmake-var  MYPROJ_CXX_FLAGS       STRING       : "-O0 -fopenmp"
opt-set-cmake-var  MYPROJ_ENABLE_OPTION_A BOOL   FORCE : ON
opt-set-cmake-var  MYPROJ_ENABLE_OPTION_B BOOL         : ON

[MYPROJ_SOURCE_DIR]
opt-set /path/to/source/dir

[MYPROJ_CONFIGURATION_NINJA]
use CMAKE_COMMAND
use CMAKE_GENERATOR_NINJA
use MYPROJ_OPTIONS
use MYPROJ_SOURCE_DIR

[MYPROJ_CONFIGURATION_MAKEFILES]
use CMAKE_COMMAND
use CMAKE_GENERATOR_MAKEFILES
use MYPROJ_OPTIONS
use MYPROJ_SOURCE_DIR
```

#### example-02.py
This python code shows generating a bash script and a CMake fragment
of the configuration specified in the .ini file.
```python
#!/usr/bin/env python3
# -*- mode: python; py-indent-offset: 4; py-continuation-offset: 4 -*-
from pathlib import Path
import setprogramoptions

print(80*"-")
print(f"- {Path(__file__).name}")
print(80*"-")

filename = "example-02.ini"
popts = setprogramoptions.SetProgramOptionsCMake(filename)

section = "MYPROJ_CONFIGURATION_NINJA"
popts.parse_section(section)

# Generate BASH output
print("")
print("Bash output")
print("-----------")
bash_options = popts.gen_option_list(section, generator="bash")
print(" \\\n   ".join(bash_options))

# Generate a CMake Fragment
print("")
print("CMake fragment output")
print("---------------------")
cmake_options = popts.gen_option_list(section, generator="cmake_fragment")
print("\n".join(cmake_options))

print("\nDone")
```

#### Output
Using the *Ninja* specialization from the above code, we generate the following
output:
```bash
$ python3 example-02.py
--------------------------------------------------------------------------------
- example-02.py
--------------------------------------------------------------------------------

**Bash output**
cmake \
   -G=Ninja \
   -DMYPROJ_CXX_FLAGS:STRING="-O0 -fopenmp" \
   -DMYPROJ_ENABLE_OPTION_A:BOOL=ON \
   -DMYPROJ_ENABLE_OPTION_B:BOOL=ON \
   /path/to/source/dir

CMake fragment output
---------------------
set(MYPROJ_CXX_FLAGS "-O0 -fopenmp" CACHE STRING "from .ini configuration")
set(MYPROJ_ENABLE_OPTION_A ON CACHE BOOL "from .ini configuration" FORCE)
set(MYPROJ_ENABLE_OPTION_B ON CACHE BOOL "from .ini configuration")

Done
```

[1]: https://cmake.org/cmake/help/latest/command/set.html
[2]: https://github.com/sandialabs/ConfigParserEnhanced
[3]: https://github.com/sandialabs/SetProgramOptions/blob/master/CHANGELOG.md
[4]: https://setprogramoptions.readthedocs.io/
[5]: https://pypi.org/project/configparserenhanced/
[6]: https://www.cmake.org/
[7]: https://configparserenhanced.readthedocs.io/
[8]: https://github.com/sandialabs/SetProgramOptions/blob/master/examples/example-01.ini
[9]: https://github.com/sandialabs/SetProgramOptions/blob/master/examples/example-01.py


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/sandialabs/SetProgramOptions",
    "name": "setprogramoptions",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6,<4.0",
    "maintainer_email": "",
    "keywords": "Utility,Bash,Configuration,ConfigParserEnhanced,ConfigParser",
    "author": "William McLendon",
    "author_email": "wcmclen@sandia.gov",
    "download_url": "https://files.pythonhosted.org/packages/ef/14/9768597165a284d7ca4d139e1f4419452fee38b46101d7fee95adf6e6d54/setprogramoptions-0.5.0.3.tar.gz",
    "platform": null,
    "description": "<!-- Github Badges -->\n[![SetProgramOptions Testing](https://github.com/sandialabs/SetProgramOptions/actions/workflows/test-driver-core.yml/badge.svg)](https://github.com/sandialabs/SetProgramOptions/actions/workflows/test-driver-core.yml)\n[![Documentation Status](https://readthedocs.org/projects/setprogramoptions/badge/?version=latest)](https://setprogramoptions.readthedocs.io/en/latest/?badge=latest)\n\n> **DEPRECATION NOTICE:**  This package was forked by the original author and\n> is now maintained under the name `ActiveConfigProgramOptions`:\n>\n> * [GitLab](https://gitlab.com/semantik-software/code/python/ActiveConfigProgramOptions)\n> * [PyPI](https://pypi.org/project/activeconfigprogramoptions/)\n> * [Docs](https://semantik-software.gitlab.io/code/python/ActiveConfigProgramOptions)\n>\n> Users of `SetProgramOptions` should switch to the new package.\n\nSetProgramOptions\n=================\nThe `SetProgramOptions` package extends [`ConfigParserEnhanced`][5] to enable the\nprocessing of **.ini** files that specify **command line program options**.\n\nAs a subclass of ConfigParserEnhanced, SetProgramOptions supports all\nthe _operations_ that [`ConfigParserEnhanced`][5] supports and adds some of its\nown. The following table notes the new **operations** that SetProgramOptions adds:\n\n| Operation    | Format                                        | Defined By                  |\n| ------------ | --------------------------------------------- | --------------------------- |\n| `use`        | `use <section>`                               | [`ConfigParserEnhanced`][5] |\n| `opt-set`    | `opt-set Param1 [Param2..ParamN] [: <VALUE>]` | `SetProgramOptions`         |\n| `opt-remove` | `opt-remove Param [SUBSTR]`                   | `SetProgramOptions`         |\n\nGenerally speaking, when we parse a section from a .ini file, the following\nsteps are taken:\n\n1. Parse the section, resolving any `use` operations to fully parse the DAG\n   generated by the section and its dependents.\n2. This generates a *list of actions* that are specified in the configuration\n   file. Any `remove` operations encountered will execute their removal search\n   during parsing to ensure they only remove matches that are _previously_ defined.\n3. Once parsed, a _generator_ can be invoked to process the actions-list and generate\n   the requested back-end format. Currently, SetProgramOptions only generates output\n   for *bash* scripts but this can easily be extended to support other formats such\n   as Windows batch or Powershell files, or other kinds of shell commands.\n   Subclasses can also be extended to include their own generator types as well.\n\nSupported Operations\n--------------------\n\n### `use`\nThe `use` operation is inherited from [`ConfigParserEnhanced`][5]. Please see its documentation\non this command and its use.\n\n### `opt-set`\nSets a generic _command line_ style option.\n\nThe format of this is `opt-set Param1 [Param2] [Param3] ... [ParamN] : [VALUE]`\n\nIn a _bash_ context, this operation attempts to generate an option for some command\nthat will be executed.\n`SetProgramOptions` will concactenate the _Params_ together and then append `=VALUE`\nif a VALUE field is present.\nFor example, `opt-set Foo Bar : Baz` will become `FooBar=Baz`.\n\n\n### `opt-remove`\n_Removes_ existing entries that have been processed up to the point the `opt-remove` is\nencountered that match a pattern.\n\nThe format of this is `opt-remove Param [SUBSTR]`\n\nWhen a _remove_ is encountered, `SetProgramOptions` will search through all processed\noptions and will delete any that contain any _Param-i_ that matches `Param`.\nBy default the parameters much be an _exact match_ of `Param`, but if the optional\n`SUBSTR` parameter is provided then `SetProgramOptions` will treat `Param` as a\nsubstring and will remove all existing options if _any parameter contains Param_.\n\n\nSetProgramOptions Config Files\n------------------------------\nA **.ini** file that can be processed by `SetProgramOptions` can be formatted like this:\n```ini\n[COMMAND_LS]\nopt-set ls\n```\nThis is perhaps the most simple thing we could do.\nUsing `gen_option_list('COMMAND_LS', generator=\"bash\")`\nthis operation would generate the command `ls` when processed.\n\nA more complex section which creates a CMake command call might look like this:\n```ini\n[COMMAND_CMAKE]\nopt-set cmake\nopt-set -G : Ninja\nopt-set -D CMAKE_CXX_FLAGS : \"-O3\"\n```\nand this would generate the command `cmake -G=Ninja -DCMAKE_CXX_FLAGS=\"-O3\"` when\nprocessed for _bash_ output.\n\n\n### Variable Expansion within VALUE fields\nVariables can be added to the VALUE fields in handled instructions, but they have their\nown format that must be used:\n```\n${VARNAME|VARTYPE}\n```\n- `VARNAME` is the variable name that you might expect for a bash style environment variable\n  that might be defined like this: `export VARNAME=VALUE`.\n- `VARTYPE` is the **type** of the variable that is being declared. For `SetProgramOptions`\n  the only recognized type is `ENV` which defines _environment variables_. Subclasses such\n  as `SetProgramOptionsCMake` define their own types.\n\nWe do not provide a **default** type for this because we wish it to be _explicit_ that this\nis a pseudo-type and do not want it to be confused with some specific variable type since that\nmeaning can change depending on the kind of generator being used. For example, `${VARNAME}`\nis an _environment variable_ within a bash context but in a CMake fragment file it would be\nan _internal CMake variable_ and `$ENV{VARNAME}` would be an _environment variable_.\nBy not providing a default we force type consideration to be made explicitly during the creation\nof the .ini file.\n\n\nLinked Projects\n---------------\n- [ConfigParserEnhanced][5] - required by SetProgramOptions - [RTD][7], [GitHub][2]\n\n\nSetProgramOptions Examples\n--------------------------\n\n### Example 1\n\n#### [example-01.ini][8]\n```ini\n[BASH_VERSION]\nopt-set bash\nopt-set --version\n\n[LS_COMMAND]\nopt-set ls\n\n[LS_LIST_TIME_REVERSED]\nopt-set \"-l -t -r\"\n\n[LS_CUSTOM_TIME_STYLE]\nopt-set --time-style : \"+%Y-%m-%d %H:%M:%S\"\n\n[MY_LS_COMMAND]\nuse LS_COMMAND\nuse LS_LIST_TIME_REVERSED\nuse LS_CUSTOM_TIME_STYLE\n```\n\n#### [example-01.py][9]\n\n```python\n#!/usr/bin/env python3\nimport setprogramoptions\n\nfilename = \"example-01.ini\"\nsection  = \"MY_LS_COMMAND\"\n\n# Create SetProgramOptions instance\npopts = setprogramoptions.SetProgramOptions(filename)\n\n# Parse section\npopts.parse_section(section)\n\n# Generate the list of bash options for the command\nbash_options = popts.gen_option_list(section, generator=\"bash\")\n\n# Print out the commands\nprint(\" \".join(bash_options))\n```\n\ngenerates the output:\n\n```bash\nls -l -t -r --time-style=\"+%Y-%m-%d %H:%M:%S\"\n```\n\n### Example 2\n\nWe can utilize the `use` operation to create a more complex configuration file\nthat provides some sort of common sections and then point-of-use sections that\nwould generate customized configurations for a particular use:\n\n```ini\n[CMAKE_COMMAND]\nopt-set cmake\nopt-set -G : Ninja\n\n[CMAKE_OPTIONS_COMMON]\nopt-set -D CMAKE_CXX_FLAGS : \"-fopenmp\"\n\n[CMAKE_OPTIONS_APPLICATION]\nopt-set -D MYAPP_FLAG1 : \"foo\"\nopt-set -D MYAPP_FLAG2 : \"bar\"\n\n[APPLICATION_PATH_TO_SOURCE]\nopt-set /path/to/source/.\n\n[APPLICATION_CMAKE_PROFILE_01]\nuse CMAKE_COMMAND\nuse CMAKE_OPTIONS_COMMON\nuse CMAKE_OPTIONS_APPLICATION\nuse APPLICATION_PATH_TO_SOURCE\n\n[APPLICATION_CMAKE_PROFILE_02]\nuse APPLICATION_PROFILE_01\nopt-remove MYAPP_FLAG2\n```\n\nThis example follows a pattern that larger projects might wish to use\nwhen there are many configurations that may be getting tested.\nHere, we set up some common option groups and then create aggregation sections\nthat will include the other sections to compose a full command line.\n\nUsing this .ini file, if we generate _bash_ output for section\n`APPLICATION_CMAKE_PROFILE_01` the resulting command generated would be:\n`cmake -G=Ninja -DCMAKE_CXX_FLAGS=\"-fopenmp\" -DMYAPP_FLAG1=\"foo\" -DMYAPP_FLAG2=\"bar\" /path/to/source/.`\n\nAlternatively, we can generate _bash_ output for section\n`APPLICATION_CMAKE_PROFILE_02` which first clones `APPLICATION_CMAKE_PROFILE_01`\nand then _removes_ all entries containing the parameter `MYAPP_FLAG2` using the\n`opt-remove` operation.\nThis will result in a generated comand\n`cmake -G=Ninja -DCMAKE_CXX_FLAGS=\"-fopenmp\" -DMYAPP_FLAG1=\"foo\" /path/to/source/.`.\n\nThis example shows how the `opt-remove` operation will fully\nremove occurrences that contain that substring from the list\nof actions.\n\nThis example shows some of the capabilities that `SetProgramOptions`\nprovides for managing many build configurations within a single .ini\nfile.\n\n\n\nSetProgramOptionsCMake\n======================\n`SetProgramOptionsCMake` is a subclass of `SetProgramOptions` that adds additional\noperations and generators to handle processing [CMake][6] options:\n- Adds `opt-set-cmake-var`.\n- Adds `cmake_fragment` generator.\n- Adds `CMAKE` type to variables.\n\nNew operations defined in `SetProgramOptionsCMake`:\n\n| Operation           | Format                                                           | Defined By               |\n| ------------------- | ---------------------------------------------------------------- | ------------------------ |\n| `opt-set-cmake-var` | `opt-set-cmake-var VARNAME [TYPE] [FORCE] [PARENT_SCOPE]: VALUE` | `SetProgramOptionsCMake` |\n\n\nSupported Operations\n--------------------\n### `opt-set-cmake-var`\nThis adds a CMake variable program option. These have a special syntax in _bash_ that looks like `-DVARNAME:TYPE=VALUE` where the `:TYPE`\nis an optional parameter. If the *type* is left out then CMake assumes the value is a _STRING_.\n\nWe may not wish to generate bash only output though. For CMake files, we might wish to generate a _cmake fragment_ file which is\nbasically a snippet of CMake that can be loaded during a CMake call using the `-S` option: `cmake -S cmake_fragment.cmake`. The\nsyntax within a CMake fragment file is the same as in a CMake script itself.\n\nIf the back-end generator is creating a CMake fragment file, the _set_ command generated will use [CMake set syntax].\nThis looks something like `set(<variable> <value>)` but can also contain additional options. These extra options can\nbe provided in the `opt-set-cmake-var` operation in the .ini file:\n\n- `FORCE` -\n    - By default, a `set()` operation does not overwrite entries in a CMake file. This can be added to\n      _force_ the value to be saved.\n    - This is only applicable to generating _cmake fragment_ files.\n- `PARENT_SCOPE` - If provided, this option instructs CMake to set the variable in the scope that is above the current scope.\n    - This is only applicable to generating _cmake fragment_ files.\n- `TYPE` - Specifies the _TYPE_ the variable can be.\n    - This is a _positional_ argument and must always come after _VARNAME_.\n    - Valid options for this are `STRING` (default), `BOOL`, `PATH`, `INTERNAL`, `FILEPATH`.\n    - Adding a _TYPE_ option implies that the _CACHE_ and _docstring_ parameters will be added to a `set()` command\n      in a CMake fragment file according to the syntax: `set(<variable> <value> CACHE <type> <docstring> [FORCE])`\n      as illustrated on the [CMake `set()` documentation][1].\n    - This is applicable to both _cmake fragment_ and _bash_ generation.\n\n\nSetProgramOptionsCMake Config Files\n-----------------------------------\nHere is an example of what a .ini file may look like using the\nCMake operations provided by this class:\n\n```ini\n[SECTION_A]\nopt-set cmake\nopt-set-cmake-var MYVARIABLENAME  : VALUE\nopt-set-cmake-var MYVARIABLENAME2 PARENT_SCOPE : VALUE\n```\n\n### Handling CMake Variables\nA _CMake variable_ in this context would be an _internal variable_ that is known to CMake.\nBecause this is not a variable that would be known outside of the context of `.cmake` files,\nthis kind of variable is only applicable when generating CMake fragment files.\n\nIt is necessary to provide a CMake variant for variable expansions because the CMake\nsyntax for variables is different than that used by Bash, and CMake fragments have\na specialized syntax for *environment* variables as well. In CMake fragment files:\n- environment variables are written as `$ENV{VARNAME}`\n- internal CMake variables are written as: `${VARNAME}`\n\nWe saw variables in `SetProgramOptions` follow the syntax: `${VARNAME|ENV}` where\n`ENV` specifies the kind of variable we're declaring. We extend this in\n`SetProgramOptionsCMake` by adding a `${VARNAME|CMAKE}` variation which\nindicates that the variable is expected to be an _internal_ cmake variable\nand is more suited towards being used within a CMake fragment file since\nit has no meaning at the command line.\n\nYou can still use a _CMake_ variable expansion entry when generating _bash_\noutput but there is a catch. The variable *must* be resolvable to something\nthat is **not** a CMake variable through its transitive closure.\nThis is achieved by caching the _last known value_ of a variable as we process\na .ini file and provided that the value ultimately resolves to either a string\nor an environment variable we can still use it.\nIf it cannot be resolved to something that isn't a CMake variable then an\nexception should be generated.\n\nFor example, if we have a .ini file that sets up `CMAKE_CXX_FLAGS` to include `-O0` in a\ncommon section like this:\n\n```ini\n[COMMON]\nopt-set-cmake-var CMAKE_CXX_FLAGS STRING FORCE: \"-O0\"\n```\nand then we have a later section that adds an OpenMP flag to it like this:\n```.ini\n[ADD_OPENMP]\nuse COMMON\nopt-set-cmake-var CMAKE_CXX_FLAGS STRING FORCE: \"${CMAKE_CXX_FLAGS|CMAKE} -fopenmp\"\n```\nThis is valid since `${CMAKE_CXX_FLAGS|CMAKE}` will get replaced with `-O0` so the\nresulting `CMAKE_CXX_FLAGS` variable would be set to `-O0 -fopenmp` after processing.\nIf we generate _bash_ output for the `ADD_OPENMP` section we'll get\na `-D` option that looks like `-DCMAKE_CXX_FLAGS:STRING=\"-O0 -fopenmp\"`.\n\nBut what if we have a .ini file with a CMake variable that can't be resolved to\nsomething that is not a CMake flag, such as:\n```ini\n[COMMON]\nopt-set-cmake-var FOO : ${SOME_CMAKE_VAR|CMAKE}\n```\nIf we tried to process this and write out the resulting script using the _bash_ generator\nan exception should be raised citing that we don't know what to do with that unresolved\nCMake variable. This would be the equivalent to a bash option `-DFOO=<SOME_CMAKE_VAR>`\nand bash can't handle that because it has no idea what it should put in that cmake var\nfield.\n\nNote: if the same CMake option is provided in multiple lines they will all be included\nin the generated output. In that case, the behaviour will match what will occur if\none called cmake directly with the same option multiple times. In that case, the\n_last one wins_ since all `-D` options are treated as though they both have `FORCE`\nand `CACHE` flags set.\n\n\n\nSetProgramOptionsCMake Examples\n-------------------------------\n\n### Example\n\nThis example shows a configuration file that can be used to generate\nbuild files using Ninja or Makefile. In the .ini file we set up some\ncommon sections that contain the arguments and then the point-of-use\nsections ( `MYPROJ_CONFIGURATION_NINJA` and `MYPROJ_CONFIGURATION_MAKEFILES` )\ncan compose their command lines by importing the argument definition sections\nvia `use`.\n\n#### example-02.ini\n```ini\n#\n# example-02.ini\n#\n[CMAKE_COMMAND]\nopt-set cmake\n\n[CMAKE_GENERATOR_NINJA]\nopt-set -G : Ninja\n\n[CMAKE_GENERATOR_MAKEFILES]\nopt-set -G : \"Unix Makefiles\"\n\n[MYPROJ_OPTIONS]\nopt-set-cmake-var  MYPROJ_CXX_FLAGS       STRING       : \"-O0 -fopenmp\"\nopt-set-cmake-var  MYPROJ_ENABLE_OPTION_A BOOL   FORCE : ON\nopt-set-cmake-var  MYPROJ_ENABLE_OPTION_B BOOL         : ON\n\n[MYPROJ_SOURCE_DIR]\nopt-set /path/to/source/dir\n\n[MYPROJ_CONFIGURATION_NINJA]\nuse CMAKE_COMMAND\nuse CMAKE_GENERATOR_NINJA\nuse MYPROJ_OPTIONS\nuse MYPROJ_SOURCE_DIR\n\n[MYPROJ_CONFIGURATION_MAKEFILES]\nuse CMAKE_COMMAND\nuse CMAKE_GENERATOR_MAKEFILES\nuse MYPROJ_OPTIONS\nuse MYPROJ_SOURCE_DIR\n```\n\n#### example-02.py\nThis python code shows generating a bash script and a CMake fragment\nof the configuration specified in the .ini file.\n```python\n#!/usr/bin/env python3\n# -*- mode: python; py-indent-offset: 4; py-continuation-offset: 4 -*-\nfrom pathlib import Path\nimport setprogramoptions\n\nprint(80*\"-\")\nprint(f\"- {Path(__file__).name}\")\nprint(80*\"-\")\n\nfilename = \"example-02.ini\"\npopts = setprogramoptions.SetProgramOptionsCMake(filename)\n\nsection = \"MYPROJ_CONFIGURATION_NINJA\"\npopts.parse_section(section)\n\n# Generate BASH output\nprint(\"\")\nprint(\"Bash output\")\nprint(\"-----------\")\nbash_options = popts.gen_option_list(section, generator=\"bash\")\nprint(\" \\\\\\n   \".join(bash_options))\n\n# Generate a CMake Fragment\nprint(\"\")\nprint(\"CMake fragment output\")\nprint(\"---------------------\")\ncmake_options = popts.gen_option_list(section, generator=\"cmake_fragment\")\nprint(\"\\n\".join(cmake_options))\n\nprint(\"\\nDone\")\n```\n\n#### Output\nUsing the *Ninja* specialization from the above code, we generate the following\noutput:\n```bash\n$ python3 example-02.py\n--------------------------------------------------------------------------------\n- example-02.py\n--------------------------------------------------------------------------------\n\n**Bash output**\ncmake \\\n   -G=Ninja \\\n   -DMYPROJ_CXX_FLAGS:STRING=\"-O0 -fopenmp\" \\\n   -DMYPROJ_ENABLE_OPTION_A:BOOL=ON \\\n   -DMYPROJ_ENABLE_OPTION_B:BOOL=ON \\\n   /path/to/source/dir\n\nCMake fragment output\n---------------------\nset(MYPROJ_CXX_FLAGS \"-O0 -fopenmp\" CACHE STRING \"from .ini configuration\")\nset(MYPROJ_ENABLE_OPTION_A ON CACHE BOOL \"from .ini configuration\" FORCE)\nset(MYPROJ_ENABLE_OPTION_B ON CACHE BOOL \"from .ini configuration\")\n\nDone\n```\n\n[1]: https://cmake.org/cmake/help/latest/command/set.html\n[2]: https://github.com/sandialabs/ConfigParserEnhanced\n[3]: https://github.com/sandialabs/SetProgramOptions/blob/master/CHANGELOG.md\n[4]: https://setprogramoptions.readthedocs.io/\n[5]: https://pypi.org/project/configparserenhanced/\n[6]: https://www.cmake.org/\n[7]: https://configparserenhanced.readthedocs.io/\n[8]: https://github.com/sandialabs/SetProgramOptions/blob/master/examples/example-01.ini\n[9]: https://github.com/sandialabs/SetProgramOptions/blob/master/examples/example-01.py\n\n",
    "bugtrack_url": null,
    "license": "LICENSE",
    "summary": "Program options configuration file reader using ConfigParserEnhanced.",
    "version": "0.5.0.3",
    "project_urls": {
        "CI": "https://github.com/sandialabs/SetProgramOptions/actions",
        "Documentation": "https://setprogramoptions.readthedocs.io/en/latest/",
        "Homepage": "https://github.com/sandialabs/SetProgramOptions",
        "Issues": "https://github.com/sandialabs/SetProgramOptions/issues",
        "Repository": "https://github.com/sandialabs/SetProgramOptions"
    },
    "split_keywords": [
        "utility",
        "bash",
        "configuration",
        "configparserenhanced",
        "configparser"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0b67568667acbd0eaecbd261a75307389bf60b12e6843f43a2d2635adcb4a81a",
                "md5": "c2f60783bced4fa172196c970e29016c",
                "sha256": "96409935e86ba681ef4c52de4da7adf46570a1929fc3401587c194e537cf5f83"
            },
            "downloads": -1,
            "filename": "setprogramoptions-0.5.0.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c2f60783bced4fa172196c970e29016c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6,<4.0",
            "size": 46393,
            "upload_time": "2023-10-29T05:00:09",
            "upload_time_iso_8601": "2023-10-29T05:00:09.561957Z",
            "url": "https://files.pythonhosted.org/packages/0b/67/568667acbd0eaecbd261a75307389bf60b12e6843f43a2d2635adcb4a81a/setprogramoptions-0.5.0.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ef149768597165a284d7ca4d139e1f4419452fee38b46101d7fee95adf6e6d54",
                "md5": "ffc758907701d75ad30bbd56ca6c9513",
                "sha256": "477878e58dd2838d4093b8b5bd9c341f0013ade08f50176026ea8bda8bcb3cfa"
            },
            "downloads": -1,
            "filename": "setprogramoptions-0.5.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "ffc758907701d75ad30bbd56ca6c9513",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6,<4.0",
            "size": 39756,
            "upload_time": "2023-10-29T05:00:12",
            "upload_time_iso_8601": "2023-10-29T05:00:12.176995Z",
            "url": "https://files.pythonhosted.org/packages/ef/14/9768597165a284d7ca4d139e1f4419452fee38b46101d7fee95adf6e6d54/setprogramoptions-0.5.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-29 05:00:12",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "sandialabs",
    "github_project": "SetProgramOptions",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "requirements": [],
    "lcname": "setprogramoptions"
}
        
Elapsed time: 0.18466s