From e75c9a2d4a88a6ec782158f5cc46e9f0c2712960 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 9 Jan 2015 15:26:14 -0600 Subject: [PATCH] Add versioning helpers --- conftest.py | 1 + docs/config/index.rst | 33 ++++++++++++++++++++++++++++++++- raven/__init__.py | 1 + raven/exceptions.py | 4 ++++ raven/versioning.py | 33 +++++++++++++++++++++++++++++++++ tests/versioning/__init__.py | 0 tests/versioning/tests.py | 18 ++++++++++++++++++ 7 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 raven/versioning.py create mode 100644 tests/versioning/__init__.py create mode 100644 tests/versioning/tests.py diff --git a/conftest.py b/conftest.py index 2f2d5908..b5b6aa17 100644 --- a/conftest.py +++ b/conftest.py @@ -68,6 +68,7 @@ def pytest_configure(config): SENTRY_ALLOW_ORIGIN='*', CELERY_ALWAYS_EAGER=True, TEMPLATE_DEBUG=True, + PROJECT_ROOT=where_am_i, TEMPLATE_DIRS=[os.path.join(where_am_i, 'tests', 'contrib', 'django', 'templates')], ALLOWED_HOSTS=['*'], ) diff --git a/docs/config/index.rst b/docs/config/index.rst index 6914c0f6..719dc493 100644 --- a/docs/config/index.rst +++ b/docs/config/index.rst @@ -13,7 +13,7 @@ As of Raven 1.2.0, you can now configure all clients through a standard DSN string. This can be specified as a default using the ``SENTRY_DSN`` environment variable, as well as passed to all clients by using the ``dsn`` argument. -:: +.. code-block:: python from raven import Client @@ -24,6 +24,26 @@ variable, as well as passed to all clients by using the ``dsn`` argument. client = Client('http://public:secret@example.com/1') +A reasonably configured client should generally include a few additional settings: + +.. code-block:: python + + import raven + + client = raven.Client( + dsn='http://public:secret@example.com/1' + + # inform the client which parts of code are yours + # include_paths=['my.app'] + include_paths=[__name__.rsplit('.', 1)[0]], + + # pass along the version of your application + # release='1.0.0' + # release=raven.fetch_package_version('my-app') + release=raven.fetch_git_sha(os.path.dirname(__file__)), + ) + + The Sentry DSN -------------- @@ -115,6 +135,17 @@ This will override the ``server_name`` value for this installation. Defaults to name = 'sentry_rocks_' + socket.gethostname() + +release +~~~~~~~~ + +The version of your application. This will map up into a Release in Sentry. + +:: + + release = '1.0.3' + + exclude_paths ~~~~~~~~~~~~~ diff --git a/raven/__init__.py b/raven/__init__.py index 8e37e410..2a453eb0 100644 --- a/raven/__init__.py +++ b/raven/__init__.py @@ -11,6 +11,7 @@ import os import os.path from raven.base import * # NOQA from raven.conf import * # NOQA +from raven.versioning import * # NOQA __all__ = ('VERSION', 'Client', 'load', 'get_version') diff --git a/raven/exceptions.py b/raven/exceptions.py index 7c30fafb..598a9f5b 100644 --- a/raven/exceptions.py +++ b/raven/exceptions.py @@ -16,3 +16,7 @@ class RateLimited(APIError): def __init__(self, message, retry_after=0): self.retry_after = retry_after super(RateLimited, self).__init__(message, 429) + + +class InvalidGitRepository(Exception): + pass diff --git a/raven/versioning.py b/raven/versioning.py new file mode 100644 index 00000000..9809f142 --- /dev/null +++ b/raven/versioning.py @@ -0,0 +1,33 @@ +from __future__ import absolute_import + +__all__ = ('fetch_git_sha', 'fetch_package_version') + +import os.path +import pkg_resources + +from .exceptions import InvalidGitRepository + + +def fetch_git_sha(path, head='master'): + """ + >>> fetch_git_sha(os.path.dirname(__file__)) + """ + revision_file = os.path.join(path, '.git', 'refs', 'heads', 'master') + if not os.path.exists(revision_file): + if not os.path.exists(os.path.join(path, '.git')): + raise InvalidGitRepository('%s does not seem to be the root of a git repository' % (path,)) + raise InvalidGitRepository('Unable to find ref to head "%s" in repository' % (head,)) + + fh = open(revision_file, 'r') + try: + return fh.read().strip() + finally: + fh.close() + + +def fetch_package_version(dist_name): + """ + >>> fetch_package_version('sentry') + """ + dist = pkg_resources.get_distribution(dist_name) + return dist.version diff --git a/tests/versioning/__init__.py b/tests/versioning/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/versioning/tests.py b/tests/versioning/tests.py new file mode 100644 index 00000000..8beb7228 --- /dev/null +++ b/tests/versioning/tests.py @@ -0,0 +1,18 @@ +from __future__ import absolute_import + +from django.conf import settings + +from raven.versioning import fetch_git_sha, fetch_package_version + + +def test_fetch_git_sha(): + result = fetch_git_sha(settings.PROJECT_ROOT) + assert result is not None + assert len(result) == 40 + assert isinstance(result, basestring) + + +def test_fetch_package_version(): + result = fetch_package_version('raven') + assert result is not None + assert isinstance(result, basestring)