dev-shell 0.9.1__tar.gz → 0.10.0__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.
Files changed (52) hide show
  1. {dev_shell-0.9.1 → dev_shell-0.10.0}/.github/workflows/tests.yml +15 -5
  2. {dev_shell-0.9.1 → dev_shell-0.10.0}/.gitignore +3 -1
  3. dev_shell-0.10.0/.run/Template Python tests.run.xml +24 -0
  4. dev_shell-0.10.0/.run/Unittests __all__.run.xml +24 -0
  5. {dev_shell-0.9.1 → dev_shell-0.10.0}/PKG-INFO +35 -62
  6. {dev_shell-0.9.1 → dev_shell-0.10.0}/README.md +25 -55
  7. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/__init__.py +1 -1
  8. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/__main__.py +2 -2
  9. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/base_cmd2_app.py +17 -38
  10. dev_shell-0.10.0/dev_shell/bootstrap-source.py +84 -0
  11. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/command_sets/dev_shell_commands.py +35 -42
  12. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/dev_shell_app.py +1 -1
  13. dev_shell-0.10.0/dev_shell/tests/__init__.py +36 -0
  14. dev_shell-0.10.0/dev_shell/tests/fixtures.py +38 -0
  15. dev_shell-0.10.0/dev_shell/tests/test_bootstrap.py +45 -0
  16. dev_shell-0.10.0/dev_shell/tests/test_dev_shell_app.py +54 -0
  17. dev_shell-0.10.0/dev_shell/tests/test_project_setup.py +40 -0
  18. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/tests/test_source_file.py +2 -20
  19. dev_shell-0.10.0/dev_shell/utils/colorful.py +73 -0
  20. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/utils/subprocess_utils.py +3 -21
  21. dev_shell-0.10.0/devshell.py +84 -0
  22. dev_shell-0.10.0/dist/.gitignore +1 -0
  23. {dev_shell-0.9.1 → dev_shell-0.10.0}/noxfile.py +10 -8
  24. {dev_shell-0.9.1 → dev_shell-0.10.0}/pyproject.toml +39 -42
  25. dev_shell-0.10.0/uv.lock +1578 -0
  26. dev_shell-0.9.1/.flake8 +0 -7
  27. dev_shell-0.9.1/dev_shell/bootstrap-source.py +0 -154
  28. dev_shell-0.9.1/dev_shell/tests/fixtures.py +0 -63
  29. dev_shell-0.9.1/dev_shell/tests/test_bootstrap.py +0 -101
  30. dev_shell-0.9.1/dev_shell/tests/test_dev_shell_app.py +0 -73
  31. dev_shell-0.9.1/dev_shell/tests/test_project_setup.py +0 -18
  32. dev_shell-0.9.1/dev_shell/tests/utils.py +0 -64
  33. dev_shell-0.9.1/dev_shell/utils/assertion.py +0 -25
  34. dev_shell-0.9.1/dev_shell/utils/colorful.py +0 -71
  35. dev_shell-0.9.1/dev_shell.egg-info/PKG-INFO +0 -179
  36. dev_shell-0.9.1/dev_shell.egg-info/SOURCES.txt +0 -38
  37. dev_shell-0.9.1/dev_shell.egg-info/dependency_links.txt +0 -1
  38. dev_shell-0.9.1/dev_shell.egg-info/entry_points.txt +0 -2
  39. dev_shell-0.9.1/dev_shell.egg-info/requires.txt +0 -2
  40. dev_shell-0.9.1/dev_shell.egg-info/top_level.txt +0 -1
  41. dev_shell-0.9.1/devshell.py +0 -154
  42. dev_shell-0.9.1/setup.cfg +0 -4
  43. dev_shell-0.9.1/uv.lock +0 -1601
  44. {dev_shell-0.9.1 → dev_shell-0.10.0}/.editorconfig +0 -0
  45. /dev_shell-0.9.1/dev_shell/tests/__init__.py → /dev_shell-0.10.0/.idea/.gitignore +0 -0
  46. {dev_shell-0.9.1 → dev_shell-0.10.0}/LICENSE +0 -0
  47. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/command_sets/__init__.py +0 -0
  48. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/config.py +0 -0
  49. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/constants.py +0 -0
  50. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/tests/constants.py +0 -0
  51. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/tests/test_doctests.py +0 -0
  52. {dev_shell-0.9.1 → dev_shell-0.10.0}/dev_shell/utils/__init__.py +0 -0
@@ -1,5 +1,6 @@
1
-
2
1
  name: tests
2
+ permissions:
3
+ contents: read
3
4
 
4
5
  on:
5
6
  push:
@@ -11,11 +12,12 @@ on:
11
12
 
12
13
  jobs:
13
14
  test:
14
- runs-on: ubuntu-latest
15
15
  strategy:
16
16
  fail-fast: false
17
17
  matrix:
18
- python-version: ["3.13", "3.12", "3.11"]
18
+ python-version: ["3.14", "3.13", "3.12"]
19
+ os: [ubuntu-latest, macos-latest] # TODO: windows-latest
20
+ runs-on: ${{ matrix.os }}
19
21
  steps:
20
22
  - name: Checkout
21
23
  run: |
@@ -25,13 +27,19 @@ jobs:
25
27
  git checkout $GITHUB_SHA || (git fetch && git checkout $GITHUB_SHA)
26
28
 
27
29
  - name: 'Set up Python ${{ matrix.python-version }}'
28
- uses: actions/setup-python@v5
30
+ uses: actions/setup-python@main
29
31
  # https://github.com/marketplace/actions/setup-python
30
32
  with:
31
33
  python-version: '${{ matrix.python-version }}'
32
34
  cache: 'pip' # caching pip dependencies
33
35
  cache-dependency-path: '**/requirements.*.txt'
34
36
 
37
+ - name: Install uv and set the Python version
38
+ # https://docs.astral.sh/uv/guides/integration/github/#multiple-python-versions
39
+ uses: astral-sh/setup-uv@main
40
+ with:
41
+ python-version: ${{ matrix.python-version }}
42
+
35
43
  - name: 'Bootstrap app venv'
36
44
  # The first CLI call will create the .venv
37
45
  run: |
@@ -49,9 +57,11 @@ jobs:
49
57
  ./devshell.py coverage
50
58
 
51
59
  - name: 'Upload coverage report'
52
- uses: codecov/codecov-action@v4
60
+ uses: codecov/codecov-action@main
53
61
  # https://github.com/marketplace/actions/codecov
54
62
  with:
63
+ # https://docs.codecov.com/docs/codecov-tokens#example-github-actions--official-codecov-action
64
+ token: ${{ secrets.CODECOV_TOKEN }}
55
65
  fail_ci_if_error: false
56
66
  verbose: true
57
67
 
@@ -7,7 +7,9 @@ __pycache__
7
7
  *.orig
8
8
 
9
9
  !.github
10
+ !.run
10
11
  !.editorconfig
11
- !.flake8
12
12
  !.gitignore
13
+ !.pre-commit-config.yaml
14
+ !.pre-commit-hooks.yaml
13
15
  !.gitkeep
@@ -0,0 +1,24 @@
1
+ <component name="ProjectRunConfigurationManager">
2
+ <configuration default="true" type="tests" factoryName="Unittests">
3
+ <module name="dev-shell" />
4
+ <option name="ENV_FILES" value="" />
5
+ <option name="INTERPRETER_OPTIONS" value="" />
6
+ <option name="PARENT_ENVS" value="true" />
7
+ <envs>
8
+ <env name="PYTHONUNBUFFERED" value="1" />
9
+ </envs>
10
+ <option name="SDK_HOME" value="$PROJECT_DIR$/.venv/bin/python" />
11
+ <option name="SDK_NAME" value="Python 3.10 (dev-shell)" />
12
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
13
+ <option name="IS_MODULE_SDK" value="false" />
14
+ <option name="ADD_CONTENT_ROOTS" value="false" />
15
+ <option name="ADD_SOURCE_ROOTS" value="false" />
16
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
17
+ <option name="RUN_TOOL" value="" />
18
+ <option name="_new_pattern" value="&quot;&quot;" />
19
+ <option name="_new_additionalArguments" value="&quot;&quot;" />
20
+ <option name="_new_target" value="&quot;&quot;" />
21
+ <option name="_new_targetType" value="&quot;PATH&quot;" />
22
+ <method v="2" />
23
+ </configuration>
24
+ </component>
@@ -0,0 +1,24 @@
1
+ <component name="ProjectRunConfigurationManager">
2
+ <configuration default="false" name="Unittests **all**" type="tests" factoryName="Unittests">
3
+ <module name="dev-shell" />
4
+ <option name="ENV_FILES" value="" />
5
+ <option name="INTERPRETER_OPTIONS" value="" />
6
+ <option name="PARENT_ENVS" value="true" />
7
+ <envs>
8
+ <env name="PYTHONUNBUFFERED" value="1" />
9
+ </envs>
10
+ <option name="SDK_HOME" value="$PROJECT_DIR$/.venv/bin/python" />
11
+ <option name="SDK_NAME" value="Python 3.10 (dev-shell)" />
12
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
13
+ <option name="IS_MODULE_SDK" value="false" />
14
+ <option name="ADD_CONTENT_ROOTS" value="false" />
15
+ <option name="ADD_SOURCE_ROOTS" value="false" />
16
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
17
+ <option name="RUN_TOOL" value="" />
18
+ <option name="_new_pattern" value="&quot;&quot;" />
19
+ <option name="_new_additionalArguments" value="&quot;&quot;" />
20
+ <option name="_new_target" value="&quot;&quot;" />
21
+ <option name="_new_targetType" value="&quot;CUSTOM&quot;" />
22
+ <method v="2" />
23
+ </configuration>
24
+ </component>
@@ -1,16 +1,19 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: dev-shell
3
- Version: 0.9.1
3
+ Version: 0.10.0
4
4
  Summary: Developer shell for easy startup...
5
- Author-email: Jens Diemer <dev-shell@jensdiemer.de>
6
- License: GPL-3.0-or-later
7
5
  Project-URL: Documentation, https://github.com/jedie/dev-shell
8
6
  Project-URL: Source, https://github.com/jedie/dev-shell
9
- Requires-Python: >=3.11
10
- Description-Content-Type: text/markdown
7
+ Author-email: Jens Diemer <dev-shell@jensdiemer.de>
8
+ License: GPL-3.0-or-later
11
9
  License-File: LICENSE
12
- Requires-Dist: cmd2
10
+ Requires-Python: >=3.12
13
11
  Requires-Dist: cli-base-utilities
12
+ Requires-Dist: cmd2
13
+ Requires-Dist: gnureadline; sys_platform != 'win32'
14
+ Requires-Dist: pyreadline3; sys_platform == 'win32'
15
+ Requires-Dist: rich
16
+ Description-Content-Type: text/markdown
14
17
 
15
18
  # A "dev-shell" for Python projects ;)
16
19
 
@@ -33,95 +36,65 @@ Run Tests? Just start the script and call the "run test command".
33
36
 
34
37
  The "dev-shell" is the base to create a CLI and a shell. It also shows how to make a project bootstrap as simply as possible, e.g.:
35
38
 
39
+
40
+ At least `uv` is needed. Install e.g.: via pipx:
36
41
  ```bash
37
- ~$ git clone https://github.com/jedie/dev-shell.git
38
- ~$ cd dev-shell
39
- ~/dev-shell$ ./devshell.py test
42
+ apt-get install pipx
43
+ pipx install uv
40
44
  ```
41
45
 
46
+ Clone the project and just start the CLI help commands.
47
+ A virtual environment will be created/updated automatically.
42
48
 
43
- ## How it works
44
-
45
- First start of the Python script [./devshell.py](https://github.com/jedie/dev-shell/blob/main/devshell.py) will bootstrap:
49
+ ```bash
50
+ ~$ git clone https://github.com/jedie/dev-shell.git
51
+ ~$ cd dev-shell
52
+ ~/dev-shell$ devshell.py --help
53
+ ~/dev-shell$ devshell.py test
54
+ ```
46
55
 
47
- * Generate a Python virtual environment (in short: `venv`)
48
- * Install poetry
49
- * Install project dependencies and the project himself
50
56
 
51
57
  The output on first bootstrap start looks like:
52
58
 
53
59
  ```bash
54
60
  ~/dev-shell$ ./devshell.py
55
- Create venv here: ~/dev-shell/.venv
56
- Collecting pip
57
- ...
58
- Successfully installed pip-21.0.1
59
- Collecting poetry
60
- ...
61
- Installing dependencies from lock file
62
-
63
- Package operations: 31 installs, 1 update, 0 removals
64
-
65
- ...
66
-
67
- Installing the current project: dev-shell (0.0.1alpha0)
68
61
 
62
+ Developer shell - dev_shell - v0.10.0
69
63
 
70
- + .venv/bin/python .venv/bin/devshell
71
-
72
-
73
- Developer shell - dev_shell - v0.2.0
74
-
75
-
76
- Documented commands (use 'help -v' for verbose/'help <topic>' for details):
77
64
 
78
65
  dev-shell commands
79
- ==================
80
- fix_code_style linting list_venv_packages publish test update
66
+ ──────────────────
67
+ check_code_style fix_code_style list_venv_packages pyupgrade update
68
+ coverage install publish test version
81
69
 
82
- ...
70
+ Uncategorized Commands
71
+ ──────────────────────
72
+ alias help history macro quit set shortcuts
83
73
 
84
74
  (dev_shell) quit
85
75
  ~/dev-shell$
86
76
  ```
87
77
 
88
- The first bootstrap start takes a few seconds. Each later startup detects the existing virtualenv and is very fast:
89
-
90
- ```bash
91
- ~/dev-shell$ ./devshell.py
92
-
93
- Developer shell - dev_shell - v0.2.0
94
-
95
- (dev_shell) help
96
- ```
97
-
98
- Info: The `.venv` will be automatically updated via `poetry install` call if the `uv.lock` file has been changed.
99
-
100
- A call with `--update` will force to call some create/update steps, e.g.:
101
-
102
- ```bash
103
- ~/dev-shell$ ./devshell.py --update
104
- ```
105
-
106
- You can also just delete `/.venv/` and start `devshell.py` again ;)
107
-
108
- (Using `--update` is not to be confused with the call of "update" command.)
109
-
110
78
 
111
79
  ## compatibility
112
80
 
113
81
  | dev-shell version | OS | Python version |
114
82
  |-------------------|-------------------------|---------------------|
83
+ | >=v0.10.0 | Linux + MacOS + Windows | 3.14, 3.13, 3.12 |
115
84
  | >=v0.7.0 | Linux + MacOS + Windows | 3.11, 3.10, 3.9 |
116
85
  | >=v0.5.0 | Linux + MacOS + Windows | 3.10, 3.9, 3.8, 3.7 |
117
86
  | >=v0.0.1 | Linux + MacOS + Windows | 3.9, 3.8, 3.7 |
118
87
 
119
- See also github test configuration: [.github/workflows/test.yml](https://github.com/jedie/dev-shell/blob/main/.github/workflows/test.yml)
88
+ See also:
89
+ * github test configuration: [.github/workflows/test.yml](https://github.com/jedie/dev-shell/blob/main/.github/workflows/test.yml)
90
+ * Nox configuration: [noxfile.py](https://github.com/jedie/dev-shell/blob/main/noxfile.py)
120
91
 
121
92
  ## History
122
93
 
123
94
  * [*dev*](https://github.com/jedie/dev-shell/compare/v0.8.0...main)
124
95
  * TBC
96
+ * [0.10.0 - 2026-02-10](https://github.com/jedie/dev-shell/compare/v0.9.1...v0.10.0)
97
+ * Modernize codebase
125
98
  * [0.9.1 - 2025-03-11](https://github.com/jedie/dev-shell/compare/v0.9.0...v0.9.1)
126
99
  * Fix usage as package in external projects
127
100
  * [0.9.0 - 2025-03-11](https://github.com/jedie/dev-shell/compare/v0.8.0...v0.9.0)
@@ -19,95 +19,65 @@ Run Tests? Just start the script and call the "run test command".
19
19
 
20
20
  The "dev-shell" is the base to create a CLI and a shell. It also shows how to make a project bootstrap as simply as possible, e.g.:
21
21
 
22
+
23
+ At least `uv` is needed. Install e.g.: via pipx:
22
24
  ```bash
23
- ~$ git clone https://github.com/jedie/dev-shell.git
24
- ~$ cd dev-shell
25
- ~/dev-shell$ ./devshell.py test
25
+ apt-get install pipx
26
+ pipx install uv
26
27
  ```
27
28
 
29
+ Clone the project and just start the CLI help commands.
30
+ A virtual environment will be created/updated automatically.
28
31
 
29
- ## How it works
30
-
31
- First start of the Python script [./devshell.py](https://github.com/jedie/dev-shell/blob/main/devshell.py) will bootstrap:
32
+ ```bash
33
+ ~$ git clone https://github.com/jedie/dev-shell.git
34
+ ~$ cd dev-shell
35
+ ~/dev-shell$ devshell.py --help
36
+ ~/dev-shell$ devshell.py test
37
+ ```
32
38
 
33
- * Generate a Python virtual environment (in short: `venv`)
34
- * Install poetry
35
- * Install project dependencies and the project himself
36
39
 
37
40
  The output on first bootstrap start looks like:
38
41
 
39
42
  ```bash
40
43
  ~/dev-shell$ ./devshell.py
41
- Create venv here: ~/dev-shell/.venv
42
- Collecting pip
43
- ...
44
- Successfully installed pip-21.0.1
45
- Collecting poetry
46
- ...
47
- Installing dependencies from lock file
48
-
49
- Package operations: 31 installs, 1 update, 0 removals
50
-
51
- ...
52
-
53
- Installing the current project: dev-shell (0.0.1alpha0)
54
-
55
-
56
- + .venv/bin/python .venv/bin/devshell
57
-
58
-
59
- Developer shell - dev_shell - v0.2.0
60
44
 
45
+ Developer shell - dev_shell - v0.10.0
61
46
 
62
- Documented commands (use 'help -v' for verbose/'help <topic>' for details):
63
47
 
64
48
  dev-shell commands
65
- ==================
66
- fix_code_style linting list_venv_packages publish test update
49
+ ──────────────────
50
+ check_code_style fix_code_style list_venv_packages pyupgrade update
51
+ coverage install publish test version
67
52
 
68
- ...
53
+ Uncategorized Commands
54
+ ──────────────────────
55
+ alias help history macro quit set shortcuts
69
56
 
70
57
  (dev_shell) quit
71
58
  ~/dev-shell$
72
59
  ```
73
60
 
74
- The first bootstrap start takes a few seconds. Each later startup detects the existing virtualenv and is very fast:
75
-
76
- ```bash
77
- ~/dev-shell$ ./devshell.py
78
-
79
- Developer shell - dev_shell - v0.2.0
80
-
81
- (dev_shell) help
82
- ```
83
-
84
- Info: The `.venv` will be automatically updated via `poetry install` call if the `uv.lock` file has been changed.
85
-
86
- A call with `--update` will force to call some create/update steps, e.g.:
87
-
88
- ```bash
89
- ~/dev-shell$ ./devshell.py --update
90
- ```
91
-
92
- You can also just delete `/.venv/` and start `devshell.py` again ;)
93
-
94
- (Using `--update` is not to be confused with the call of "update" command.)
95
-
96
61
 
97
62
  ## compatibility
98
63
 
99
64
  | dev-shell version | OS | Python version |
100
65
  |-------------------|-------------------------|---------------------|
66
+ | >=v0.10.0 | Linux + MacOS + Windows | 3.14, 3.13, 3.12 |
101
67
  | >=v0.7.0 | Linux + MacOS + Windows | 3.11, 3.10, 3.9 |
102
68
  | >=v0.5.0 | Linux + MacOS + Windows | 3.10, 3.9, 3.8, 3.7 |
103
69
  | >=v0.0.1 | Linux + MacOS + Windows | 3.9, 3.8, 3.7 |
104
70
 
105
- See also github test configuration: [.github/workflows/test.yml](https://github.com/jedie/dev-shell/blob/main/.github/workflows/test.yml)
71
+ See also:
72
+ * github test configuration: [.github/workflows/test.yml](https://github.com/jedie/dev-shell/blob/main/.github/workflows/test.yml)
73
+ * Nox configuration: [noxfile.py](https://github.com/jedie/dev-shell/blob/main/noxfile.py)
106
74
 
107
75
  ## History
108
76
 
109
77
  * [*dev*](https://github.com/jedie/dev-shell/compare/v0.8.0...main)
110
78
  * TBC
79
+ * [0.10.0 - 2026-02-10](https://github.com/jedie/dev-shell/compare/v0.9.1...v0.10.0)
80
+ * Modernize codebase
111
81
  * [0.9.1 - 2025-03-11](https://github.com/jedie/dev-shell/compare/v0.9.0...v0.9.1)
112
82
  * Fix usage as package in external projects
113
83
  * [0.9.0 - 2025-03-11](https://github.com/jedie/dev-shell/compare/v0.8.0...v0.9.0)
@@ -4,5 +4,5 @@ Developer shell for easy startup...
4
4
  """
5
5
 
6
6
  # See https://packaging.python.org/en/latest/specifications/version-specifiers/
7
- __version__ = '0.9.1'
7
+ __version__ = '0.10.0'
8
8
  __author__ = 'Jens Diemer <dev-shell@jensdiemer.de>'
@@ -3,8 +3,8 @@ Allow dev_shell to be executable
3
3
  through `python -m dev_shell`.
4
4
  """
5
5
 
6
- from dev_shell.dev_shell_app import devshell_cmdloop
6
+ from dev_shell.dev_shell_app import main
7
7
 
8
8
 
9
9
  if __name__ == '__main__':
10
- devshell_cmdloop()
10
+ main()
@@ -1,12 +1,12 @@
1
1
  import os
2
+ import shlex
2
3
  import sys
3
4
  from pathlib import Path
4
5
 
5
- import cmd2 as cmd2
6
+ import cmd2
6
7
 
7
8
  from dev_shell.config import DevShellConfig
8
9
  from dev_shell.utils.colorful import bright_blue, bright_yellow
9
- from dev_shell.utils.subprocess_utils import argv2str
10
10
 
11
11
 
12
12
  class DevShellBaseApp(cmd2.Cmd):
@@ -14,55 +14,34 @@ class DevShellBaseApp(cmd2.Cmd):
14
14
  Base cmd2 App with some gimmicks ;)
15
15
  """
16
16
 
17
+ # Remove some default cmd2 commands:
18
+ delattr(cmd2.Cmd, 'do_edit')
19
+ delattr(cmd2.Cmd, 'do_shell')
20
+ delattr(cmd2.Cmd, 'do_run_script')
21
+ delattr(cmd2.Cmd, 'do_run_pyscript')
22
+
17
23
  def __init__(self, *args, config: DevShellConfig, **kwargs):
18
- kwargs.update(dict(
19
- persistent_history_file='.history',
20
- allow_cli_args=False
21
- ))
24
+ kwargs.update(dict(persistent_history_file='.history', allow_cli_args=False))
22
25
  super().__init__(*args, **kwargs)
23
26
 
24
27
  self.config = config
25
28
 
26
- self.intro = (
27
- f'\n\nDeveloper shell - {bright_yellow(config.package_path.name)} - v{config.version}\n'
28
- )
29
+ self.intro = f'\n\nDeveloper shell - {bright_yellow(config.package_path.name)} - v{config.version}\n'
29
30
  self.prompt = f'\n({bright_blue(config.package_path.name)}) '
30
31
 
31
- # work-a-round: https://github.com/python-cmd2/cmd2/issues/1072
32
- args = sys.argv[1:]
33
- if args:
34
- # CLI usage => execute command and exit
35
- self.intro = None
36
- command = argv2str(args)
37
- self._startup_commands = [command]
38
- else:
39
- self._startup_commands = ['help']
40
-
41
32
  # Set aliases:
42
- self.aliases.update({
43
- 'q': 'quit',
44
- })
33
+ self.aliases.update(
34
+ {
35
+ 'q': 'quit',
36
+ '--help': 'help', # Support --help as alias for help
37
+ }
38
+ )
45
39
 
46
40
  # Display Tracebacks on errors:
47
41
  self.debug = True
48
42
 
49
43
  self.update_path()
50
44
 
51
- def onecmd(self, *args, **kwargs):
52
- """
53
- 1. Exit cmdloop if shell was used as CLI ;)
54
- 2. Pass sys.exit() code
55
- """
56
- try:
57
- stop = super().onecmd(*args, **kwargs)
58
- except SystemExit as exit_code:
59
- # Pass the sys.exit() code
60
- # See also: https://github.com/python-cmd2/cmd2/pull/1076
61
- self.exit_code = exit_code
62
- stop = True
63
-
64
- return stop
65
-
66
45
  def update_path(self):
67
46
  """
68
47
  Add our .venv/bin/ directory into PATH at first position.
@@ -80,7 +59,7 @@ def run_cmd2_app(app: cmd2.Cmd) -> None:
80
59
  """
81
60
  if len(sys.argv) > 1:
82
61
  # CLI usage => run only one command and then exit
83
- app.onecmd_plus_hooks(line=argv2str(sys.argv[1:]))
62
+ app.onecmd_plus_hooks(line=shlex.join(sys.argv[1:]))
84
63
  exit_code = app.exit_code
85
64
  else:
86
65
  exit_code = app.cmdloop()
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """
4
+ developer shell
5
+ ~~~~~~~~~~~~~~~
6
+
7
+ Just call this file, and the magic happens ;)
8
+
9
+ The `uv` tool is required to run the development CLI.
10
+
11
+ e.g.: Install `uv` via `pipx`
12
+ apt install pipx
13
+ pipx install uv
14
+
15
+ This file is from: https://pypi.org/project/dev-shell/
16
+ Source: https://github.com/jedie/dev-shell/blob/main/devshell.py
17
+
18
+ :copyleft: 2021-2024 by Jens Diemer
19
+ :license: GNU GPL v3 or above
20
+ """
21
+
22
+ import os
23
+ import shlex
24
+ import shutil
25
+ import signal
26
+ import subprocess
27
+ import sys
28
+ from pathlib import Path
29
+
30
+
31
+ assert sys.version_info >= (3, 12), f'Python version {sys.version_info} is too old!'
32
+
33
+
34
+ BASE_PATH = Path(__file__).parent.resolve()
35
+
36
+ # Create and use "<project-directory>/.venv/" for virtualenv:
37
+ VIRTUAL_ENV = str(BASE_PATH / '.venv')
38
+
39
+
40
+ def print_uv_error_and_exit():
41
+ print('\nError: "uv" command not found in PATH. Please install "uv" first!\n')
42
+ print('Hint:')
43
+ print('\tapt-get install pipx\n')
44
+ print('\tpipx install uv\n')
45
+ sys.exit(1)
46
+
47
+
48
+ def verbose_check_call(*popen_args):
49
+ print(f'\n+ {shlex.join(str(arg) for arg in popen_args)}\n')
50
+ env = {
51
+ 'VIRTUAL_ENV': VIRTUAL_ENV,
52
+ 'UV_VENV': VIRTUAL_ENV,
53
+ **os.environ,
54
+ }
55
+ return subprocess.check_call(
56
+ popen_args,
57
+ env=env,
58
+ cwd=BASE_PATH, # Needed if called from other working directory
59
+ )
60
+
61
+
62
+ def noop_signal_handler(signal_num, frame):
63
+ """
64
+ Signal handler that does nothing: Used to ignore "Ctrl-C" signals
65
+ """
66
+
67
+
68
+ def main(argv):
69
+ uv_bin = shutil.which('uv') # Ensure 'uv' is available in PATH
70
+ if not uv_bin:
71
+ print_uv_error_and_exit()
72
+
73
+ # The cmd2 shell should not abort on Ctrl-C => ignore "Interrupt from keyboard" signal:
74
+ signal.signal(signal.SIGINT, noop_signal_handler)
75
+
76
+ # Call our entry point CLI:
77
+ try:
78
+ verbose_check_call(uv_bin, 'run', '-m', 'dev_shell', *argv[1:])
79
+ except subprocess.CalledProcessError as err:
80
+ sys.exit(err.returncode)
81
+
82
+
83
+ if __name__ == '__main__':
84
+ main(sys.argv)