aridity 62__tar.gz → 63__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aridity-62 → aridity-63}/PKG-INFO +37 -1
- {aridity-62 → aridity-63}/README.md +36 -0
- {aridity-62 → aridity-63}/aridity/config.py +1 -0
- {aridity-62 → aridity-63}/aridity/functions.py +1 -1
- {aridity-62 → aridity-63}/aridity/keyring.py +9 -0
- {aridity-62 → aridity-63}/aridity.egg-info/PKG-INFO +37 -1
- {aridity-62 → aridity-63}/setup.py +1 -1
- {aridity-62 → aridity-63}/COPYING +0 -0
- {aridity-62 → aridity-63}/aridity/__init__.py +0 -0
- {aridity-62 → aridity-63}/aridity/arid_config.py +0 -0
- {aridity-62 → aridity-63}/aridity/directives.py +0 -0
- {aridity-62 → aridity-63}/aridity/grammar.py +0 -0
- {aridity-62 → aridity-63}/aridity/model.py +0 -0
- {aridity-62 → aridity-63}/aridity/processtemplate.py +0 -0
- {aridity-62 → aridity-63}/aridity/repl.py +0 -0
- {aridity-62 → aridity-63}/aridity/scope.py +0 -0
- {aridity-62 → aridity-63}/aridity/stacks.py +0 -0
- {aridity-62 → aridity-63}/aridity/util.py +0 -0
- {aridity-62 → aridity-63}/aridity.egg-info/SOURCES.txt +0 -0
- {aridity-62 → aridity-63}/aridity.egg-info/dependency_links.txt +0 -0
- {aridity-62 → aridity-63}/aridity.egg-info/entry_points.txt +0 -0
- {aridity-62 → aridity-63}/aridity.egg-info/requires.txt +0 -0
- {aridity-62 → aridity-63}/aridity.egg-info/top_level.txt +0 -0
- {aridity-62 → aridity-63}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: aridity
|
|
3
|
-
Version:
|
|
3
|
+
Version: 63
|
|
4
4
|
Summary: DRY config and template system, easily extensible with Python
|
|
5
5
|
Home-page: https://github.com/combatopera/aridity
|
|
6
6
|
Author: Andrzej Cichocki
|
|
@@ -27,6 +27,42 @@ DRY config and template system, easily extensible with Python
|
|
|
27
27
|
* Principle of least astonishment driven design
|
|
28
28
|
* Don't make users jump through hoops
|
|
29
29
|
|
|
30
|
+
## Motivation
|
|
31
|
+
* Environment variables are too crude to configure non-trivial apps, and maybe even trivial apps in the cloud
|
|
32
|
+
* They do not support nested data or lists, without some encoding scheme implemented in app code or a lib
|
|
33
|
+
* Multiple bespoke encoding schemes in the system are an error-prone maintenance burden worth avoiding
|
|
34
|
+
* Testing code that queries the environment directly comes with a big risk of leaking state between tests
|
|
35
|
+
* Often tools/libraries must be configured using config files
|
|
36
|
+
* Support for config file interpolation is not enough to stay DRY, and comes with a different set of gotchas per tool
|
|
37
|
+
* In particular Helm/Terraform have their own ways of sharing config between envs
|
|
38
|
+
* aridity is a general purpose solution for all the above, also see [soak](https://github.com/combatopera/soak)
|
|
39
|
+
|
|
40
|
+
## Config API
|
|
41
|
+
* Normally you pass around a Config object, and application code can get data out via attribute access e.g. config.foo.bar
|
|
42
|
+
* Here config.foo is also a Config object, a child scope of config named foo
|
|
43
|
+
* The passing around can be taken care of by a dependency injection container such as [diapyr](https://github.com/combatopera/diapyr)
|
|
44
|
+
* Every Config has an associated ConfigCtrl on which Python API such as processtemplate is available
|
|
45
|
+
* Use negation to get ConfigCtrl when you have a Config e.g. (-config).processtemplate(...)
|
|
46
|
+
* Use the node attribute to get Config when you have a ConfigCtrl, this is a rare situation in practice
|
|
47
|
+
* When unit testing a class or function that expects a Config object, you can use SimpleNamespace to mock one
|
|
48
|
+
|
|
49
|
+
## Guidelines
|
|
50
|
+
* Config files have the extension .arid and templates .aridt
|
|
51
|
+
* A template is simply a file-sized aridity expression
|
|
52
|
+
* Conventionally the template processor sets " to the appropriate quote function for the file format, e.g. jsonquote for JSON/YAML
|
|
53
|
+
* Instead of adding Python objects to the config in main, it's tidier to use aridity's pyref function to achieve this
|
|
54
|
+
* When some value needs to be constructed using concatenation, consider whether it would be more tasteful to do this in the config
|
|
55
|
+
|
|
56
|
+
## Feature switch
|
|
57
|
+
* Sometimes we want to deploy a change, but something in production isn't ready for that change
|
|
58
|
+
* A feature switch allows deployment to production in this case
|
|
59
|
+
* Add a boolean to the base config (conventionally root.arid) e.g. foo enabled = true
|
|
60
|
+
* This value should be the configuration that we eventually want in all environments
|
|
61
|
+
* In production config, override with foo enabled = false
|
|
62
|
+
* In the code, read config.foo.enabled and enable the change based on this boolean
|
|
63
|
+
* The above can now be deployed to all environments, and is not a blocker for other changes
|
|
64
|
+
* Later when production is ready for it, it's a 1 line change to remove the override from production config
|
|
65
|
+
|
|
30
66
|
## Install
|
|
31
67
|
These are generic installation instructions.
|
|
32
68
|
|
|
@@ -16,6 +16,42 @@ DRY config and template system, easily extensible with Python
|
|
|
16
16
|
* Principle of least astonishment driven design
|
|
17
17
|
* Don't make users jump through hoops
|
|
18
18
|
|
|
19
|
+
## Motivation
|
|
20
|
+
* Environment variables are too crude to configure non-trivial apps, and maybe even trivial apps in the cloud
|
|
21
|
+
* They do not support nested data or lists, without some encoding scheme implemented in app code or a lib
|
|
22
|
+
* Multiple bespoke encoding schemes in the system are an error-prone maintenance burden worth avoiding
|
|
23
|
+
* Testing code that queries the environment directly comes with a big risk of leaking state between tests
|
|
24
|
+
* Often tools/libraries must be configured using config files
|
|
25
|
+
* Support for config file interpolation is not enough to stay DRY, and comes with a different set of gotchas per tool
|
|
26
|
+
* In particular Helm/Terraform have their own ways of sharing config between envs
|
|
27
|
+
* aridity is a general purpose solution for all the above, also see [soak](https://github.com/combatopera/soak)
|
|
28
|
+
|
|
29
|
+
## Config API
|
|
30
|
+
* Normally you pass around a Config object, and application code can get data out via attribute access e.g. config.foo.bar
|
|
31
|
+
* Here config.foo is also a Config object, a child scope of config named foo
|
|
32
|
+
* The passing around can be taken care of by a dependency injection container such as [diapyr](https://github.com/combatopera/diapyr)
|
|
33
|
+
* Every Config has an associated ConfigCtrl on which Python API such as processtemplate is available
|
|
34
|
+
* Use negation to get ConfigCtrl when you have a Config e.g. (-config).processtemplate(...)
|
|
35
|
+
* Use the node attribute to get Config when you have a ConfigCtrl, this is a rare situation in practice
|
|
36
|
+
* When unit testing a class or function that expects a Config object, you can use SimpleNamespace to mock one
|
|
37
|
+
|
|
38
|
+
## Guidelines
|
|
39
|
+
* Config files have the extension .arid and templates .aridt
|
|
40
|
+
* A template is simply a file-sized aridity expression
|
|
41
|
+
* Conventionally the template processor sets " to the appropriate quote function for the file format, e.g. jsonquote for JSON/YAML
|
|
42
|
+
* Instead of adding Python objects to the config in main, it's tidier to use aridity's pyref function to achieve this
|
|
43
|
+
* When some value needs to be constructed using concatenation, consider whether it would be more tasteful to do this in the config
|
|
44
|
+
|
|
45
|
+
## Feature switch
|
|
46
|
+
* Sometimes we want to deploy a change, but something in production isn't ready for that change
|
|
47
|
+
* A feature switch allows deployment to production in this case
|
|
48
|
+
* Add a boolean to the base config (conventionally root.arid) e.g. foo enabled = true
|
|
49
|
+
* This value should be the configuration that we eventually want in all environments
|
|
50
|
+
* In production config, override with foo enabled = false
|
|
51
|
+
* In the code, read config.foo.enabled and enable the change based on this boolean
|
|
52
|
+
* The above can now be deployed to all environments, and is not a blocker for other changes
|
|
53
|
+
* Later when production is ready for it, it's a 1 line change to remove the override from production config
|
|
54
|
+
|
|
19
55
|
## Install
|
|
20
56
|
These are generic installation instructions.
|
|
21
57
|
|
|
@@ -42,6 +42,7 @@ def _processmainfunction(mainfunction):
|
|
|
42
42
|
appname = scriptname[:-len(dotpy)].replace('_', '-')
|
|
43
43
|
else:
|
|
44
44
|
attr = mainfunction.__qualname__
|
|
45
|
+
# FIXME: Requires metadata e.g. egg-info in projects that have not been installed:
|
|
45
46
|
appname, = (ep.name for ep in entry_points(group = 'console_scripts') if ep.module == module and ep.attr == attr)
|
|
46
47
|
return module, appname
|
|
47
48
|
|
|
@@ -17,8 +17,11 @@
|
|
|
17
17
|
|
|
18
18
|
from .model import Scalar
|
|
19
19
|
from .util import null_exc_info
|
|
20
|
+
from base64 import b64decode
|
|
20
21
|
from functools import partial
|
|
21
22
|
from getpass import getpass
|
|
23
|
+
from subprocess import check_output
|
|
24
|
+
from tempfile import NamedTemporaryFile
|
|
22
25
|
from threading import Semaphore
|
|
23
26
|
import logging, os
|
|
24
27
|
|
|
@@ -51,3 +54,9 @@ def keyring(scope, serviceres, usernameres):
|
|
|
51
54
|
username = usernameres.resolve(scope).cat()
|
|
52
55
|
password = None if scope.resolved('keyring_force').scalar else get_password(service, username)
|
|
53
56
|
return Scalar(Password(*[getpass(), partial(set_password, service, username)] if password is None else [password, None]))
|
|
57
|
+
|
|
58
|
+
def gpg(scope, resolvable):
|
|
59
|
+
with NamedTemporaryFile() as f:
|
|
60
|
+
f.write(b64decode(resolvable.resolve(scope).cat()))
|
|
61
|
+
f.flush()
|
|
62
|
+
return Scalar(Password(check_output(['gpg', '-d', f.name]).decode('ascii'), None))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: aridity
|
|
3
|
-
Version:
|
|
3
|
+
Version: 63
|
|
4
4
|
Summary: DRY config and template system, easily extensible with Python
|
|
5
5
|
Home-page: https://github.com/combatopera/aridity
|
|
6
6
|
Author: Andrzej Cichocki
|
|
@@ -27,6 +27,42 @@ DRY config and template system, easily extensible with Python
|
|
|
27
27
|
* Principle of least astonishment driven design
|
|
28
28
|
* Don't make users jump through hoops
|
|
29
29
|
|
|
30
|
+
## Motivation
|
|
31
|
+
* Environment variables are too crude to configure non-trivial apps, and maybe even trivial apps in the cloud
|
|
32
|
+
* They do not support nested data or lists, without some encoding scheme implemented in app code or a lib
|
|
33
|
+
* Multiple bespoke encoding schemes in the system are an error-prone maintenance burden worth avoiding
|
|
34
|
+
* Testing code that queries the environment directly comes with a big risk of leaking state between tests
|
|
35
|
+
* Often tools/libraries must be configured using config files
|
|
36
|
+
* Support for config file interpolation is not enough to stay DRY, and comes with a different set of gotchas per tool
|
|
37
|
+
* In particular Helm/Terraform have their own ways of sharing config between envs
|
|
38
|
+
* aridity is a general purpose solution for all the above, also see [soak](https://github.com/combatopera/soak)
|
|
39
|
+
|
|
40
|
+
## Config API
|
|
41
|
+
* Normally you pass around a Config object, and application code can get data out via attribute access e.g. config.foo.bar
|
|
42
|
+
* Here config.foo is also a Config object, a child scope of config named foo
|
|
43
|
+
* The passing around can be taken care of by a dependency injection container such as [diapyr](https://github.com/combatopera/diapyr)
|
|
44
|
+
* Every Config has an associated ConfigCtrl on which Python API such as processtemplate is available
|
|
45
|
+
* Use negation to get ConfigCtrl when you have a Config e.g. (-config).processtemplate(...)
|
|
46
|
+
* Use the node attribute to get Config when you have a ConfigCtrl, this is a rare situation in practice
|
|
47
|
+
* When unit testing a class or function that expects a Config object, you can use SimpleNamespace to mock one
|
|
48
|
+
|
|
49
|
+
## Guidelines
|
|
50
|
+
* Config files have the extension .arid and templates .aridt
|
|
51
|
+
* A template is simply a file-sized aridity expression
|
|
52
|
+
* Conventionally the template processor sets " to the appropriate quote function for the file format, e.g. jsonquote for JSON/YAML
|
|
53
|
+
* Instead of adding Python objects to the config in main, it's tidier to use aridity's pyref function to achieve this
|
|
54
|
+
* When some value needs to be constructed using concatenation, consider whether it would be more tasteful to do this in the config
|
|
55
|
+
|
|
56
|
+
## Feature switch
|
|
57
|
+
* Sometimes we want to deploy a change, but something in production isn't ready for that change
|
|
58
|
+
* A feature switch allows deployment to production in this case
|
|
59
|
+
* Add a boolean to the base config (conventionally root.arid) e.g. foo enabled = true
|
|
60
|
+
* This value should be the configuration that we eventually want in all environments
|
|
61
|
+
* In production config, override with foo enabled = false
|
|
62
|
+
* In the code, read config.foo.enabled and enable the change based on this boolean
|
|
63
|
+
* The above can now be deployed to all environments, and is not a blocker for other changes
|
|
64
|
+
* Later when production is ready for it, it's a 1 line change to remove the override from production config
|
|
65
|
+
|
|
30
66
|
## Install
|
|
31
67
|
These are generic installation instructions.
|
|
32
68
|
|
|
@@ -136,7 +136,7 @@ def ext_modules():
|
|
|
136
136
|
sourceinfo = SourceInfo('.')
|
|
137
137
|
setuptools.setup(
|
|
138
138
|
name = 'aridity',
|
|
139
|
-
version = '
|
|
139
|
+
version = '63',
|
|
140
140
|
description = 'DRY config and template system, easily extensible with Python',
|
|
141
141
|
long_description = long_description(),
|
|
142
142
|
long_description_content_type = 'text/markdown',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|