mirror of https://github.com/tqdm/tqdm.git
bump version number, Merge pull request #44 from tqdm/lrq3000-makefile
This commit is contained in:
commit
8a11ecf554
|
@ -1,6 +1,10 @@
|
|||
sudo: false
|
||||
language: python
|
||||
python: 3.4
|
||||
branches: # remove travis double-check on pull requests in main repo
|
||||
only:
|
||||
- master
|
||||
- /^\d\.\d+$/
|
||||
env:
|
||||
- TOXENV=py26
|
||||
- TOXENV=py27
|
||||
|
|
63
CONTRIBUTE
63
CONTRIBUTE
|
@ -4,19 +4,25 @@ HOW TO CONTRIBUTE TO TQDM
|
|||
This file describes how to contribute changes to the project, and how to
|
||||
upload to the pypi repository.
|
||||
|
||||
Most of the management commands have been directly placed inside the
|
||||
Makefile: `python setup.py make [alias]`, (or simply `make [alias]` in
|
||||
UNIX-like environments).
|
||||
|
||||
Note: to use the Makefile on Windows, you need to install make.exe,
|
||||
for example by installing [MinGW MSYS](http://www.mingw.org/wiki/msys).
|
||||
|
||||
|
||||
HOW TO COMMIT YOUR CONTRIBUTIONS
|
||||
--------------------------------
|
||||
|
||||
Contributions to the project is made using the "Fork & Pull" model. Here's a
|
||||
quickstart on how to do that (your mileage may vary depending on your git
|
||||
config):
|
||||
Contributions to the project are made using the "Fork & Pull" model. The
|
||||
typical steps would be:
|
||||
|
||||
- create an account on [github](https://github.com)
|
||||
- fork [tqdm](https://github.com/tqdm/tqdm)
|
||||
- make a local clone: `git clone https://github.com/your_account/tqdm.git`
|
||||
- make your changes on your local copy
|
||||
- commit your changes `git commit -m "my message"`
|
||||
- commit your changes `git commit -a -m "my message"`
|
||||
- TEST YOUR CHANGES (see below)
|
||||
- `push` to your github account: `git push origin`
|
||||
- finally, create a Pull Request (PR) from your github fork
|
||||
|
@ -30,22 +36,57 @@ TESTING
|
|||
To test functionality on your machine (such as before submitting a Pull
|
||||
Request), there are a number of unit tests.
|
||||
|
||||
To run the tests,
|
||||
|
||||
Standard unit testing
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The standard way to run the tests:
|
||||
|
||||
- install `tox`
|
||||
- `cd` to the root of the `tqdm` directory (in the same folder as this file)
|
||||
- run the following commands:
|
||||
- run the following command:
|
||||
|
||||
```
|
||||
python setup.py make test
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
make test
|
||||
make coverage
|
||||
make flake8
|
||||
```
|
||||
|
||||
Alternatively (if you can't use `make`)
|
||||
or
|
||||
|
||||
- install `nosetest`
|
||||
- run the following commands:
|
||||
```
|
||||
tox --skip-missing-interpreters
|
||||
```
|
||||
|
||||
This will build the module and run the tests in a virtual environment.
|
||||
Errors and coverage rates will be output to the console/log. (Ignore missing
|
||||
interpreters errors - these are due to the local machine missing certain
|
||||
versions of Python.)
|
||||
|
||||
Note: to install all versions of the Python interpreter that are specified
|
||||
in [tox.ini](https://raw.githubusercontent.com/tqdm/tqdm/master/tox.ini),
|
||||
you can use `MiniConda` to install a minimal setup. You must also make sure
|
||||
that each distribution has an alias to call the Python interpreter:
|
||||
`python27` for Python 2.7's interpreter, `python32` for Python 3.2's, etc.
|
||||
|
||||
|
||||
Alternative unit testing with Nose
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Alternatively, use `nose` to run the tests just for your Python version:
|
||||
|
||||
- install `nose` and `flake8`
|
||||
- run the following command:
|
||||
|
||||
```
|
||||
python setup.py make alltests
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
nosetests --with-coverage --cover-package=tqdm -v tqdm/
|
||||
|
|
69
Makefile
69
Makefile
|
@ -1,13 +1,76 @@
|
|||
.PHONY: all flake8 test coverage
|
||||
# IMPORTANT: for compatibility with `python setup.py make [alias]`, ensure:
|
||||
# 1. A line return after every alias
|
||||
# 2. One command per line
|
||||
# E.g.:
|
||||
# ```
|
||||
# all:
|
||||
# @make test
|
||||
# @make install
|
||||
# test:
|
||||
# nosetest
|
||||
# install:
|
||||
# python setup.py install
|
||||
# ```
|
||||
|
||||
.PHONY:
|
||||
alltests
|
||||
all
|
||||
flake8
|
||||
test
|
||||
testnose
|
||||
testsetup
|
||||
testcoverage
|
||||
installdev
|
||||
install
|
||||
build
|
||||
pypimeta
|
||||
pypi
|
||||
none
|
||||
|
||||
alltests:
|
||||
@make testcoverage
|
||||
@make flake8
|
||||
@make testsetup
|
||||
|
||||
all:
|
||||
@make alltests
|
||||
@make build
|
||||
|
||||
all: flake8 coverage
|
||||
flake8:
|
||||
flake8 --max-line-length=80 --count --statistics --exit-zero tqdm/
|
||||
flake8 --max-line-length=80 --count --statistics --exit-zero examples/
|
||||
flake8 --max-line-length=80 --count --statistics --exit-zero .
|
||||
|
||||
test:
|
||||
tox --skip-missing-interpreters
|
||||
|
||||
testnose:
|
||||
nosetests tqdm -v
|
||||
|
||||
coverage:
|
||||
testsetup:
|
||||
python setup.py check --restructuredtext --strict
|
||||
python setup.py make none
|
||||
|
||||
testcoverage:
|
||||
rm -f .coverage # coverage erase
|
||||
nosetests tqdm --with-coverage --cover-package=tqdm -v
|
||||
|
||||
installdev:
|
||||
python setup.py develop --uninstall
|
||||
python setup.py develop
|
||||
|
||||
install:
|
||||
python setup.py install
|
||||
|
||||
build:
|
||||
python setup.py sdist --formats=gztar,zip bdist_wininst
|
||||
python setup.py sdist bdist_wheel
|
||||
|
||||
pypimeta:
|
||||
python setup.py register
|
||||
|
||||
pypi:
|
||||
twine upload dist/*
|
||||
|
||||
none:
|
||||
# used for unit testing
|
||||
|
|
|
@ -225,13 +225,14 @@ with the following command:
|
|||
$ make test
|
||||
$ make coverage
|
||||
|
||||
See the `CONTRIBUTE <CONTRIBUTE>`__ file for more information.
|
||||
See the `CONTRIBUTE <https://raw.githubusercontent.com/tqdm/tqdm/master/CONTRIBUTE>`__
|
||||
file for more information.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
`MIT LICENSE <LICENSE>`__.
|
||||
`MIT LICENSE <https://raw.githubusercontent.com/tqdm/tqdm/master/LICENSE>`__.
|
||||
|
||||
|
||||
Authors
|
||||
|
|
40
RELEASE
40
RELEASE
|
@ -4,13 +4,20 @@ HOW TO MANAGE A NEW RELEASE
|
|||
This file is intended for the project's maintainers and it describes
|
||||
how to update, build and upload a new release.
|
||||
|
||||
Most of the management commands have been directly placed inside the
|
||||
Makefile: `python setup.py make [alias]`, (or simply `make [alias]` in
|
||||
UNIX-like environments).
|
||||
|
||||
Note: to use the Makefile on Windows, you need to install make.exe,
|
||||
for example by installing [MinGW MSYS](http://www.mingw.org/wiki/msys).
|
||||
|
||||
|
||||
SEMANTIC VERSIONING
|
||||
-------------------
|
||||
|
||||
The tqdm repository managers should regularly bump the version number in the
|
||||
VERSION file to follow the [Semantic Versioning](http://semver.org/)
|
||||
convention.
|
||||
[_version.py](https://raw.githubusercontent.com/tqdm/tqdm/master/tqdm/_version.py)
|
||||
file to follow the [Semantic Versioning](http://semver.org/) convention.
|
||||
|
||||
Tools can be used to automate this process, such as
|
||||
[bumpversion](https://github.com/peritus/bumpversion) or
|
||||
|
@ -18,23 +25,22 @@ Tools can be used to automate this process, such as
|
|||
to automate this task.
|
||||
|
||||
The managers should take care of this instead of users to avoid PR conflicts
|
||||
solely due to the VERSION file bumping.
|
||||
solely due to the version file bumping.
|
||||
|
||||
|
||||
CHECKING SETUP.PY
|
||||
-----------------
|
||||
|
||||
To check that the setup.py is OK for PyPi (eg, version number,
|
||||
reStructuredText in README.rst intelligible for PyPi, which uses a
|
||||
awkward RST lib, etc.) you can use the following command to make
|
||||
sure everything's ok:
|
||||
To check that the `setup.py` file is compliant with PyPi requirements (e.g.
|
||||
version number; reStructuredText in README.rst) use the following command:
|
||||
|
||||
```
|
||||
python setup.py check --restructuredtext --strict
|
||||
```
|
||||
|
||||
Also, if you happen to mistakenly upload a broken release to PyPi,
|
||||
you can fix the metadata by using: `python setup.py register`.
|
||||
If you happen to mistakenly upload a broken release to PyPi,
|
||||
you can fix the metadata by using: `python setup.py make pypimeta`
|
||||
or `python setup.py register`.
|
||||
|
||||
|
||||
BUILDING A RELEASE AND UPLOADING TO PYPI
|
||||
|
@ -46,24 +52,22 @@ process and info that will be uploaded to [pypi](pypi.python.org).
|
|||
Check the result by using the following commands:
|
||||
|
||||
```
|
||||
python setup.py develop --uninstall
|
||||
python setup.py develop
|
||||
python setup.py make installdev
|
||||
```
|
||||
|
||||
Secondly, build tqdm into a distributable python package:
|
||||
|
||||
```
|
||||
python setup.py sdist --formats=gztar,zip bdist_wininst --plat-name=win32
|
||||
python setup.py sdist bdist_wheel --plat-name=win32
|
||||
python setup.py make build
|
||||
```
|
||||
|
||||
This will generate several builds in the `dist/` folder.
|
||||
|
||||
Finally, we can upload everything to pypi. Uploading to pypi can be done
|
||||
easily using the [twine](https://github.com/pypa/twine) module:
|
||||
Finally, upload everything to pypi. This can be done easily using the
|
||||
[twine](https://github.com/pypa/twine) module:
|
||||
|
||||
```
|
||||
twine upload dist/*
|
||||
python setup.py make pypi
|
||||
```
|
||||
|
||||
NOTE:
|
||||
|
@ -74,7 +78,7 @@ before the real deployment
|
|||
cannot re-upload another with the same version number!
|
||||
- in case of a mistake in the metadata on pypi (like the long description README
|
||||
getting garbled because of a silent error), you can use the following
|
||||
command to update the metadata: `python setup.py register`
|
||||
command to update the metadata: `make pypimeta` or `python setup.py register`
|
||||
|
||||
Also, the new release can be added to the Github by creating a new release
|
||||
Also, the new release can be added to github by creating a new release
|
||||
from the web interface.
|
||||
|
|
|
@ -26,5 +26,5 @@ stmts = (
|
|||
' [i for i in ProgressBar()(xrange(int(1e8)))]')
|
||||
|
||||
for s in stmts:
|
||||
print s
|
||||
print timeit(stmt=s, number=1), 'seconds'
|
||||
print(s)
|
||||
print(timeit(stmt=s, number=1), 'seconds')
|
||||
|
|
166
setup.py
166
setup.py
|
@ -1,14 +1,161 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
from setuptools import setup
|
||||
import sys
|
||||
import subprocess
|
||||
# For Makefile parsing
|
||||
try: # pragma: no cover
|
||||
import ConfigParser
|
||||
import StringIO
|
||||
except ImportError: # pragma: no cover
|
||||
# Python 3 compatibility
|
||||
import configparser as ConfigParser
|
||||
import io as StringIO
|
||||
|
||||
|
||||
""" Makefile auxiliary functions """
|
||||
|
||||
|
||||
def parse_makefile_aliases(filepath):
|
||||
'''
|
||||
Parse a makefile to find commands and substitute variables. Expects a
|
||||
makefile with only aliases and a line return between each command, i.e.:
|
||||
|
||||
```
|
||||
all:
|
||||
test
|
||||
install
|
||||
test:
|
||||
nosetest
|
||||
install:
|
||||
python setup.py install
|
||||
```
|
||||
|
||||
Returns a dict, with a list of commands for each alias.
|
||||
'''
|
||||
|
||||
# -- Parsing the Makefile using ConfigParser
|
||||
# Adding a fake section to make the Makefile a valid Ini file
|
||||
ini_str = '[root]\n'
|
||||
with open(filepath, 'r') as fd:
|
||||
ini_str = ini_str + fd.read().replace('@make ', '')
|
||||
ini_fp = StringIO.StringIO(ini_str)
|
||||
# Parse using ConfigParser
|
||||
config = ConfigParser.RawConfigParser()
|
||||
config.readfp(ini_fp)
|
||||
# Fetch the list of aliases
|
||||
aliases = config.options('root')
|
||||
|
||||
# -- Extracting commands for each alias
|
||||
commands = {}
|
||||
for alias in aliases:
|
||||
# strip the first line return, and then split by any line return
|
||||
commands[alias] = config.get('root', alias).lstrip('\n').split('\n')
|
||||
|
||||
# -- Commands substitution
|
||||
# Loop until all aliases are substituted by their commands:
|
||||
# Check each command of each alias, and if there is one command that is to
|
||||
# be substituted by an alias, try to do it right away. If this is not
|
||||
# possible because this alias itself points to other aliases , then stop
|
||||
# and put the current alias back in the queue to be processed again later.
|
||||
|
||||
# Create the queue of aliases to process
|
||||
aliases_todo = commands.keys()
|
||||
# Create the dict that will hold the full commands
|
||||
commands_new = {}
|
||||
# Loop until we have processed all aliases
|
||||
while aliases_todo:
|
||||
# Pick the first alias in the queue
|
||||
alias = aliases_todo.pop(0)
|
||||
# Create a new entry in the resulting dict
|
||||
commands_new[alias] = []
|
||||
# For each command of this alias
|
||||
for cmd in commands[alias]:
|
||||
# Ignore self-referencing (alias points to itself)
|
||||
if cmd == alias:
|
||||
pass
|
||||
# Substitute full command
|
||||
elif cmd in aliases and cmd in commands_new:
|
||||
# Append all the commands referenced by the alias
|
||||
commands_new[alias].extend(commands_new[cmd])
|
||||
# Delay substituting another alias, waiting for the other alias to
|
||||
# be substituted first
|
||||
elif cmd in aliases and cmd not in commands_new:
|
||||
# Delete the current entry to avoid other aliases
|
||||
# to reference this one wrongly (as it is empty)
|
||||
del commands_new[alias]
|
||||
aliases_todo.append(alias)
|
||||
break
|
||||
# Full command (no aliases)
|
||||
else:
|
||||
commands_new[alias].append(cmd)
|
||||
commands = commands_new
|
||||
del commands_new
|
||||
|
||||
# -- Prepending prefix to avoid conflicts with standard setup.py commands
|
||||
# for alias in commands.keys():
|
||||
# commands['make_'+alias] = commands[alias]
|
||||
# del commands[alias]
|
||||
|
||||
return commands
|
||||
|
||||
|
||||
def execute_makefile_commands(commands, alias, verbose=False):
|
||||
cmds = commands[alias]
|
||||
for cmd in cmds:
|
||||
if verbose:
|
||||
print("Running command: " + cmd)
|
||||
subprocess.check_call(cmd.split())
|
||||
|
||||
|
||||
""" Main setup.py config """
|
||||
|
||||
|
||||
# Get version from tqdm/_version.py
|
||||
__version__ = None
|
||||
version_file = os.path.join(os.path.dirname(__file__), 'tqdm', '_version.py')
|
||||
for line in open(version_file).readlines():
|
||||
if (line.startswith('version_info') or line.startswith('__version__')):
|
||||
exec(line.strip())
|
||||
with open(version_file) as fd:
|
||||
exec(fd.read())
|
||||
|
||||
# Executing makefile commands if specified
|
||||
if sys.argv[1].lower().strip() == 'make':
|
||||
# Filename of the makefile
|
||||
fpath = 'Makefile'
|
||||
# Parse the makefile, substitute the aliases and extract the commands
|
||||
commands = parse_makefile_aliases(fpath)
|
||||
|
||||
# If no alias (only `python setup.py make`), print the list of aliases
|
||||
if len(sys.argv) < 3 or sys.argv[-1] == '--help':
|
||||
print("Shortcut to use commands via aliases. List of aliases:")
|
||||
for alias in sorted(commands.keys()):
|
||||
print("- " + alias)
|
||||
|
||||
# Else process the commands for this alias
|
||||
else:
|
||||
arg = sys.argv[-1]
|
||||
# if unit testing, we do nothing (we just checked the makefile parsing)
|
||||
if arg == 'none':
|
||||
sys.exit(0)
|
||||
# else if the alias exists, we execute its commands
|
||||
elif arg in commands.keys():
|
||||
execute_makefile_commands(commands, arg, verbose=True)
|
||||
# else the alias cannot be found
|
||||
else:
|
||||
raise Exception("Provided alias cannot be found: make " + arg)
|
||||
# Stop the processing of setup.py here:
|
||||
# It's important to avoid setup.py raising an error because of the command
|
||||
# not being standard
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
""" Python package config """
|
||||
|
||||
|
||||
README_rst = ''
|
||||
with open('README.rst', 'r') as fd:
|
||||
README_rst = fd.read()
|
||||
|
||||
setup(
|
||||
name='tqdm',
|
||||
|
@ -20,10 +167,12 @@ setup(
|
|||
url='https://github.com/tqdm/tqdm',
|
||||
maintainer='tqdm developers',
|
||||
maintainer_email='python.tqdm@gmail.com',
|
||||
platforms = ["any"],
|
||||
platforms=['any'],
|
||||
packages=['tqdm'],
|
||||
long_description = open("README.rst", "r").read(),
|
||||
classifiers=[ # Trove classifiers, see https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||
long_description=README_rst,
|
||||
classifiers=[
|
||||
# Trove classifiers
|
||||
# (https://pypi.python.org/pypi?%3Aaction=list_classifiers)
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Environment :: Console',
|
||||
|
@ -48,5 +197,8 @@ setup(
|
|||
'Topic :: Utilities',
|
||||
'Intended Audience :: Developers',
|
||||
],
|
||||
keywords = 'progressbar progressmeter progress bar meter rate eta console terminal time',
|
||||
keywords='progressbar progressmeter progress bar meter'
|
||||
' rate eta console terminal time',
|
||||
test_suite='nose.collector',
|
||||
tests_require=['nose', 'flake8', 'coverage'],
|
||||
)
|
||||
|
|
16
tox.ini
16
tox.ini
|
@ -4,7 +4,7 @@
|
|||
# and then run "tox" from this directory.
|
||||
|
||||
[tox]
|
||||
envlist = py26, py27, py32, py33, py34, pypy, pypy3, flake8
|
||||
envlist = py26, py27, py32, py33, py34, pypy, pypy3, flake8, setup.py
|
||||
|
||||
[testenv]
|
||||
passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH
|
||||
|
@ -17,8 +17,16 @@ commands =
|
|||
coveralls
|
||||
|
||||
[testenv:flake8]
|
||||
basepython = python2.7
|
||||
deps = flake8
|
||||
commands =
|
||||
flake8 --count --statistics tqdm/
|
||||
flake8 --count --statistics examples/
|
||||
flake8 --max-line-length=80 --count --statistics --exit-zero tqdm/
|
||||
flake8 --max-line-length=80 --count --statistics --exit-zero examples/
|
||||
flake8 --max-line-length=80 --count --statistics --exit-zero .
|
||||
|
||||
[testenv:setup.py]
|
||||
deps =
|
||||
docutils
|
||||
pygments
|
||||
commands =
|
||||
python setup.py check --restructuredtext --metadata --strict
|
||||
python setup.py make none
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Definition of the version number
|
||||
version_info = 2, 1, 0 # major, minor, patch, -extra
|
||||
version_info = 2, 2, 0 # major, minor, patch, -extra
|
||||
|
||||
# Nice string for the version
|
||||
__version__ = '.'.join(map(str, version_info)).replace('.-', '-').strip('.-')
|
||||
|
|
Loading…
Reference in New Issue