Commit ba8529cf authored by Manuel Günther's avatar Manuel Günther

Moved new_version package to bob/extension/scripts directory and added a test.

parent f3f5008e
from .new_version import main as new_version
# gets sphinx autodoc done right - don't remove it
__all__ = [_ for _ in dir() if not _.startswith('_')]
#!/usr/bin/env python
from __future__ import print_function
import sys, os
import subprocess
import argparse
from distutils.version import StrictVersion as Version
def main(command_line_options = None):
"""
This script will push a new ``'stable'`` version of the current package on GitHub and PyPI, and update the new version of the package to the given ``'latest'`` version.
It assumes that you are in the main directory of the package and have successfully ran bootstrap, and that you have submitted all changes that should go into the new version.
Preferably, the build on Travis passed.
For database packages, it also assumes that the ``.sql3`` files have been generated.
Also, it assumes that the ``'stable'`` version has not yet been uploaded to PyPI, and that no GitHub tag with this version exists.
The ``'stable'`` version (i.e., what will be downloadable from PyPI) can be current version of the package, but not lower than that.
The ``'latest'`` version (i.e., what will be the new master branch on GitHub) must be higher than the current and than the stable version.
By default, five steps are executed, in this order:
- ``tag``: If given, the --stable-version will be set and added to GitHub; and the version is tagged in GitHub and pushed.
- ``build``: The package will be (re-)built with bin/buildout using the provided build options.
- ``pypi``: The --stable-version (or the current version) will be registered and uploaded to PyPI
- ``docs``: The documentation will be generated and uploaded to PythonHosted
- ``latest``: The --latest-version will be set and committed to GitHub
If any of these commands fail, the remaining steps will be skipped, unless you specify the ``--keep-going`` option.
If you only want a subset of the steps to be executed, you can limit them using the ``--steps`` option.
A valid use case, e.g., is only to re-upload the documentation.
"""
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("--latest-version", '-l', required = True, help = "The latest version for the package")
parser.add_argument("--stable-version", '-s', help = "The stable version for the package; if not given, the current version is used")
parser.add_argument("--build-options", '-b', nargs='+', default = [], help = "Add options to build your package")
parser.add_argument("--steps", nargs = "+", choices = ['tag', 'build', 'pypi', 'docs', 'latest'], default = ['tag', 'build', 'pypi', 'docs', 'latest'], help = "Select the steps that you want to execute")
parser.add_argument("--dry-run", '-q', action = 'store_true', help = "Only print the actions, but do not execute them")
parser.add_argument("--keep-going", '-f', action = 'store_true', help = "Run all steps, even if some of them fail. HANDLE THIS FLAG WITH CARE!")
parser.add_argument("--verbose", '-v', action = 'store_true', help = "Print more information")
args = parser.parse_args(command_line_options)
# assert the the version file is there
version_file = 'version.txt'
if not os.path.exists(version_file):
raise ValueError("Could not find the file '%s' containing the version number. Are you inside the root directory of your package?")
def run_commands(version, *calls):
"""Updates the version.txt to the given version and runs the given commands."""
if version is not None and (args.verbose or args.dry_run):
print (" - cat '%s' > %s" % (version, version_file))
if not args.dry_run and version is not None:
# update version to stable version, if not done yet
with open(version_file, 'w') as f:
f.write(version)
# get all calls
for call in calls:
if args.verbose or args.dry_run:
print (' - ' + ' '.join(call))
if not args.dry_run:
# execute call
if subprocess.call(call):
# call failed (has non-zero exit status)
print ("Command '%s' failed; stopping" % ' '.join(call))
if not args.keep_going:
raise ValueError("Command '%s' failed; stopping" % ' '.join(call))
# get current version
current_version = open(version_file).read().rstrip()
# check the versions
if args.stable_version is not None and Version(args.latest_version) <= Version(args.stable_version):
raise ValueError("The latest version '%s' must be greater than the stable version '%s'" % (args.latest_version, args.stable_version))
if Version(current_version) >= Version(args.latest_version):
raise ValueError("The latest version '%s' must be greater than the current version '%s'" % (args.latest_version, current_version))
if args.stable_version is not None and Version(current_version) > Version(args.stable_version):
raise ValueError("The stable version '%s' cannot be smaller than the current version '%s'" % (args.stable_version, current_version))
if 'tag' in args.steps:
if args.stable_version is not None and Version(args.stable_version) > Version(current_version):
# update stable version on github
run_commands(args.stable_version, ['git', 'add', 'version.txt'], ['git', 'commit', '-m', 'Increased version to %s [skip ci]' % args.stable_version])
else:
# assure that we have the current version
args.stable_version = current_version
# add a github tag
print ("\nTagging version '%s'" % args.stable_version)
run_commands(None, ['git', 'tag', 'v%s' % args.stable_version], ['git', 'push', '--tags'])
if 'build' in args.steps:
print ("\nBuilding the package")
run_commands(None, ['./bin/buildout'] + args.build_options)
if 'pypi' in args.steps:
print ("\nUploading version '%s' to PyPI" % args.stable_version)
# update version on github and add a tag
run_commands(None, ['./bin/python', 'setup.py', 'register'], ['./bin/python', 'setup.py', 'sdist', '--formats', 'zip', 'upload'])
if 'docs' in args.steps:
# Documentation can be uploaded, independent of the versions
print ("\nUploading documentation to PythonHosted.org")
run_commands(None, ["./bin/python", "setup.py", "build_sphinx", "--source-dir", "doc", "--build-dir", "build/doc", "--all-files"], ["./bin/python", "setup.py", "upload_docs", "--upload-dir", "build/doc/html"])
if 'latest' in args.steps:
# update GitHub version to latest version
print ("\nSetting latest version '%s'" % args.latest_version)
run_commands(args.latest_version, ['git', 'add', 'version.txt'], ['git', 'commit', '-m', 'Increased version to %s' % args.latest_version], ['git', 'push'])
if __name__ == '__main__':
main()
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Andre Anjos <andre.anjos@idiap.ch>
# Thu 20 Mar 2014 12:43:48 CET
"""Tests for scripts
"""
import os
import sys
import nose.tools
def test_new_version():
# Tests the bin/bob_new_version.py script
from bob.extension.scripts import new_version
# test the script using the dry-run option (to avoid to actually tag and push code)
# assert that it does not raise an exception, when both latest and stable version are specified
new_version(['--dry-run', '--stable-version', '20.7.0', '--latest-version', '20.8.0'])
# assert that it does not raise an exception, when only the latest version is specified
new_version(['--dry-run', '--latest-version', '20.8.0'])
# assert that it does raise an exception, when the latest version is too low
nose.tools.assert_raises(ValueError, new_version, ['--dry-run', '--latest-version', '0.8.0'])
# assert that it does raise an exception, when the stable version is too low
nose.tools.assert_raises(ValueError, new_version, ['--dry-run', '--stable-version', '0.8.0', '--latest-version', '0.9.0'])
# assert that it does raise an exception, when the stable version is higher than latest version
nose.tools.assert_raises(ValueError, new_version, ['--dry-run', '--stable-version', '20.8.0', '--latest-version', '20.8.0a1'])
......@@ -324,7 +324,7 @@ This file will be used to generate the front page of your package on PyPI_ and w
The ``README.rst`` of **this package** (``bob.extension``) is a good example, including all the badges that show the current status of the package and the link to relevant information.
To ease up your life, we also provide a script to run all steps to publish your package.
Please read the following paragraphs to understand the steps in the ``./scripts/new_version.py`` script that will be explained at the end of this section.
Please read the following paragraphs to understand the steps in the ``./bin/bob_new_version.py`` script that will be explained at the end of this section.
Version Numbering Scheme
========================
......@@ -472,13 +472,13 @@ and, finally, to keep track of new changes:
5. Switch to a new version number.
All these steps are combined in the ``./scripts/new_version.py`` script.
All these steps are combined in the ``./bin/bob_new_version.py`` script.
This script needs to be run from within the root directory of your package.
Please run:
.. code-block:: sh
$ [PATH/TO/]bob.extension/script/new_version.py --help
$ ./bin/bob_new_version.py --help
to see a list of options.
......
......@@ -6,7 +6,14 @@
Python API to `bob.extension`
================================
This section includes information for using the Python API of
``bob.extension``.
This section includes information for using the Python API of ``bob.extension``.
Functions
---------
.. automodule:: bob.extension
Scripts
-------
.. automodule:: bob.extension.scripts
#!/usr/bin/env python
from __future__ import print_function
import sys, os
import subprocess
import argparse
from distutils.version import StrictVersion as Version
doc = """
This script will push a new 'stable' version of the current package on GitHub and PyPI, and update the new version of the package to the given 'latest' version.
It assumes that you are in the main directory of the package and have successfully ran bootstrap, and that you have submitted all changes that should go into the new version.
For database packages, it also assumes that the .sql3 files have been generated.
Also, it assumes that the 'stable' version has not yet been uploaded to PyPI, and that no GitHub tag with this version exists.
The 'stable' version (i.e., what will be downloadable from PyPI) can be current version of the package, but not lower than that.
The 'latest' version (i.e., what will be the new master branch on GitHub) must be higher than the current and than the stable version.
By default, five steps are executed, in this order:
- tag: If given, the --stable-version will be set and added to GitHub; and the version is tagged in GitHub and pushed.
- build: The package will be (re-)built with bin/buildout using the provided build options.
- pypi: The --stable-version (or the current version) will be registered and uploaded to PyPI
- docs: The documentation will be generated and uploaded to PythonHosted
- latest: The --latest-version will be set and committed to GitHub
If any of these commands fail, the remaining steps will be skipped, unless you specify the --keep-going option.
If you only want a subset of the steps to be executed, you can limit them using the --steps option.
A valid use case, e.g., is only to re-upload the documentation.
"""
parser = argparse.ArgumentParser(description=doc, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("--latest-version", '-l', required = True, help = "The latest version for the package")
parser.add_argument("--stable-version", '-s', help = "The stable version for the package; if not given, the current version is used")
parser.add_argument("--build-options", '-b', nargs='+', default = [], help = "Add options to build your package")
parser.add_argument("--steps", nargs = "+", choices = ['tag', 'build', 'pypi', 'docs', 'latest'], default = ['tag', 'build', 'pypi', 'docs', 'latest'], help = "Select the steps that you want to execute")
parser.add_argument("--dry-run", '-q', action = 'store_true', help = "Only print the actions, but do not execute them")
parser.add_argument("--keep-going", '-f', action = 'store_true', help = "Run all steps, even if some of them fail. HANDLE THIS FLAG WITH CARE!")
parser.add_argument("--verbose", '-v', action = 'store_true', help = "Print more information")
args = parser.parse_args()
# assert the the version file is there
version_file = 'version.txt'
if not os.path.exists(version_file):
print("Could not find the file '%s' containing the version number. Are you inside the root directory of your package?")
sys.exit(-1)
def run_commands(version, *calls):
"""Updates the version.txt to the given version and runs the given commands."""
if version is not None and (args.verbose or args.dry_run):
print (" - cat '%s' > %s" % (version, version_file))
if not args.dry_run and version is not None:
# update version to stable version, if not done yet
with open(version_file, 'w') as f:
f.write(version)
# get all calls
for call in calls:
if args.verbose or args.dry_run:
print (' - ' + ' '.join(call))
if not args.dry_run:
# execute call
if subprocess.call(call):
# call failed (has non-zero exit status)
print ("Command '%s' failed; stopping" % ' '.join(call))
if not args.keep_going:
sys.exit(-1)
# get current version
current_version = open(version_file).read().rstrip()
# check the versions
if args.stable_version is not None and Version(args.latest_version) <= Version(args.stable_version):
print ("The latest version '%s' must be greater than the stable version '%s'" % (args.latest_version, args.stable_version))
sys.exit(-1)
if Version(current_version) >= Version(args.latest_version):
print ("The latest version '%s' must be greater than the current version '%s'" % (args.latest_version, current_version))
sys.exit(-1)
if args.stable_version is not None and Version(current_version) > Version(args.stable_version):
print ("The stable version '%s' cannot be smaller than the current version '%s'" % (args.stable_version, current_version))
sys.exit(-1)
if 'tag' in args.steps:
if args.stable_version is not None and Version(args.stable_version) > Version(current_version):
# update stable version on github
run_commands(args.stable_version, ['git', 'add', 'version.txt'], ['git', 'commit', '-m', 'Increased version to %s [skip ci]' % args.stable_version])
else:
# assure that we have the current version
args.stable_version = current_version
# add a github tag
print ("\nTagging version '%s'" % args.stable_version)
run_commands(None, ['git', 'tag', 'v%s' % args.stable_version], ['git', 'push', '--tags'])
if 'build' in args.steps:
print ("\nBuilding the package")
run_commands(None, ['./bin/buildout'] + args.build_options)
if 'pypi' in args.steps:
print ("\nUploading version '%s' to PyPI" % args.stable_version)
# update version on github and add a tag
run_commands(None, ['./bin/python', 'setup.py', 'register'], ['./bin/python', 'setup.py', 'sdist', '--formats', 'zip', 'upload'])
if 'docs' in args.steps:
# Documentation can be uploaded, independent of the versions
print ("\nUploading documentation to PythonHosted.org")
run_commands(None, ["./bin/python", "setup.py", "build_sphinx", "--source-dir", "doc", "--build-dir", "build/doc", "--all-files"], ["./bin/python", "setup.py", "upload_docs", "--upload-dir", "build/doc/html"])
if 'latest' in args.steps:
# update GitHub version to latest version
print ("\nSetting latest version '%s'" % args.latest_version)
run_commands(args.latest_version, ['git', 'add', 'version.txt'], ['git', 'commit', '-m', 'Increased version to %s' % args.latest_version], ['git', 'push'])
......@@ -34,6 +34,12 @@ setup(
'setuptools',
],
entry_points = {
'console_scripts': [
'bob_new_version.py = bob.extension.scripts:new_version',
],
},
classifiers = [
'Framework :: Bob',
'Development Status :: 4 - Beta',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment