magicli 2.1.3__tar.gz → 2.1.4__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.
- {magicli-2.1.3 → magicli-2.1.4}/.github/workflows/lint.yml +9 -8
- {magicli-2.1.3 → magicli-2.1.4}/.github/workflows/pytest.yml +3 -2
- {magicli-2.1.3 → magicli-2.1.4}/.github/workflows/release.yml +2 -2
- {magicli-2.1.3 → magicli-2.1.4}/PKG-INFO +32 -38
- magicli-2.1.4/README.md +90 -0
- magicli-2.1.4/docs/img/hello.svg +1 -0
- {magicli-2.1.3 → magicli-2.1.4}/magicli.egg-info/PKG-INFO +32 -38
- {magicli-2.1.3 → magicli-2.1.4}/magicli.egg-info/SOURCES.txt +1 -0
- {magicli-2.1.3 → magicli-2.1.4}/magicli.py +6 -5
- magicli-2.1.3/README.md +0 -96
- {magicli-2.1.3 → magicli-2.1.4}/.gitignore +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/LICENSE +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/magicli.egg-info/dependency_links.txt +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/magicli.egg-info/entry_points.txt +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/magicli.egg-info/requires.txt +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/magicli.egg-info/top_level.txt +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/pyproject.toml +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/setup.cfg +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/tests/fixtures.py +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/tests/test_cli.py +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/tests/test_help.py +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/tests/test_magicli.py +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/tests/test_parse_kwarg.py +0 -0
- {magicli-2.1.3 → magicli-2.1.4}/tests/test_parse_short_options.py +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
name: Lint
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
+
workflow_dispatch:
|
|
4
5
|
pull_request:
|
|
5
6
|
paths:
|
|
6
7
|
- magicli.py
|
|
@@ -9,8 +10,8 @@ jobs:
|
|
|
9
10
|
flake8:
|
|
10
11
|
runs-on: ubuntu-latest
|
|
11
12
|
steps:
|
|
12
|
-
- uses: actions/checkout@
|
|
13
|
-
- uses: astral-sh/setup-uv@
|
|
13
|
+
- uses: actions/checkout@v6
|
|
14
|
+
- uses: astral-sh/setup-uv@v8.1.0
|
|
14
15
|
with:
|
|
15
16
|
cache-dependency-glob: ""
|
|
16
17
|
- run: uv run --with flake8 flake8 magicli.py --extend-ignore=E203,E501
|
|
@@ -18,8 +19,8 @@ jobs:
|
|
|
18
19
|
pylint:
|
|
19
20
|
runs-on: ubuntu-latest
|
|
20
21
|
steps:
|
|
21
|
-
- uses: actions/checkout@
|
|
22
|
-
- uses: astral-sh/setup-uv@
|
|
22
|
+
- uses: actions/checkout@v6
|
|
23
|
+
- uses: astral-sh/setup-uv@v8.1.0
|
|
23
24
|
with:
|
|
24
25
|
cache-dependency-glob: ""
|
|
25
26
|
- run: uv run --with pylint pylint magicli.py
|
|
@@ -27,8 +28,8 @@ jobs:
|
|
|
27
28
|
ruff:
|
|
28
29
|
runs-on: ubuntu-latest
|
|
29
30
|
steps:
|
|
30
|
-
- uses: actions/checkout@
|
|
31
|
-
- uses: astral-sh/setup-uv@
|
|
31
|
+
- uses: actions/checkout@v6
|
|
32
|
+
- uses: astral-sh/setup-uv@v8.1.0
|
|
32
33
|
with:
|
|
33
34
|
cache-dependency-glob: ""
|
|
34
35
|
- run: uv run --with ruff ruff format magicli.py --diff
|
|
@@ -36,8 +37,8 @@ jobs:
|
|
|
36
37
|
isort:
|
|
37
38
|
runs-on: ubuntu-latest
|
|
38
39
|
steps:
|
|
39
|
-
- uses: actions/checkout@
|
|
40
|
-
- uses: astral-sh/setup-uv@
|
|
40
|
+
- uses: actions/checkout@v6
|
|
41
|
+
- uses: astral-sh/setup-uv@v8.1.0
|
|
41
42
|
with:
|
|
42
43
|
cache-dependency-glob: ""
|
|
43
44
|
- run: uv run --with isort isort --check --diff magicli.py
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
name: Pytest
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
+
workflow_dispatch:
|
|
4
5
|
pull_request:
|
|
5
6
|
paths:
|
|
6
7
|
- "**/*.py"
|
|
@@ -13,8 +14,8 @@ jobs:
|
|
|
13
14
|
matrix:
|
|
14
15
|
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
15
16
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
17
|
-
- uses: astral-sh/setup-uv@
|
|
17
|
+
- uses: actions/checkout@v6
|
|
18
|
+
- uses: astral-sh/setup-uv@v8.1.0
|
|
18
19
|
with:
|
|
19
20
|
cache-dependency-glob: ""
|
|
20
21
|
python-version: ${{ matrix.python-version }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: magicli
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.4
|
|
4
4
|
Summary: Automatically generates a CLI from functions.
|
|
5
5
|
Author-email: Patrick Elmer <patrick@elmer.ws>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -13,70 +13,64 @@ Dynamic: license-file
|
|
|
13
13
|
|
|
14
14
|
# magiᴄʟɪ✨
|
|
15
15
|
|
|
16
|
-
Automatically
|
|
16
|
+
Automatically turns a file into a CLI without any boilerplate by introspecting its functions.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
**`hello world` example**
|
|
19
19
|
|
|
20
|
-
```
|
|
21
|
-
|
|
20
|
+
```python
|
|
21
|
+
# hello.py
|
|
22
|
+
def hello(name, greeting="hello"):
|
|
23
|
+
print(greeting, name)
|
|
22
24
|
```
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
becomes
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
<img src="docs/img/hello.svg"/>
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
# module.py
|
|
30
|
-
def hello(name, times=1):
|
|
31
|
-
for _ in range(times):
|
|
32
|
-
print("hello", name)
|
|
33
|
-
```
|
|
30
|
+
with only 3 commands
|
|
34
31
|
|
|
35
|
-
|
|
32
|
+
1. `pip install magicli`
|
|
33
|
+
1. `magicli`
|
|
34
|
+
1. `pip install .`
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
magicli
|
|
39
|
-
```
|
|
36
|
+
## Quick start
|
|
40
37
|
|
|
41
|
-
|
|
38
|
+
### Install magicli
|
|
42
39
|
|
|
43
|
-
```
|
|
44
|
-
pip install
|
|
40
|
+
```
|
|
41
|
+
pip install magicli
|
|
45
42
|
```
|
|
46
43
|
|
|
47
|
-
|
|
44
|
+
### Setup your repository
|
|
45
|
+
|
|
46
|
+
Initialize repo
|
|
48
47
|
|
|
49
48
|
```bash
|
|
50
|
-
|
|
51
|
-
hello world
|
|
52
|
-
hello world
|
|
49
|
+
git init
|
|
53
50
|
```
|
|
54
51
|
|
|
55
|
-
|
|
52
|
+
Add version info (optional)
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
```toml
|
|
60
|
-
[project.scripts]
|
|
61
|
-
hello = "magicli:magicli"
|
|
54
|
+
```bash
|
|
55
|
+
git tag 1.0.0
|
|
62
56
|
```
|
|
63
57
|
|
|
64
|
-
|
|
58
|
+
### Automatically create CLI
|
|
65
59
|
|
|
66
60
|
```bash
|
|
67
|
-
|
|
68
|
-
├── hello.py
|
|
69
|
-
└── pyproject.toml
|
|
61
|
+
magicli
|
|
70
62
|
```
|
|
71
63
|
|
|
72
|
-
|
|
64
|
+
_Make sure the name of your CLI, the module name and the name of the function have to same name._
|
|
65
|
+
|
|
66
|
+
### Install your Python package
|
|
73
67
|
|
|
74
68
|
```bash
|
|
75
|
-
|
|
76
|
-
hello world
|
|
77
|
-
hello world
|
|
69
|
+
pip install .
|
|
78
70
|
```
|
|
79
71
|
|
|
72
|
+
## Advanced use
|
|
73
|
+
|
|
80
74
|
### Using subcommands
|
|
81
75
|
|
|
82
76
|
```python
|
magicli-2.1.4/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# magiᴄʟɪ✨
|
|
2
|
+
|
|
3
|
+
Automatically turns a file into a CLI without any boilerplate by introspecting its functions.
|
|
4
|
+
|
|
5
|
+
**`hello world` example**
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
# hello.py
|
|
9
|
+
def hello(name, greeting="hello"):
|
|
10
|
+
print(greeting, name)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
becomes
|
|
14
|
+
|
|
15
|
+
<img src="docs/img/hello.svg"/>
|
|
16
|
+
|
|
17
|
+
with only 3 commands
|
|
18
|
+
|
|
19
|
+
1. `pip install magicli`
|
|
20
|
+
1. `magicli`
|
|
21
|
+
1. `pip install .`
|
|
22
|
+
|
|
23
|
+
## Quick start
|
|
24
|
+
|
|
25
|
+
### Install magicli
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
pip install magicli
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Setup your repository
|
|
32
|
+
|
|
33
|
+
Initialize repo
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git init
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Add version info (optional)
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git tag 1.0.0
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Automatically create CLI
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
magicli
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
_Make sure the name of your CLI, the module name and the name of the function have to same name._
|
|
52
|
+
|
|
53
|
+
### Install your Python package
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install .
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Advanced use
|
|
60
|
+
|
|
61
|
+
### Using subcommands
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
# module.py
|
|
65
|
+
def hello(): ...
|
|
66
|
+
|
|
67
|
+
def world(times=1):
|
|
68
|
+
for _ in range(times):
|
|
69
|
+
print("hello world")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
$ hello world --times 2
|
|
74
|
+
hello world
|
|
75
|
+
hello world
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Help message
|
|
79
|
+
|
|
80
|
+
By default, the docstring of the function will be displayed.
|
|
81
|
+
|
|
82
|
+
If no docstring is specified, an error message will be printed.
|
|
83
|
+
|
|
84
|
+
## Development
|
|
85
|
+
|
|
86
|
+
Run pytest with coverage report:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
python3 -m pytest -s --cov=magicli --cov-report=term-missing
|
|
90
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="540" height="222" font-family="monospace" font-size="18px" fill="#ffffff"><rect width="100%" height="100%" rx="10" fill="#151b23" /><g transform="scale(0.9) translate(20 38)"><text y="0" opacity="0" style="user-select: none;">$ <animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0;0;1;1" dur="11s" repeatCount="indefinite" /></text><text x="21.6" y="0" opacity="0">h<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.0545;0.0545;1;1" dur="11s" repeatCount="indefinite" /></text><text x="32.400000000000006" y="0" opacity="0">e<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.0636;0.0636;1;1" dur="11s" repeatCount="indefinite" /></text><text x="43.2" y="0" opacity="0">l<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.0727;0.0727;1;1" dur="11s" repeatCount="indefinite" /></text><text x="54" y="0" opacity="0">l<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.0818;0.0818;1;1" dur="11s" repeatCount="indefinite" /></text><text x="64.80000000000001" y="0" opacity="0">o<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.0909;0.0909;1;1" dur="11s" repeatCount="indefinite" /></text><text x="75.60000000000001" y="0" opacity="0"> <animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.1;0.1;1;1" dur="11s" repeatCount="indefinite" /></text><text x="86.4" y="0" opacity="0">w<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.1091;0.1091;1;1" dur="11s" repeatCount="indefinite" /></text><text x="97.2" y="0" opacity="0">o<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.1182;0.1182;1;1" dur="11s" repeatCount="indefinite" /></text><text x="108" y="0" opacity="0">r<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.1273;0.1273;1;1" dur="11s" repeatCount="indefinite" /></text><text x="118.80000000000001" y="0" opacity="0">l<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.1364;0.1364;1;1" dur="11s" repeatCount="indefinite" /></text><text x="129.60000000000002" y="0" opacity="0">d<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.1455;0.1455;1;1" dur="11s" repeatCount="indefinite" /></text><text y="23" opacity="0">hello world<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.1545;0.1545;1;1" dur="11s" repeatCount="indefinite" /></text><text y="46" opacity="0" style="user-select: none;">$ <animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.1545;0.1545;1;1" dur="11s" repeatCount="indefinite" /></text><text x="21.6" y="46" opacity="0">h<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.3455;0.3455;1;1" dur="11s" repeatCount="indefinite" /></text><text x="32.400000000000006" y="46" opacity="0">e<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.3545;0.3545;1;1" dur="11s" repeatCount="indefinite" /></text><text x="43.2" y="46" opacity="0">l<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.3636;0.3636;1;1" dur="11s" repeatCount="indefinite" /></text><text x="54" y="46" opacity="0">l<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.3727;0.3727;1;1" dur="11s" repeatCount="indefinite" /></text><text x="64.80000000000001" y="46" opacity="0">o<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.3818;0.3818;1;1" dur="11s" repeatCount="indefinite" /></text><text y="69" opacity="0">name: positional argument missing<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.3909;0.3909;1;1" dur="11s" repeatCount="indefinite" /></text><text y="92" opacity="0"><animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.3909;0.3909;1;1" dur="11s" repeatCount="indefinite" /></text><text y="115" opacity="0">usage:<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.3909;0.3909;1;1" dur="11s" repeatCount="indefinite" /></text><text y="138" opacity="0">  hello name [--greeting]<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.3909;0.3909;1;1" dur="11s" repeatCount="indefinite" /></text><text y="161" opacity="0" style="user-select: none;">$ <animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.3909;0.3909;1;1" dur="11s" repeatCount="indefinite" /></text><text x="21.6" y="161" opacity="0">h<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.5818;0.5818;1;1" dur="11s" repeatCount="indefinite" /></text><text x="32.400000000000006" y="161" opacity="0">e<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.5909;0.5909;1;1" dur="11s" repeatCount="indefinite" /></text><text x="43.2" y="161" opacity="0">l<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.6;0.6;1;1" dur="11s" repeatCount="indefinite" /></text><text x="54" y="161" opacity="0">l<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.6091;0.6091;1;1" dur="11s" repeatCount="indefinite" /></text><text x="64.80000000000001" y="161" opacity="0">o<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.6182;0.6182;1;1" dur="11s" repeatCount="indefinite" /></text><text x="75.60000000000001" y="161" opacity="0"> <animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.6273;0.6273;1;1" dur="11s" repeatCount="indefinite" /></text><text x="86.4" y="161" opacity="0">w<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.6364;0.6364;1;1" dur="11s" repeatCount="indefinite" /></text><text x="97.2" y="161" opacity="0">o<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.6455;0.6455;1;1" dur="11s" repeatCount="indefinite" /></text><text x="108" y="161" opacity="0">r<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.6545;0.6545;1;1" dur="11s" repeatCount="indefinite" /></text><text x="118.80000000000001" y="161" opacity="0">l<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.6636;0.6636;1;1" dur="11s" repeatCount="indefinite" /></text><text x="129.60000000000002" y="161" opacity="0">d<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.6727;0.6727;1;1" dur="11s" repeatCount="indefinite" /></text><text x="140.4" y="161" opacity="0"> <animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.6818;0.6818;1;1" dur="11s" repeatCount="indefinite" /></text><text x="151.20000000000002" y="161" opacity="0">-<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.6909;0.6909;1;1" dur="11s" repeatCount="indefinite" /></text><text x="162" y="161" opacity="0">-<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.7;0.7;1;1" dur="11s" repeatCount="indefinite" /></text><text x="172.8" y="161" opacity="0">g<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.7091;0.7091;1;1" dur="11s" repeatCount="indefinite" /></text><text x="183.60000000000002" y="161" opacity="0">r<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.7182;0.7182;1;1" dur="11s" repeatCount="indefinite" /></text><text x="194.4" y="161" opacity="0">e<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.7273;0.7273;1;1" dur="11s" repeatCount="indefinite" /></text><text x="205.20000000000002" y="161" opacity="0">e<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.7364;0.7364;1;1" dur="11s" repeatCount="indefinite" /></text><text x="216" y="161" opacity="0">t<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.7455;0.7455;1;1" dur="11s" repeatCount="indefinite" /></text><text x="226.8" y="161" opacity="0">i<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.7545;0.7545;1;1" dur="11s" repeatCount="indefinite" /></text><text x="237.60000000000002" y="161" opacity="0">n<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.7636;0.7636;1;1" dur="11s" repeatCount="indefinite" /></text><text x="248.4" y="161" opacity="0">g<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.7727;0.7727;1;1" dur="11s" repeatCount="indefinite" /></text><text x="259.20000000000005" y="161" opacity="0"> <animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.7818;0.7818;1;1" dur="11s" repeatCount="indefinite" /></text><text x="270" y="161" opacity="0">b<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.7909;0.7909;1;1" dur="11s" repeatCount="indefinite" /></text><text x="280.8" y="161" opacity="0">y<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.8;0.8;1;1" dur="11s" repeatCount="indefinite" /></text><text x="291.6" y="161" opacity="0">e<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.8091;0.8091;1;1" dur="11s" repeatCount="indefinite" /></text><text y="184" opacity="0">bye world<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.8182;0.8182;1;1" dur="11s" repeatCount="indefinite" /></text></g></svg>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: magicli
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.4
|
|
4
4
|
Summary: Automatically generates a CLI from functions.
|
|
5
5
|
Author-email: Patrick Elmer <patrick@elmer.ws>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -13,70 +13,64 @@ Dynamic: license-file
|
|
|
13
13
|
|
|
14
14
|
# magiᴄʟɪ✨
|
|
15
15
|
|
|
16
|
-
Automatically
|
|
16
|
+
Automatically turns a file into a CLI without any boilerplate by introspecting its functions.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
**`hello world` example**
|
|
19
19
|
|
|
20
|
-
```
|
|
21
|
-
|
|
20
|
+
```python
|
|
21
|
+
# hello.py
|
|
22
|
+
def hello(name, greeting="hello"):
|
|
23
|
+
print(greeting, name)
|
|
22
24
|
```
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
becomes
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
<img src="docs/img/hello.svg"/>
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
# module.py
|
|
30
|
-
def hello(name, times=1):
|
|
31
|
-
for _ in range(times):
|
|
32
|
-
print("hello", name)
|
|
33
|
-
```
|
|
30
|
+
with only 3 commands
|
|
34
31
|
|
|
35
|
-
|
|
32
|
+
1. `pip install magicli`
|
|
33
|
+
1. `magicli`
|
|
34
|
+
1. `pip install .`
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
magicli
|
|
39
|
-
```
|
|
36
|
+
## Quick start
|
|
40
37
|
|
|
41
|
-
|
|
38
|
+
### Install magicli
|
|
42
39
|
|
|
43
|
-
```
|
|
44
|
-
pip install
|
|
40
|
+
```
|
|
41
|
+
pip install magicli
|
|
45
42
|
```
|
|
46
43
|
|
|
47
|
-
|
|
44
|
+
### Setup your repository
|
|
45
|
+
|
|
46
|
+
Initialize repo
|
|
48
47
|
|
|
49
48
|
```bash
|
|
50
|
-
|
|
51
|
-
hello world
|
|
52
|
-
hello world
|
|
49
|
+
git init
|
|
53
50
|
```
|
|
54
51
|
|
|
55
|
-
|
|
52
|
+
Add version info (optional)
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
```toml
|
|
60
|
-
[project.scripts]
|
|
61
|
-
hello = "magicli:magicli"
|
|
54
|
+
```bash
|
|
55
|
+
git tag 1.0.0
|
|
62
56
|
```
|
|
63
57
|
|
|
64
|
-
|
|
58
|
+
### Automatically create CLI
|
|
65
59
|
|
|
66
60
|
```bash
|
|
67
|
-
|
|
68
|
-
├── hello.py
|
|
69
|
-
└── pyproject.toml
|
|
61
|
+
magicli
|
|
70
62
|
```
|
|
71
63
|
|
|
72
|
-
|
|
64
|
+
_Make sure the name of your CLI, the module name and the name of the function have to same name._
|
|
65
|
+
|
|
66
|
+
### Install your Python package
|
|
73
67
|
|
|
74
68
|
```bash
|
|
75
|
-
|
|
76
|
-
hello world
|
|
77
|
-
hello world
|
|
69
|
+
pip install .
|
|
78
70
|
```
|
|
79
71
|
|
|
72
|
+
## Advanced use
|
|
73
|
+
|
|
80
74
|
### Using subcommands
|
|
81
75
|
|
|
82
76
|
```python
|
|
@@ -15,6 +15,7 @@ from importlib import metadata
|
|
|
15
15
|
from pathlib import Path
|
|
16
16
|
|
|
17
17
|
logging.basicConfig(level=os.getenv("MAGICLI_LOG_LEVEL", "DEBUG"), format="%(message)s")
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
class ParseArgvError(Exception):
|
|
@@ -209,7 +210,7 @@ def check_for_version(argv, parameters, docstring, module):
|
|
|
209
210
|
"-V": "-V, --version",
|
|
210
211
|
}
|
|
211
212
|
if (doc := args.get(argv[0])) and doc in docstring:
|
|
212
|
-
|
|
213
|
+
logger.info(get_version(module))
|
|
213
214
|
raise SystemExit
|
|
214
215
|
|
|
215
216
|
|
|
@@ -387,9 +388,9 @@ def cli(name="", author="", email="", description="", homepage=""):
|
|
|
387
388
|
author = author or get_output("git config --get user.name")
|
|
388
389
|
email = email or get_output("git config --get user.email")
|
|
389
390
|
if not get_output("git tag"):
|
|
390
|
-
|
|
391
|
+
logger.debug("Specify the version with `git tag`")
|
|
391
392
|
else:
|
|
392
|
-
|
|
393
|
+
logger.debug("Not a git repo. Run `git init`")
|
|
393
394
|
|
|
394
395
|
authors = [f'{k}="{v}"' for k, v in {"name": author, "email": email}.items() if v]
|
|
395
396
|
|
|
@@ -411,7 +412,7 @@ def cli(name="", author="", email="", description="", homepage=""):
|
|
|
411
412
|
if license_expression := get_license_expression(license_content):
|
|
412
413
|
project.append(f'license = "{license_expression}"')
|
|
413
414
|
else:
|
|
414
|
-
|
|
415
|
+
logger.debug("Unknown license: %s", license_file.name)
|
|
415
416
|
project.append(f'license-files = ["{license_file.name}"]')
|
|
416
417
|
|
|
417
418
|
if description or (description := get_description(name)):
|
|
@@ -431,4 +432,4 @@ def cli(name="", author="", email="", description="", homepage=""):
|
|
|
431
432
|
)
|
|
432
433
|
|
|
433
434
|
pyproject.write_text(format_blocks(blocks, sep="\n") + "\n", encoding="utf-8")
|
|
434
|
-
|
|
435
|
+
logger.debug("Created pyproject.toml ✨")
|
magicli-2.1.3/README.md
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
# magiᴄʟɪ✨
|
|
2
|
-
|
|
3
|
-
Automatically generates a CLI from functions of a module.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
pip install magicli
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Get started
|
|
12
|
-
|
|
13
|
-
Simple usage example.
|
|
14
|
-
|
|
15
|
-
```python
|
|
16
|
-
# module.py
|
|
17
|
-
def hello(name, times=1):
|
|
18
|
-
for _ in range(times):
|
|
19
|
-
print("hello", name)
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
Then run this in your terminal to initialize the CLI:
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
magicli
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
You are now able to install your package:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
pip install .
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
And then call it:
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
$ hello world --times 2
|
|
38
|
-
hello world
|
|
39
|
-
hello world
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Define name of CLI in `pyproject.toml`
|
|
43
|
-
|
|
44
|
-
The terminal command `magicli` adds the following to your `pyproject.toml`.
|
|
45
|
-
|
|
46
|
-
```toml
|
|
47
|
-
[project.scripts]
|
|
48
|
-
hello = "magicli:magicli"
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Important: Make sure the name of your CLI, the module name and the name of the function to be called are the same!
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
.
|
|
55
|
-
├── hello.py
|
|
56
|
-
└── pyproject.toml
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
You can now `pip install` your code and call it like this:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
$ hello world --times 2
|
|
63
|
-
hello world
|
|
64
|
-
hello world
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### Using subcommands
|
|
68
|
-
|
|
69
|
-
```python
|
|
70
|
-
# module.py
|
|
71
|
-
def hello(): ...
|
|
72
|
-
|
|
73
|
-
def world(times=1):
|
|
74
|
-
for _ in range(times):
|
|
75
|
-
print("hello world")
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
$ hello world --times 2
|
|
80
|
-
hello world
|
|
81
|
-
hello world
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Help message
|
|
85
|
-
|
|
86
|
-
By default, the docstring of the function will be displayed.
|
|
87
|
-
|
|
88
|
-
If no docstring is specified, an error message will be printed.
|
|
89
|
-
|
|
90
|
-
## Development
|
|
91
|
-
|
|
92
|
-
Run pytest with coverage report:
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
python3 -m pytest -s --cov=magicli --cov-report=term-missing
|
|
96
|
-
```
|
|
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
|