aridity 77__tar.gz → 79__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-77/aridity.egg-info → aridity-79}/PKG-INFO +50 -15
- aridity-77/PKG-INFO → aridity-79/README.md +48 -25
- {aridity-77 → aridity-79}/aridity/functions.py +2 -2
- {aridity-77 → aridity-79}/aridity/keyring.py +7 -2
- aridity-77/README.md → aridity-79/aridity.egg-info/PKG-INFO +60 -13
- {aridity-77 → aridity-79}/aridity.egg-info/requires.txt +1 -1
- {aridity-77 → aridity-79}/setup.cfg +1 -1
- aridity-79/setup.py +62 -0
- aridity-77/setup.py +0 -21
- {aridity-77 → aridity-79}/aridity/__init__.py +0 -0
- {aridity-77 → aridity-79}/aridity/arid_config.py +0 -0
- {aridity-77 → aridity-79}/aridity/config.py +0 -0
- {aridity-77 → aridity-79}/aridity/directives.py +0 -0
- {aridity-77 → aridity-79}/aridity/grammar.py +0 -0
- {aridity-77 → aridity-79}/aridity/model.py +0 -0
- {aridity-77 → aridity-79}/aridity/processtemplate.py +0 -0
- {aridity-77 → aridity-79}/aridity/repl.py +0 -0
- {aridity-77 → aridity-79}/aridity/resolve.py +0 -0
- {aridity-77 → aridity-79}/aridity/scope.py +0 -0
- {aridity-77 → aridity-79}/aridity/search.py +0 -0
- {aridity-77 → aridity-79}/aridity/stacks.py +0 -0
- {aridity-77 → aridity-79}/aridity/util.py +0 -0
- {aridity-77 → aridity-79}/aridity.egg-info/SOURCES.txt +0 -0
- {aridity-77 → aridity-79}/aridity.egg-info/dependency_links.txt +0 -0
- {aridity-77 → aridity-79}/aridity.egg-info/entry_points.txt +0 -0
- {aridity-77 → aridity-79}/aridity.egg-info/top_level.txt +0 -0
- {aridity-77 → aridity-79}/parabject.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: aridity
|
|
3
|
-
Version:
|
|
3
|
+
Version: 79
|
|
4
4
|
Summary: DRY config and template system, easily extensible with Python
|
|
5
5
|
Home-page: https://pypi.org/project/aridity/
|
|
6
6
|
Author: foyono
|
|
@@ -8,11 +8,46 @@ Author-email: shrovis@foyono.com
|
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
Requires-Dist: importlib-metadata>=2.1.3
|
|
10
10
|
Requires-Dist: importlib-resources>=3.3.1
|
|
11
|
-
Requires-Dist: pyparsing
|
|
11
|
+
Requires-Dist: pyparsing>=3.0.2
|
|
12
12
|
|
|
13
13
|
# aridity
|
|
14
14
|
DRY config and template system, easily extensible with Python
|
|
15
15
|
|
|
16
|
+
## Typical usage
|
|
17
|
+
Main module of dbtool app:
|
|
18
|
+
```
|
|
19
|
+
from aridity.config import ConfigCtrl
|
|
20
|
+
|
|
21
|
+
def main():
|
|
22
|
+
# Deduce app name from main function and create scope of that name, load dbtool.arid into that scope, load .settings.arid into the root scope, and return app scope:
|
|
23
|
+
config = ConfigCtrl().loadappconfig(main, 'dbtool.arid')
|
|
24
|
+
print(config.dbhost)
|
|
25
|
+
```
|
|
26
|
+
Sibling dbtool.arid of main module, self-documenting that `dbhost` should be configured:
|
|
27
|
+
```
|
|
28
|
+
dbhost = $(void)
|
|
29
|
+
```
|
|
30
|
+
Shared config file `.settings.arid` in home directory:
|
|
31
|
+
```
|
|
32
|
+
dbtool dbhost = anaximander.local
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Integration with argparse
|
|
36
|
+
App config file:
|
|
37
|
+
```
|
|
38
|
+
cli v = $(void)
|
|
39
|
+
verbose = $(cli v)
|
|
40
|
+
```
|
|
41
|
+
Main function:
|
|
42
|
+
```
|
|
43
|
+
def main():
|
|
44
|
+
config = ConfigCtrl().loadappconfig(main, 'dbtool.arid')
|
|
45
|
+
parser = ArgumentParser()
|
|
46
|
+
parser.add_argument('-v', action = 'store_true')
|
|
47
|
+
parser.parse_args(namespace = config.cli)
|
|
48
|
+
print(config.verbose)
|
|
49
|
+
```
|
|
50
|
+
|
|
16
51
|
## The Arid Manifesto
|
|
17
52
|
* Keys are paths to avoid concatenation
|
|
18
53
|
* It's never necessary to repeat a value
|
|
@@ -23,7 +58,7 @@ DRY config and template system, easily extensible with Python
|
|
|
23
58
|
* Templating using same syntax as expressions
|
|
24
59
|
* Easy to correctly quote/escape values in templates
|
|
25
60
|
* Extensibility via user-defined functions
|
|
26
|
-
*
|
|
61
|
+
* Common tasks are easy, rare tasks are possible
|
|
27
62
|
* Many applications can share one user config
|
|
28
63
|
* Principle of least astonishment driven design
|
|
29
64
|
* Don't make users jump through hoops
|
|
@@ -39,28 +74,28 @@ DRY config and template system, easily extensible with Python
|
|
|
39
74
|
* aridity is a general purpose solution for all the above, also see [soak](https://pypi.org/project/soak/)
|
|
40
75
|
|
|
41
76
|
## Config API
|
|
42
|
-
* Normally you pass around a Config object, and application code can get data out via attribute access e.g. config.foo.bar
|
|
43
|
-
* Here config.foo is also a Config object, a child scope of config named foo
|
|
77
|
+
* Normally you pass around a `Config` object, and application code can get data out via attribute access e.g. `config.foo.bar`
|
|
78
|
+
* Here `config.foo` is also a Config object, a child scope of `config` named foo
|
|
44
79
|
* The passing around can be taken care of by a dependency injection container such as [diapyr](https://pypi.org/project/diapyr/)
|
|
45
|
-
* Every Config has an associated ConfigCtrl on which Python API such as processtemplate is available
|
|
46
|
-
* Use negation to get ConfigCtrl when you have a Config e.g. (-config).processtemplate(...)
|
|
47
|
-
* Use the node attribute to get Config when you have a ConfigCtrl, this is a rare situation in practice
|
|
80
|
+
* Every Config has an associated ConfigCtrl on which Python API such as `processtemplate` is available
|
|
81
|
+
* Use negation to get ConfigCtrl when you have a Config e.g. `(-config).processtemplate(...)`
|
|
82
|
+
* Use the `node` attribute to get Config when you have a ConfigCtrl, this is a rare situation in practice
|
|
48
83
|
* When unit testing a class or function that expects a Config object, you can use SimpleNamespace to mock one
|
|
49
84
|
|
|
50
85
|
## Guidelines
|
|
51
|
-
* Config files have the extension
|
|
86
|
+
* Config files have the extension `.arid` and templates `.aridt`
|
|
52
87
|
* A template is simply a file-sized aridity expression
|
|
53
|
-
* Conventionally the template processor sets " to the appropriate quote function for the file format, e.g. jsonquote for JSON/YAML
|
|
54
|
-
* Instead of adding Python objects to the config in main
|
|
88
|
+
* Conventionally the template processor sets `"` to the appropriate quote function for the file format, e.g. `jsonquote` for JSON/YAML
|
|
89
|
+
* Instead of adding Python objects to the config in `main`, it's tidier to use aridity's `pyref` function to achieve this
|
|
55
90
|
* When some value needs to be constructed using concatenation, consider whether it would be more tasteful to do this in the config
|
|
56
91
|
|
|
57
92
|
## Feature switch
|
|
58
93
|
* Sometimes we want to deploy a change, but something in production isn't ready for that change
|
|
59
94
|
* A feature switch allows deployment to production in this case
|
|
60
|
-
* Add a boolean to the base config (conventionally root.arid) e.g. foo enabled = true
|
|
95
|
+
* Add a boolean to the base config (conventionally root.arid) e.g. `foo enabled = true`
|
|
61
96
|
* This value should be the configuration that we eventually want in all environments
|
|
62
|
-
* In production config, override with foo enabled = false
|
|
63
|
-
* In the code, read config.foo.enabled and enable the change based on this boolean
|
|
97
|
+
* In production config, override with `foo enabled = false`
|
|
98
|
+
* In the code, read `config.foo.enabled` and enable the change based on this boolean
|
|
64
99
|
* The above can now be deployed to all environments, and is not a blocker for other changes
|
|
65
100
|
* Later when production is ready for it, it's a 1 line change to remove the override from production config
|
|
66
101
|
|
|
@@ -604,7 +639,7 @@ Python object in given module with given qualified name. Module may be relative
|
|
|
604
639
|
###### pyres
|
|
605
640
|
|
|
606
641
|
```python
|
|
607
|
-
def pyres(scope, packageresolvable, nameresolvable)
|
|
642
|
+
def pyres(scope, packageresolvable, nameresolvable, encoding=Text('ascii'))
|
|
608
643
|
```
|
|
609
644
|
|
|
610
645
|
Python resource for inclusion with `.` directive.
|
|
@@ -1,18 +1,41 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: aridity
|
|
3
|
-
Version: 77
|
|
4
|
-
Summary: DRY config and template system, easily extensible with Python
|
|
5
|
-
Home-page: https://pypi.org/project/aridity/
|
|
6
|
-
Author: foyono
|
|
7
|
-
Author-email: shrovis@foyono.com
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
Requires-Dist: importlib-metadata>=2.1.3
|
|
10
|
-
Requires-Dist: importlib-resources>=3.3.1
|
|
11
|
-
Requires-Dist: pyparsing==2.4.7
|
|
12
|
-
|
|
13
1
|
# aridity
|
|
14
2
|
DRY config and template system, easily extensible with Python
|
|
15
3
|
|
|
4
|
+
## Typical usage
|
|
5
|
+
Main module of dbtool app:
|
|
6
|
+
```
|
|
7
|
+
from aridity.config import ConfigCtrl
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
# Deduce app name from main function and create scope of that name, load dbtool.arid into that scope, load .settings.arid into the root scope, and return app scope:
|
|
11
|
+
config = ConfigCtrl().loadappconfig(main, 'dbtool.arid')
|
|
12
|
+
print(config.dbhost)
|
|
13
|
+
```
|
|
14
|
+
Sibling dbtool.arid of main module, self-documenting that `dbhost` should be configured:
|
|
15
|
+
```
|
|
16
|
+
dbhost = $(void)
|
|
17
|
+
```
|
|
18
|
+
Shared config file `.settings.arid` in home directory:
|
|
19
|
+
```
|
|
20
|
+
dbtool dbhost = anaximander.local
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Integration with argparse
|
|
24
|
+
App config file:
|
|
25
|
+
```
|
|
26
|
+
cli v = $(void)
|
|
27
|
+
verbose = $(cli v)
|
|
28
|
+
```
|
|
29
|
+
Main function:
|
|
30
|
+
```
|
|
31
|
+
def main():
|
|
32
|
+
config = ConfigCtrl().loadappconfig(main, 'dbtool.arid')
|
|
33
|
+
parser = ArgumentParser()
|
|
34
|
+
parser.add_argument('-v', action = 'store_true')
|
|
35
|
+
parser.parse_args(namespace = config.cli)
|
|
36
|
+
print(config.verbose)
|
|
37
|
+
```
|
|
38
|
+
|
|
16
39
|
## The Arid Manifesto
|
|
17
40
|
* Keys are paths to avoid concatenation
|
|
18
41
|
* It's never necessary to repeat a value
|
|
@@ -23,7 +46,7 @@ DRY config and template system, easily extensible with Python
|
|
|
23
46
|
* Templating using same syntax as expressions
|
|
24
47
|
* Easy to correctly quote/escape values in templates
|
|
25
48
|
* Extensibility via user-defined functions
|
|
26
|
-
*
|
|
49
|
+
* Common tasks are easy, rare tasks are possible
|
|
27
50
|
* Many applications can share one user config
|
|
28
51
|
* Principle of least astonishment driven design
|
|
29
52
|
* Don't make users jump through hoops
|
|
@@ -39,28 +62,28 @@ DRY config and template system, easily extensible with Python
|
|
|
39
62
|
* aridity is a general purpose solution for all the above, also see [soak](https://pypi.org/project/soak/)
|
|
40
63
|
|
|
41
64
|
## Config API
|
|
42
|
-
* Normally you pass around a Config object, and application code can get data out via attribute access e.g. config.foo.bar
|
|
43
|
-
* Here config.foo is also a Config object, a child scope of config named foo
|
|
65
|
+
* Normally you pass around a `Config` object, and application code can get data out via attribute access e.g. `config.foo.bar`
|
|
66
|
+
* Here `config.foo` is also a Config object, a child scope of `config` named foo
|
|
44
67
|
* The passing around can be taken care of by a dependency injection container such as [diapyr](https://pypi.org/project/diapyr/)
|
|
45
|
-
* Every Config has an associated ConfigCtrl on which Python API such as processtemplate is available
|
|
46
|
-
* Use negation to get ConfigCtrl when you have a Config e.g. (-config).processtemplate(...)
|
|
47
|
-
* Use the node attribute to get Config when you have a ConfigCtrl, this is a rare situation in practice
|
|
68
|
+
* Every Config has an associated ConfigCtrl on which Python API such as `processtemplate` is available
|
|
69
|
+
* Use negation to get ConfigCtrl when you have a Config e.g. `(-config).processtemplate(...)`
|
|
70
|
+
* Use the `node` attribute to get Config when you have a ConfigCtrl, this is a rare situation in practice
|
|
48
71
|
* When unit testing a class or function that expects a Config object, you can use SimpleNamespace to mock one
|
|
49
72
|
|
|
50
73
|
## Guidelines
|
|
51
|
-
* Config files have the extension
|
|
74
|
+
* Config files have the extension `.arid` and templates `.aridt`
|
|
52
75
|
* A template is simply a file-sized aridity expression
|
|
53
|
-
* Conventionally the template processor sets " to the appropriate quote function for the file format, e.g. jsonquote for JSON/YAML
|
|
54
|
-
* Instead of adding Python objects to the config in main
|
|
76
|
+
* Conventionally the template processor sets `"` to the appropriate quote function for the file format, e.g. `jsonquote` for JSON/YAML
|
|
77
|
+
* Instead of adding Python objects to the config in `main`, it's tidier to use aridity's `pyref` function to achieve this
|
|
55
78
|
* When some value needs to be constructed using concatenation, consider whether it would be more tasteful to do this in the config
|
|
56
79
|
|
|
57
80
|
## Feature switch
|
|
58
81
|
* Sometimes we want to deploy a change, but something in production isn't ready for that change
|
|
59
82
|
* A feature switch allows deployment to production in this case
|
|
60
|
-
* Add a boolean to the base config (conventionally root.arid) e.g. foo enabled = true
|
|
83
|
+
* Add a boolean to the base config (conventionally root.arid) e.g. `foo enabled = true`
|
|
61
84
|
* This value should be the configuration that we eventually want in all environments
|
|
62
|
-
* In production config, override with foo enabled = false
|
|
63
|
-
* In the code, read config.foo.enabled and enable the change based on this boolean
|
|
85
|
+
* In production config, override with `foo enabled = false`
|
|
86
|
+
* In the code, read `config.foo.enabled` and enable the change based on this boolean
|
|
64
87
|
* The above can now be deployed to all environments, and is not a blocker for other changes
|
|
65
88
|
* Later when production is ready for it, it's a 1 line change to remove the override from production config
|
|
66
89
|
|
|
@@ -604,7 +627,7 @@ Python object in given module with given qualified name. Module may be relative
|
|
|
604
627
|
###### pyres
|
|
605
628
|
|
|
606
629
|
```python
|
|
607
|
-
def pyres(scope, packageresolvable, nameresolvable)
|
|
630
|
+
def pyres(scope, packageresolvable, nameresolvable, encoding=Text('ascii'))
|
|
608
631
|
```
|
|
609
632
|
|
|
610
633
|
Python resource for inclusion with `.` directive.
|
|
@@ -221,9 +221,9 @@ class Functions:
|
|
|
221
221
|
pyobj = getattr(pyobj, name)
|
|
222
222
|
return wrap(pyobj)
|
|
223
223
|
|
|
224
|
-
def pyres(scope, packageresolvable, nameresolvable):
|
|
224
|
+
def pyres(scope, packageresolvable, nameresolvable, encoding = Text('ascii')):
|
|
225
225
|
'Python resource for inclusion with `.` directive.'
|
|
226
|
-
return Resource(packageresolvable.resolve(scope).cat(), nameresolvable.resolve(scope).cat())
|
|
226
|
+
return Resource(packageresolvable.resolve(scope).cat(), nameresolvable.resolve(scope).cat(), encoding.resolve(scope).cat())
|
|
227
227
|
|
|
228
228
|
@realname('\N{NOT SIGN}')
|
|
229
229
|
def not_(scope, resolvable):
|
|
@@ -3,7 +3,7 @@ from .util import null_exc_info
|
|
|
3
3
|
from base64 import b64decode
|
|
4
4
|
from functools import partial
|
|
5
5
|
from getpass import getpass
|
|
6
|
-
from subprocess import check_output
|
|
6
|
+
from subprocess import CalledProcessError, check_output
|
|
7
7
|
from tempfile import NamedTemporaryFile
|
|
8
8
|
from threading import Semaphore
|
|
9
9
|
import logging, os
|
|
@@ -38,9 +38,14 @@ def keyring(scope, serviceres, usernameres):
|
|
|
38
38
|
password = None if scope.resolved('keyring_force').scalar else get_password(service, username)
|
|
39
39
|
return Scalar(Password(*[getpass(), partial(set_password, service, username)] if password is None else [password, None]))
|
|
40
40
|
|
|
41
|
+
class DecryptionFailedException(Exception): pass
|
|
42
|
+
|
|
41
43
|
def gpg(scope, resolvable):
|
|
42
44
|
'Use gpg to decrypt the given base64-encoded blob.'
|
|
43
45
|
with NamedTemporaryFile() as f:
|
|
44
46
|
f.write(b64decode(resolvable.resolve(scope).cat()))
|
|
45
47
|
f.flush()
|
|
46
|
-
|
|
48
|
+
try:
|
|
49
|
+
return Scalar(Password(check_output(['gpg', '-d', f.name]).decode('ascii'), None))
|
|
50
|
+
except CalledProcessError:
|
|
51
|
+
raise DecryptionFailedException
|
|
@@ -1,6 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: aridity
|
|
3
|
+
Version: 79
|
|
4
|
+
Summary: DRY config and template system, easily extensible with Python
|
|
5
|
+
Home-page: https://pypi.org/project/aridity/
|
|
6
|
+
Author: foyono
|
|
7
|
+
Author-email: shrovis@foyono.com
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: importlib-metadata>=2.1.3
|
|
10
|
+
Requires-Dist: importlib-resources>=3.3.1
|
|
11
|
+
Requires-Dist: pyparsing>=3.0.2
|
|
12
|
+
|
|
1
13
|
# aridity
|
|
2
14
|
DRY config and template system, easily extensible with Python
|
|
3
15
|
|
|
16
|
+
## Typical usage
|
|
17
|
+
Main module of dbtool app:
|
|
18
|
+
```
|
|
19
|
+
from aridity.config import ConfigCtrl
|
|
20
|
+
|
|
21
|
+
def main():
|
|
22
|
+
# Deduce app name from main function and create scope of that name, load dbtool.arid into that scope, load .settings.arid into the root scope, and return app scope:
|
|
23
|
+
config = ConfigCtrl().loadappconfig(main, 'dbtool.arid')
|
|
24
|
+
print(config.dbhost)
|
|
25
|
+
```
|
|
26
|
+
Sibling dbtool.arid of main module, self-documenting that `dbhost` should be configured:
|
|
27
|
+
```
|
|
28
|
+
dbhost = $(void)
|
|
29
|
+
```
|
|
30
|
+
Shared config file `.settings.arid` in home directory:
|
|
31
|
+
```
|
|
32
|
+
dbtool dbhost = anaximander.local
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Integration with argparse
|
|
36
|
+
App config file:
|
|
37
|
+
```
|
|
38
|
+
cli v = $(void)
|
|
39
|
+
verbose = $(cli v)
|
|
40
|
+
```
|
|
41
|
+
Main function:
|
|
42
|
+
```
|
|
43
|
+
def main():
|
|
44
|
+
config = ConfigCtrl().loadappconfig(main, 'dbtool.arid')
|
|
45
|
+
parser = ArgumentParser()
|
|
46
|
+
parser.add_argument('-v', action = 'store_true')
|
|
47
|
+
parser.parse_args(namespace = config.cli)
|
|
48
|
+
print(config.verbose)
|
|
49
|
+
```
|
|
50
|
+
|
|
4
51
|
## The Arid Manifesto
|
|
5
52
|
* Keys are paths to avoid concatenation
|
|
6
53
|
* It's never necessary to repeat a value
|
|
@@ -11,7 +58,7 @@ DRY config and template system, easily extensible with Python
|
|
|
11
58
|
* Templating using same syntax as expressions
|
|
12
59
|
* Easy to correctly quote/escape values in templates
|
|
13
60
|
* Extensibility via user-defined functions
|
|
14
|
-
*
|
|
61
|
+
* Common tasks are easy, rare tasks are possible
|
|
15
62
|
* Many applications can share one user config
|
|
16
63
|
* Principle of least astonishment driven design
|
|
17
64
|
* Don't make users jump through hoops
|
|
@@ -27,28 +74,28 @@ DRY config and template system, easily extensible with Python
|
|
|
27
74
|
* aridity is a general purpose solution for all the above, also see [soak](https://pypi.org/project/soak/)
|
|
28
75
|
|
|
29
76
|
## 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
|
|
77
|
+
* Normally you pass around a `Config` object, and application code can get data out via attribute access e.g. `config.foo.bar`
|
|
78
|
+
* Here `config.foo` is also a Config object, a child scope of `config` named foo
|
|
32
79
|
* The passing around can be taken care of by a dependency injection container such as [diapyr](https://pypi.org/project/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
|
|
80
|
+
* Every Config has an associated ConfigCtrl on which Python API such as `processtemplate` is available
|
|
81
|
+
* Use negation to get ConfigCtrl when you have a Config e.g. `(-config).processtemplate(...)`
|
|
82
|
+
* Use the `node` attribute to get Config when you have a ConfigCtrl, this is a rare situation in practice
|
|
36
83
|
* When unit testing a class or function that expects a Config object, you can use SimpleNamespace to mock one
|
|
37
84
|
|
|
38
85
|
## Guidelines
|
|
39
|
-
* Config files have the extension
|
|
86
|
+
* Config files have the extension `.arid` and templates `.aridt`
|
|
40
87
|
* 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
|
|
88
|
+
* Conventionally the template processor sets `"` to the appropriate quote function for the file format, e.g. `jsonquote` for JSON/YAML
|
|
89
|
+
* Instead of adding Python objects to the config in `main`, it's tidier to use aridity's `pyref` function to achieve this
|
|
43
90
|
* When some value needs to be constructed using concatenation, consider whether it would be more tasteful to do this in the config
|
|
44
91
|
|
|
45
92
|
## Feature switch
|
|
46
93
|
* Sometimes we want to deploy a change, but something in production isn't ready for that change
|
|
47
94
|
* 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
|
|
95
|
+
* Add a boolean to the base config (conventionally root.arid) e.g. `foo enabled = true`
|
|
49
96
|
* 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
|
|
97
|
+
* In production config, override with `foo enabled = false`
|
|
98
|
+
* In the code, read `config.foo.enabled` and enable the change based on this boolean
|
|
52
99
|
* The above can now be deployed to all environments, and is not a blocker for other changes
|
|
53
100
|
* Later when production is ready for it, it's a 1 line change to remove the override from production config
|
|
54
101
|
|
|
@@ -592,7 +639,7 @@ Python object in given module with given qualified name. Module may be relative
|
|
|
592
639
|
###### pyres
|
|
593
640
|
|
|
594
641
|
```python
|
|
595
|
-
def pyres(scope, packageresolvable, nameresolvable)
|
|
642
|
+
def pyres(scope, packageresolvable, nameresolvable, encoding=Text('ascii'))
|
|
596
643
|
```
|
|
597
644
|
|
|
598
645
|
Python resource for inclusion with `.` directive.
|
aridity-79/setup.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from setuptools import setup
|
|
2
|
+
try:
|
|
3
|
+
from Cython.Build import cythonize
|
|
4
|
+
except ModuleNotFoundError:
|
|
5
|
+
pass
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from setuptools import find_packages
|
|
8
|
+
import os
|
|
9
|
+
|
|
10
|
+
class SourceInfo:
|
|
11
|
+
|
|
12
|
+
class PYXPath:
|
|
13
|
+
|
|
14
|
+
def __init__(self, module, path):
|
|
15
|
+
self.module = module
|
|
16
|
+
self.path = path
|
|
17
|
+
|
|
18
|
+
def make_ext(self):
|
|
19
|
+
g = {}
|
|
20
|
+
with open(f"{self.path}bld") as f: # Assume project root.
|
|
21
|
+
exec(f.read(), g)
|
|
22
|
+
return g['make_ext'](self.module, self.path)
|
|
23
|
+
|
|
24
|
+
def __init__(self, rootdir):
|
|
25
|
+
def addextpaths(dirpath, moduleprefix, suffix = '.pyx'):
|
|
26
|
+
for name in sorted(os.listdir(os.path.join(rootdir, dirpath))):
|
|
27
|
+
if name.endswith(suffix):
|
|
28
|
+
module = f"{moduleprefix}{name[:-len(suffix)]}"
|
|
29
|
+
if module not in extpaths:
|
|
30
|
+
extpaths[module] = self.PYXPath(module, os.path.join(dirpath, name))
|
|
31
|
+
self.packages = find_packages(rootdir)
|
|
32
|
+
extpaths = {}
|
|
33
|
+
addextpaths('.', '')
|
|
34
|
+
for package in self.packages:
|
|
35
|
+
addextpaths(package.replace('.', os.sep), f"{package}.")
|
|
36
|
+
self.extpaths = extpaths.values()
|
|
37
|
+
|
|
38
|
+
def setup_kwargs(self):
|
|
39
|
+
kwargs = dict(packages = self.packages)
|
|
40
|
+
try:
|
|
41
|
+
kwargs['long_description'] = Path('README.md').read_text()
|
|
42
|
+
kwargs['long_description_content_type'] = 'text/markdown'
|
|
43
|
+
except FileNotFoundError:
|
|
44
|
+
pass
|
|
45
|
+
if self.extpaths:
|
|
46
|
+
kwargs['ext_modules'] = cythonize([path.make_ext() for path in self.extpaths])
|
|
47
|
+
return kwargs
|
|
48
|
+
|
|
49
|
+
sourceinfo = SourceInfo('.')
|
|
50
|
+
setup(
|
|
51
|
+
name = 'aridity',
|
|
52
|
+
version = '79',
|
|
53
|
+
description = 'DRY config and template system, easily extensible with Python',
|
|
54
|
+
url = 'https://pypi.org/project/aridity/',
|
|
55
|
+
author = 'foyono',
|
|
56
|
+
author_email = 'shrovis@foyono.com',
|
|
57
|
+
py_modules = ['parabject'],
|
|
58
|
+
install_requires = ['importlib-metadata>=2.1.3', 'importlib-resources>=3.3.1', 'pyparsing>=3.0.2'],
|
|
59
|
+
package_data = {'': ['*.pxd', '*.pyx', '*.pyxbld', '*.arid', '*.aridt']},
|
|
60
|
+
entry_points = {'console_scripts': ['aridity=aridity.__init__:main', 'arid-config=aridity.arid_config:main', 'processtemplate=aridity.processtemplate:main']},
|
|
61
|
+
**sourceinfo.setup_kwargs(),
|
|
62
|
+
)
|
aridity-77/setup.py
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
from setuptools import find_packages, setup
|
|
2
|
-
|
|
3
|
-
def long_description():
|
|
4
|
-
with open('README.md') as f:
|
|
5
|
-
return f.read()
|
|
6
|
-
|
|
7
|
-
setup(
|
|
8
|
-
name = 'aridity',
|
|
9
|
-
version = '77',
|
|
10
|
-
description = 'DRY config and template system, easily extensible with Python',
|
|
11
|
-
long_description = long_description(),
|
|
12
|
-
long_description_content_type = 'text/markdown',
|
|
13
|
-
url = 'https://pypi.org/project/aridity/',
|
|
14
|
-
author = 'foyono',
|
|
15
|
-
author_email = 'shrovis@foyono.com',
|
|
16
|
-
packages = find_packages(),
|
|
17
|
-
py_modules = ['parabject'],
|
|
18
|
-
install_requires = ['importlib-metadata>=2.1.3', 'importlib-resources>=3.3.1', 'pyparsing==2.4.7'],
|
|
19
|
-
package_data = {'': ['*.pxd', '*.pyx', '*.pyxbld', '*.arid', '*.aridt']},
|
|
20
|
-
entry_points = {'console_scripts': ['aridity=aridity.__init__:main', 'arid-config=aridity.arid_config:main', 'processtemplate=aridity.processtemplate:main']},
|
|
21
|
-
)
|
|
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
|
|
File without changes
|