Skip to content

Commit 7e1cd13

Browse files
committed
Add tasks to be run with ‘invoke’
1 parent a93cf42 commit 7e1cd13

File tree

3 files changed

+335
-34
lines changed

3 files changed

+335
-34
lines changed

README.md

+117-34
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
- [Using this template](#using-this-template)
66
- [Naming](#naming)
77
- [Adding functionality](#adding-functionality)
8-
- [Testing](#testing)
98
- [Examples](#examples)
9+
- [Development Tasks](#development-tasks)
1010
- [Packaging and Distribution](#packaging-and-distribution)
1111
- [License](#license)
1212

@@ -68,7 +68,7 @@ class Example(cmd2_myplugin.MyPlugin, cmd2.Cmd):
6868
Note how the plugin must be inherited (or mixed in) before `cmd2.Cmd`. This is
6969
required for two reasons:
7070

71-
- As of python 3.6.5, the `cmd.Cmd.__init__()` method in the python standard library does not call
71+
- The `cmd.Cmd.__init__()` method in the python standard library does not call
7272
`super().__init__()`. Because of this oversight, if you don't inherit from `MyPlugin` first, the
7373
`MyPlugin.__init__()` method will never be called.
7474
- You may want your plugin to be able to override methods from `cmd2.Cmd`.
@@ -171,11 +171,41 @@ developers of cmd2 based applications. Describe these classes and functions in
171171
your documentation so users of your plugin will know what's available.
172172

173173

174-
## Testing
174+
## Examples
175+
176+
Include an example or two in the `examples` directory which demonstrate how your
177+
plugin works. This will help developers utilize it from within their
178+
application.
179+
180+
181+
## Development Tasks
175182

176-
Make sure you test on all versions of python supported by cmd2, and on
177-
all supported platforms. cmd2 uses a three tiered testing strategy to
178-
accomplish this objective.
183+
This project uses many other python modules for various development tasks,
184+
including testing, linting, building wheels, and distributing releases. These
185+
modules can be configured many different ways, which can make it difficult to
186+
learn the specific incantations required for each project you are familiar with.
187+
188+
This project uses [invoke](<http://www.pyinvoke.org>) to provide a clean,
189+
high level interface for these development tasks. To see the full list of
190+
functions available:
191+
```
192+
$ invoke -l
193+
```
194+
195+
You can run multiple tasks in a single invocation, for example:
196+
```
197+
$ invoke clean docs sdist wheel
198+
```
199+
200+
That one command will remove all superflous cache, testing, and build
201+
files, render the documentation, and build a source distribution and a
202+
wheel distribution.
203+
204+
For more information, read `tasks.py`.
205+
206+
While developing your plugin, you should make sure you support all versions of
207+
python supported by cmd2, and all supported platforms. cmd2 uses a three
208+
tiered testing strategy to accomplish this objective.
179209

180210
- [pytest](https://pytest.org) runs the unit tests
181211
- [tox](https://tox.readthedocs.io/) runs the unit tests on multiple versions
@@ -186,47 +216,100 @@ accomplish this objective.
186216
This plugin template is set up to use the same strategy.
187217

188218

189-
### Running unit tests
219+
### Create python environments
190220

191-
Run `pytest` from the top level directory of your plugin to run all the
192-
unit tests.
221+
This project uses [tox](https://tox.readthedocs.io/en/latest/) to run the test
222+
suite against multiple python versions. I recommend
223+
[pyenv](https://github.com/pyenv/pyenv) with the
224+
[pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv>) plugin to manage
225+
these various versions. If you are a Windows user, `pyenv` won't work for you,
226+
but [conda](https://conda.io/) can also be used to solve this problem.
193227

228+
This distribution includes a shell script `build-pyenvs.sh` which
229+
automates the creation of these environments.
194230

195-
### Use tox to run unit tests in multiple versions of python
231+
If you prefer to create these virtualenvs by hand, do the following:
232+
```
233+
$ cd cmd2_abbrev
234+
$ pyenv install 3.7.0
235+
$ pyenv virtualenv -p python3.7 3.7.0 cmd2-3.7
236+
$ pyenv install 3.6.5
237+
$ pyenv virtualenv -p python3.6 3.6.5 cmd2-3.6
238+
$ pyenv install 3.5.5
239+
$ pyenv virtualenv -p python3.5 3.5.5 cmd2-3.5
240+
$ pyenv install 3.4.8
241+
$ pyenv virtualenv -p python3.4 3.4.8 cmd2-3.4
242+
```
196243

197-
The included `tox.ini` is setup to run the unit tests in python 3.4, 3.5, 3.6,
198-
and 3.7. In order for `tox` to work, you need to have different versions of
199-
python executables available in your path.
200-
[pyenv](https://github.com/pyenv/pyenv) is one method of doing this easily. Once
201-
`pyenv` is installed, use it to install multiple versions of python:
244+
Now set pyenv to make all three of those available at the same time:
245+
```
246+
$ pyenv local cmd2-3.7 cmd2-3.6 cmd2-3.5 cmd2-3.4
247+
```
202248

249+
Whether you ran the script, or did it by hand, you now have isolated virtualenvs
250+
for each of the major python versions. This table shows various python commands,
251+
the version of python which will be executed, and the virtualenv it will
252+
utilize.
253+
254+
| Command | python | virtualenv |
255+
| ----------- | ------ | ---------- |
256+
| `python` | 3.7.0 | cmd2-3.6 |
257+
| `python3` | 3.7.0 | cmd2-3.6 |
258+
| `python3.7` | 3.7.0 | cmd2-3.7 |
259+
| `python3.6` | 3.6.5 | cmd2-3.6 |
260+
| `python3.5` | 3.5.5 | cmd2-3.5 |
261+
| `python3.4` | 3.4.8 | cmd2-3.4 |
262+
| `pip` | 3.7.0 | cmd2-3.6 |
263+
| `pip3` | 3.7.0 | cmd2-3.6 |
264+
| `pip3.7` | 3.7.0 | cmd2-3.7 |
265+
| `pip3.6` | 3.6.5 | cmd2-3.6 |
266+
| `pip3.5` | 3.5.5 | cmd2-3.5 |
267+
| `pip3.4` | 3.4.8 | cmd2-3.4 |
268+
269+
## Install Dependencies
270+
271+
Install all the development dependencies:
203272
```
204-
$ pyenv install 3.4.8
205-
$ pyenv install 3.5.5
206-
$ pyenv install 3.6.5
207-
$ pyenv install 3.7.0
208-
$ pyenv local 3.7.0 3.6.5 3.5.5 3.4.8
273+
$ pip install -e .[dev]
209274
```
210275

211-
This will create a `.python-version` file and instruct the `pyenv` shims to make
212-
`python3.7`, `python3.6`, `python3.5`, and `python3.4` launch the appropriate
213-
versions of python.
276+
This command also installs `cmd2-myplugin` "in-place", so the package points to
277+
the source code instead of copying files to the python `site-packages` folder.
214278

215-
Once these executables are configured, invoking `tox` will create a virtual
216-
environment for each version of python, install the prerequisite packages, and
217-
run your unit tests.
279+
All the dependencies now have been installed in the `cmd2-3.7`
280+
virtualenv. If you want to work in other virtualenvs, you'll need to manually
281+
select it, and install again::
218282

283+
$ pyenv shell cmd2-3.4
284+
$ pip install -e .[dev]
219285

220-
### Run unit tests on multiple platforms
286+
Now that you have your python environments created, you need to install the
287+
package in place, along with all the other development dependencies:
288+
```
289+
$ pip install -e .[dev]
290+
```
221291

222-
AppVeyor and TravisCI offer free plans for open source projects.
223292

293+
### Running unit tests
224294

225-
## Examples
295+
Run `invoke pytest` from the top level directory of your plugin to run all the
296+
unit tests found in the `tests` directory.
226297

227-
Include an example or two in the `examples` directory which demonstrate how your
228-
plugin works. This will help developers utilize it from within their
229-
application.
298+
299+
### Use tox to run unit tests in multiple versions of python
300+
301+
The included `tox.ini` is setup to run the unit tests in python 3.4, 3.5, 3.6,
302+
and 3.7. You can run your unit tests in all of these versions of python by:
303+
```
304+
$ invoke tox
305+
```
306+
307+
308+
### Run unit tests on multiple platforms
309+
310+
[AppVeyor](https://github.com/marketplace/appveyor) and
311+
[TravisCI](https://docs.travis-ci.com/user/getting-started/) offer free plans
312+
for open source projects.
230313

231314

232315
## Packaging and Distribution
@@ -235,8 +318,8 @@ When creating your `setup.py` file, keep the following in mind:
235318

236319
- use the keywords `cmd2 plugin` to make it easier for people to find your plugin
237320
- since cmd2 uses semantic versioning, you should use something like
238-
`install_requires=['cmd2 >= 0.9.3, <=2']` to make sure that your plugin
239-
doesn't try and run with a future version of cmd2 with which it may not be
321+
`install_requires=['cmd2 >= 0.9.4, <=2']` to make sure that your plugin
322+
doesn't try and run with a future version of `cmd2` with which it may not be
240323
compatible
241324

242325

build-pyenvs.sh

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env bash
2+
#
3+
4+
# create pyenv environments for each minor version of python
5+
# supported by this project
6+
#
7+
# this script uses terms from Semantic Versioning https://semver.org/
8+
# version numbers are: major.minor.patch
9+
#
10+
# this script will delete and recreate existing virtualenvs named
11+
# cmd2-3.7, etc. It will also create a .python-version
12+
#
13+
# Prerequisites:
14+
# - *nix-ish environment like macOS or Linux
15+
# - pyenv installed
16+
# - pyenv-virtualenv installed
17+
# - readline and openssl libraries installed so pyenv can
18+
# build pythons
19+
#
20+
21+
# Make a array of the python minor versions we want to install.
22+
# Order matters in this list, because it's the order that the
23+
# virtualenvs will be added to '.python-version'. Feel free to modify
24+
# this list, but note that this script intentionally won't install
25+
# dev, rc, or beta python releases
26+
declare -a pythons=("3.7" "3.6" "3.5" "3.4")
27+
28+
# function to find the latest patch of a minor version of python
29+
function find_latest_version {
30+
pyenv install -l | \
31+
sed -En -e "s/^ *//g" -e "/(dev|b|rc)/d" -e "/^$1/p" | \
32+
tail -1
33+
}
34+
35+
# empty out '.python-version'
36+
> .python-version
37+
38+
# loop through the pythons
39+
for minor_version in "${pythons[@]}"
40+
do
41+
patch_version=$( find_latest_version "$minor_version" )
42+
# use pyenv to install the latest versions of python
43+
# if it's already installed don't install it again
44+
pyenv install -s "$patch_version"
45+
46+
envname="cmd2-$minor_version"
47+
# remove the associated virtualenv
48+
pyenv uninstall -f "$envname"
49+
# create a new virtualenv
50+
pyenv virtualenv -p "python$minor_version" "$patch_version" "$envname"
51+
# append the virtualenv to .python-version
52+
echo "$envname" >> .python-version
53+
done

0 commit comments

Comments
 (0)