launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #20963
[Merge] lp:~cjwatson/launchpad/git-version-info into lp:launchpad
Colin Watson has proposed merging lp:~cjwatson/launchpad/git-version-info into lp:launchpad.
Commit message:
Handle running from a Git working tree.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/git-version-info/+merge/305701
Handle running from a Git working tree.
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/git-version-info into lp:launchpad.
=== modified file '.bzrignore'
--- .bzrignore 2013-04-15 02:36:07 +0000
+++ .bzrignore 2016-09-14 11:56:46 +0000
@@ -1,5 +1,6 @@
+*.pyc
.tags
-bzr-version-info.py
+version-info.py
logs/*
+*
sourcecode/*
=== added symlink '.gitignore'
=== target is u'.bzrignore'
=== modified file 'Makefile'
--- Makefile 2015-09-08 02:31:49 +0000
+++ Makefile 2016-09-14 11:56:46 +0000
@@ -35,7 +35,7 @@
CONVOY_ROOT?=/srv/launchpad.dev/convoy
-BZR_VERSION_INFO = bzr-version-info.py
+VERSION_INFO = version-info.py
APIDOC_DIR = lib/canonical/launchpad/apidoc
APIDOC_TMPDIR = $(APIDOC_DIR).tmp/
@@ -73,7 +73,7 @@
hosted_branches: $(PY)
$(PY) ./utilities/make-dummy-hosted-branches
-$(API_INDEX): $(BZR_VERSION_INFO) $(PY)
+$(API_INDEX): $(VERSION_INFO) $(PY)
$(RM) -r $(APIDOC_DIR) $(APIDOC_DIR).tmp
mkdir -p $(APIDOC_DIR).tmp
LPCONFIG=$(LPCONFIG) $(PY) ./utilities/create-lp-wadl-and-apidoc.py \
@@ -238,7 +238,7 @@
$(subst $(PY),,$(BUILDOUT_BIN)): $(PY)
-compile: $(PY) $(BZR_VERSION_INFO)
+compile: $(PY) $(VERSION_INFO)
${SHHH} $(MAKE) -C sourcecode build PYTHON=${PYTHON} \
LPCONFIG=${LPCONFIG}
${SHHH} LPCONFIG=${LPCONFIG} ${PY} -t buildmailman.py
@@ -295,10 +295,10 @@
stop_librarian:
bin/killservice librarian
-$(BZR_VERSION_INFO):
- scripts/update-bzr-version-info.sh
+$(VERSION_INFO):
+ scripts/update-version-info.sh
-support_files: $(API_INDEX) $(BZR_VERSION_INFO)
+support_files: $(API_INDEX) $(VERSION_INFO)
# Intended for use on developer machines
start: inplace stop support_files initscript-start
@@ -393,7 +393,7 @@
$(RM) -r $(APIDOC_DIR)
$(RM) -r $(APIDOC_DIR).tmp
$(RM) -r build
- $(RM) $(BZR_VERSION_INFO)
+ $(RM) $(VERSION_INFO)
$(RM) +config-overrides.zcml
$(RM) -r /var/tmp/builddmaster \
/var/tmp/bzrsync \
=== modified file 'database/schema/upgrade.py'
--- database/schema/upgrade.py 2014-08-29 01:34:04 +0000
+++ database/schema/upgrade.py 2016-09-14 11:56:46 +0000
@@ -1,6 +1,6 @@
#!/usr/bin/python -S
#
-# Copyright 2009 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""
@@ -15,6 +15,7 @@
from optparse import OptionParser
import os.path
import re
+import subprocess
from textwrap import dedent
from bzrlib.branch import Branch
@@ -31,7 +32,7 @@
)
-SCHEMA_DIR = os.path.dirname(__file__)
+SCHEMA_DIR = os.path.dirname(os.path.abspath(__file__))
def main(con=None):
@@ -161,7 +162,7 @@
# Repair patch timestamps if necessary.
cur.execute(
- FIX_PATCH_TIMES_POST_SQL % sqlvalues(*get_bzr_details()))
+ FIX_PATCH_TIMES_POST_SQL % sqlvalues(*get_vcs_details()))
# Update comments.
apply_comments(con)
@@ -245,26 +246,38 @@
log.debug("Skipping comments.sql per command line settings")
-_bzr_details_cache = None
-
-
-def get_bzr_details():
- """Return (branch_nick, revno, revision_id) of this Bazaar branch.
+_vcs_details_cache = None
+
+
+def get_vcs_details():
+ """Return (branch_nick, revno, revision_id) of this VCS branch.
+
+ If this is a Git branch, then revno will be None.
Returns (None, None, None) if the tree this code is running from
- is not a Bazaar branch.
+ is not a VCS branch.
"""
- global _bzr_details_cache
- if _bzr_details_cache is None:
- try:
- branch = Branch.open_containing(SCHEMA_DIR)[0]
- revno, revision_id = branch.last_revision_info()
- branch_nick = branch.get_config().get_nickname()
- except NotBranchError:
- log.warning("Not a Bazaar branch - branch details unavailable")
- revision_id, revno, branch_nick = None, None, None
- _bzr_details_cache = (branch_nick, revno, revision_id)
- return _bzr_details_cache
+ global _vcs_details_cache
+ if _vcs_details_cache is None:
+ top = os.path.dirname(os.path.dirname(SCHEMA_DIR))
+ if os.path.exists(os.path.join(top, ".git")):
+ branch_nick = subprocess.check_output(
+ ["git", "rev-parse", "--abbrev-ref", "HEAD"],
+ universal_newlines=True).rstrip("\n")
+ revno = None
+ revision_id = subprocess.check_output(
+ ["git", "rev-parse", "HEAD"],
+ universal_newlines=True).rstrip("\n")
+ else:
+ try:
+ branch = Branch.open_containing(SCHEMA_DIR)[0]
+ revno, revision_id = branch.last_revision_info()
+ branch_nick = branch.get_config().get_nickname()
+ except NotBranchError:
+ log.warning("Not a Bazaar branch - branch details unavailable")
+ revision_id, revno, branch_nick = None, None, None
+ _vcs_details_cache = (branch_nick, revno, revision_id)
+ return _vcs_details_cache
if __name__ == '__main__':
=== modified symlink 'lib/launchpadversioninfo.py'
=== target changed u'../bzr-version-info.py' => u'../version-info.py'
=== modified file 'lib/lp/app/browser/folder.py'
--- lib/lp/app/browser/folder.py 2015-10-26 14:54:43 +0000
+++ lib/lp/app/browser/folder.py 2016-09-14 11:56:46 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
@@ -43,7 +43,7 @@
"""View that gives access to the files in a folder.
The URL to the folder can start with an optional path step like
- /revNNN/ where NNN is one or more digits. This path step will
+ /revNNN/ where NNN is one or more hex digits. This path step will
be ignored. It is useful for having a different path for
all resources being served, to ensure that we don't use cached
files in browsers.
@@ -52,7 +52,7 @@
to True to change this.
"""
- rev_part_re = re.compile('rev\d+$')
+ rev_part_re = re.compile('rev[0-9a-f]+$')
export_subdirectories = False
=== modified file 'lib/lp/app/templates/base-layout-macros.pt'
--- lib/lp/app/templates/base-layout-macros.pt 2016-03-14 00:45:42 +0000
+++ lib/lp/app/templates/base-layout-macros.pt 2016-09-14 11:56:46 +0000
@@ -35,8 +35,8 @@
<metal:load-javascript define-macro="load-javascript"
tal:define="
- revno modules/lp.app.versioninfo/revno | string:unknown;
- icingroot string:/+icing/rev${revno};
+ revision modules/lp.app.versioninfo/revision | string:unknown;
+ icingroot string:/+icing/rev${revision};
combo_url view/combo_url;
devmode modules/lp.services.config/config/devmode;
yui_version view/yui_version;
@@ -109,7 +109,6 @@
<metal:page-javascript define-macro="page-javascript"
tal:define="
- revno modules/lp.app.versioninfo/revno | string:unknown;
devmode modules/lp.services.config/config/devmode;">
<tal:comment replace="nothing">
Load and initialize the common script used by all pages.
@@ -194,8 +193,8 @@
<metal:launchpad-stylesheet-3-0 define-macro="launchpad-stylesheet-3-0"
tal:define="
- revno modules/lp.app.versioninfo/revno | string:unknown;
- icingroot string:/+icing/rev${revno}">
+ revision modules/lp.app.versioninfo/revision | string:unknown;
+ icingroot string:/+icing/rev${revision}">
<tal:comment replace="nothing">
This macro loads a single css file containing all our stylesheets.
If you need to include a new css file here, add it to
@@ -316,7 +315,7 @@
>System status</a>
<span id="lp-version">
•
- r<tal:revno replace="revno" />
+ r<tal:display_revision replace="display_revision" />
<tal:devmode condition="devmode">devmode</tal:devmode>
<tal:demo condition="is_demo">demo site</tal:demo>
(<a href="https://dev.launchpad.net/"
=== modified file 'lib/lp/app/templates/base-layout.pt'
--- lib/lp/app/templates/base-layout.pt 2015-11-21 10:21:42 +0000
+++ lib/lp/app/templates/base-layout.pt 2016-09-14 11:56:46 +0000
@@ -3,13 +3,14 @@
xmlns:tal="http://xml.zope.org/namespaces/tal"
define-macro="master"
tal:define="
- revno modules/lp.app.versioninfo/revno | string:unknown;
+ revision modules/lp.app.versioninfo/revision | string:unknown;
+ display_revision modules/lp.app.versioninfo/display_revision | string:unknown;
devmode modules/lp.services.config/config/devmode;
rooturl modules/lp.services.webapp.vhosts/allvhosts/configs/mainsite/rooturl;
is_demo modules/lp.services.config/config/launchpad/is_demo;
is_lpnet modules/lp.services.config/config/launchpad/is_lpnet;
site_message modules/lp.services.config/config/launchpad/site_message;
- icingroot string:${rooturl}+icing/rev${revno};
+ icingroot string:${rooturl}+icing/rev${revision};
features request/features;
feature_scopes request/features/scopes;
CONTEXTS python:{'template':template, 'context': context, 'view':view};
@@ -182,7 +183,7 @@
Features: ${request/features/usedFlags}
- r${revno}
+ r${display_revision}
-->" />
</tal:template>
=== modified file 'lib/lp/app/templates/oops.pt'
--- lib/lp/app/templates/oops.pt 2011-12-24 17:49:30 +0000
+++ lib/lp/app/templates/oops.pt 2016-09-14 11:56:46 +0000
@@ -6,8 +6,8 @@
>
<head
tal:define="
- revno modules/lp.app.versioninfo/revno | string:unknown;
- icingroot string:/+icing/rev${revno}"
+ revision modules/lp.app.versioninfo/revision | string:unknown;
+ icingroot string:/+icing/rev${revision}"
>
<title>Oops!</title>
<link
=== modified file 'lib/lp/app/tests/test_versioninfo.py'
--- lib/lp/app/tests/test_versioninfo.py 2012-01-01 02:58:52 +0000
+++ lib/lp/app/tests/test_versioninfo.py 2016-09-14 11:56:46 +0000
@@ -1,4 +1,4 @@
-# Copyright 2010 Canonical Ltd. This software is licensed under the
+# Copyright 2010-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
@@ -7,7 +7,7 @@
import subprocess
import unittest
-from lp.app.versioninfo import revno
+from lp.app.versioninfo import revision
from lp.services.config import TREE_ROOT
@@ -17,8 +17,8 @@
# Our cronscripts are executed with cwd != LP root.
# Getting version info should still work in them.
args = [os.path.join(TREE_ROOT, "bin/py"), "-c",
- "from lp.app.versioninfo import revno;"
- "print revno"]
+ "from lp.app.versioninfo import revision;"
+ "print revision"]
process = subprocess.Popen(args, cwd='/tmp', stdout=subprocess.PIPE)
(output, errors) = process.communicate(None)
- self.assertEquals(int(revno), int(output))
+ self.assertEqual(revision, output.rstrip("\n"))
=== modified file 'lib/lp/app/versioninfo.py'
--- lib/lp/app/versioninfo.py 2011-02-18 16:02:56 +0000
+++ lib/lp/app/versioninfo.py 2016-09-14 11:56:46 +0000
@@ -1,23 +1,24 @@
-# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
-"""Give access to bzr and other version info, if available.
+"""Give access to version info, if available.
-The bzr version info file is expected to be in the Launchpad root in the
-file bzr-version-info.py.
+The version info file is expected to be in the Launchpad root in the
+file version-info.py.
From this module, you can get:
versioninfo: the version_info dict
- revno: the revision number
+ revision: the commit ID (Git) or revision number (Bazaar)
+ display_revision: `revision` formatted for display
date: the date of the last revision
branch_nick: the branch nickname
-If the bzr-version-info.py file does not exist, then revno, date and
-branch_nick will all be None.
+If the version-info.py file does not exist, then revision, display_revision,
+date, and branch_nick will all be None.
-If that file exists, and contains valid Python, revno, date and branch_nick
-will have appropriate values from version_info.
+If that file exists, and contains valid Python, revision, display_revision,
+date, and branch_nick will have appropriate values from version_info.
If that file exists, and contains invalid Python, there will be an error when
this module is loaded. This module is imported into lp/app/__init__.py so
@@ -27,7 +28,8 @@
__all__ = [
'branch_nick',
'date',
- 'revno',
+ 'display_revision',
+ 'revision',
'versioninfo',
]
@@ -45,10 +47,16 @@
if versioninfo is None:
- revno = None
+ revision = None
+ display_revision = None
date = None
branch_nick = None
else:
- revno = versioninfo.get('revno')
+ if 'revno' in versioninfo:
+ revision = versioninfo.get('revno')
+ display_revision = revision
+ else:
+ revision = versioninfo.get('revision_id')
+ display_revision = revision[:7]
date = versioninfo.get('date')
branch_nick = versioninfo.get('branch_nick')
=== modified file 'lib/lp/services/mail/sendmail.py'
--- lib/lp/services/mail/sendmail.py 2015-07-21 09:04:01 +0000
+++ lib/lp/services/mail/sendmail.py 2016-09-14 11:56:46 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""The One True Way to send mail from the Launchpad application.
@@ -434,7 +434,7 @@
# Add an X-Generated-By header for easy whitelisting
del message['X-Generated-By']
message['X-Generated-By'] = 'Launchpad (canonical.com)'
- message.set_param('Revision', str(versioninfo.revno), 'X-Generated-By')
+ message.set_param('Revision', str(versioninfo.revision), 'X-Generated-By')
message.set_param('Instance', config.name, 'X-Generated-By')
# Add a shared secret header for pre-approval with Mailman. This approach
=== modified file 'lib/lp/services/webapp/errorlog.py'
--- lib/lp/services/webapp/errorlog.py 2015-12-07 08:24:41 +0000
+++ lib/lp/services/webapp/errorlog.py 2016-09-14 11:56:46 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Error logging facilities."""
@@ -18,7 +18,6 @@
import oops.createhooks
import oops_amqp
from oops_datedir_repo import DateDirRepo
-import oops_datedir_repo.serializer
import oops_timeline
import pytz
from zope.component.interfaces import ObjectEvent
@@ -39,7 +38,6 @@
soft_timeout_expired,
)
from lp.services.webapp.interfaces import (
- IErrorReport,
IErrorReportEvent,
IErrorReportRequest,
IUnloggedException,
@@ -87,40 +85,6 @@
"""A new error report has been created."""
-@implementer(IErrorReport)
-class ErrorReport:
-
- def __init__(self, id, type, value, time, tb_text, username,
- url, duration, req_vars, timeline, informational=None,
- branch_nick=None, revno=None, topic=None, reporter=None):
- self.id = id
- self.type = type
- self.value = value
- self.time = time
- self.topic = topic
- if reporter is not None:
- self.reporter = reporter
- self.tb_text = tb_text
- self.username = username
- self.url = url
- self.duration = duration
- # informational is ignored - will be going from the oops module
- # soon too.
- self.req_vars = req_vars
- self.timeline = timeline
- self.branch_nick = branch_nick or versioninfo.branch_nick
- self.revno = revno or versioninfo.revno
-
- def __repr__(self):
- return '<ErrorReport %s %s: %s>' % (self.id, self.type, self.value)
-
- @classmethod
- def read(cls, fp):
- # Deprecated: use the oops module directly now, when possible.
- report = oops_datedir_repo.serializer.read(fp)
- return cls(**report)
-
-
def notify_publisher(report):
if not report.get('id'):
report['id'] = str(id(report))
@@ -318,7 +282,9 @@
# What do we want in our reports?
# Constants:
self._oops_config.template['branch_nick'] = versioninfo.branch_nick
- self._oops_config.template['revno'] = versioninfo.revno
+ # XXX cjwatson 2016-09-14: This should really be 'revision', but
+ # that requires coordination with python-oops-tools.
+ self._oops_config.template['revno'] = versioninfo.revision
reporter = config[self._default_config_section].oops_prefix
if section_name != self._default_config_section:
reporter = '%s-%s' % (reporter, section_name)
=== modified file 'lib/lp/services/webapp/errorlog.zcml'
--- lib/lp/services/webapp/errorlog.zcml 2013-04-10 09:12:32 +0000
+++ lib/lp/services/webapp/errorlog.zcml 2016-09-14 11:56:46 +0000
@@ -1,4 +1,4 @@
-<!-- Copyright 2009 Canonical Ltd. This software is licensed under the
+<!-- Copyright 2009-2016 Canonical Ltd. This software is licensed under the
GNU Affero General Public License version 3 (see the file LICENSE).
-->
@@ -13,12 +13,6 @@
/>
</class>
- <class class="lp.services.webapp.errorlog.ErrorReport">
- <allow
- interface="lp.services.webapp.interfaces.IErrorReport"
- />
- </class>
-
<utility
provides="zope.error.interfaces.IErrorReportingUtility"
component="lp.services.webapp.errorlog.globalErrorUtility"
=== modified file 'lib/lp/services/webapp/interfaces.py'
--- lib/lp/services/webapp/interfaces.py 2016-02-28 19:13:17 +0000
+++ lib/lp/services/webapp/interfaces.py 2016-09-14 11:56:46 +0000
@@ -701,24 +701,6 @@
"""A new error report has been created."""
-class IErrorReport(Interface):
- id = TextLine(description=u"The name of this error report.")
- type = TextLine(description=u"The type of the exception that occurred.")
- value = TextLine(description=u"The value of the exception that occurred.")
- time = Datetime(description=u"The time at which the exception occurred.")
- pageid = TextLine(
- description=u"""
- The context class plus the page template where the exception
- occurred.
- """)
- branch_nick = TextLine(description=u"The branch nickname.")
- revno = TextLine(description=u"The revision number of the branch.")
- tb_text = Text(description=u"A text version of the traceback.")
- username = TextLine(description=u"The user associated with the request.")
- url = TextLine(description=u"The URL for the failed request.")
- req_vars = Attribute("The request variables.")
-
-
class IErrorReportRequest(Interface):
oopsid = TextLine(
description=u"""an identifier for the exception, or None if no
=== modified file 'lib/lp/services/webapp/publisher.py'
--- lib/lp/services/webapp/publisher.py 2016-02-28 19:13:17 +0000
+++ lib/lp/services/webapp/publisher.py 2016-09-14 11:56:46 +0000
@@ -63,10 +63,10 @@
)
from zope.traversing.browser.interfaces import IAbsoluteURL
+from lp.app import versioninfo
from lp.app.errors import NotFoundError
from lp.app.interfaces.informationtype import IInformationType
from lp.app.interfaces.launchpad import IPrivacy
-from lp.app.versioninfo import revno
from lp.layers import (
LaunchpadLayer,
setFirstLayer,
@@ -412,7 +412,7 @@
from lp.services.config import config
combo_url = '/+combo'
if not config.devmode:
- combo_url += '/rev%s' % revno
+ combo_url += '/rev%s' % versioninfo.revision
return combo_url
def render(self):
=== modified file 'lib/lp/services/webapp/servers.py'
--- lib/lp/services/webapp/servers.py 2016-06-24 11:31:44 +0000
+++ lib/lp/services/webapp/servers.py 2016-09-14 11:56:46 +0000
@@ -602,7 +602,7 @@
'Strict-Transport-Security', 'max-age=15552000')
# Publish revision information.
- self.response.setHeader('X-Launchpad-Revision', versioninfo.revno)
+ self.response.setHeader('X-Launchpad-Revision', versioninfo.revision)
@property
def stepstogo(self):
=== modified file 'lib/lp/services/webapp/tests/test_errorlog.py'
--- lib/lp/services/webapp/tests/test_errorlog.py 2015-07-08 16:05:11 +0000
+++ lib/lp/services/webapp/tests/test_errorlog.py 2016-09-14 11:56:46 +0000
@@ -1,13 +1,11 @@
-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Tests for error logging & OOPS reporting."""
__metaclass__ = type
-import datetime
import httplib
-import StringIO
import sys
from textwrap import dedent
import traceback
@@ -30,7 +28,6 @@
from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
from zope.security.interfaces import Unauthorized
-from lp.app import versioninfo
from lp.app.errors import (
GoneError,
TranslationUnavailable,
@@ -41,7 +38,6 @@
_filter_session_statement,
_is_sensitive,
attach_http_request,
- ErrorReport,
ErrorReportingUtility,
notify_publisher,
ScriptRequest,
@@ -60,79 +56,6 @@
"""Used to test handling of exceptions in OOPS reports."""
-class TestErrorReport(testtools.TestCase):
-
- def test___init__(self):
- """Test ErrorReport.__init__()"""
- entry = ErrorReport('id', 'exc-type', 'exc-value', 'timestamp',
- 'traceback-text', 'username', 'url', 42,
- {'name1': 'value1', 'name2': 'value2',
- 'name3': 'value3'},
- [(1, 5, 'store_a', 'SELECT 1'),
- (5, 10, 'store_b', 'SELECT 2')],
- topic='pageid',
- )
- self.assertEqual(entry.id, 'id')
- self.assertEqual(entry.type, 'exc-type')
- self.assertEqual(entry.value, 'exc-value')
- self.assertEqual(entry.time, 'timestamp')
- self.assertEqual(entry.topic, 'pageid')
- self.assertEqual(entry.branch_nick, versioninfo.branch_nick)
- self.assertEqual(entry.revno, versioninfo.revno)
- self.assertEqual(entry.username, 'username')
- self.assertEqual(entry.url, 'url')
- self.assertEqual(entry.duration, 42)
- self.assertEqual({
- 'name1': 'value1',
- 'name2': 'value2',
- 'name3': 'value3',
- }, entry.req_vars)
- self.assertEqual(len(entry.timeline), 2)
- self.assertEqual(entry.timeline[0], (1, 5, 'store_a', 'SELECT 1'))
- self.assertEqual(entry.timeline[1], (5, 10, 'store_b', 'SELECT 2'))
-
- def test_read(self):
- """Test ErrorReport.read()."""
- # Note: this exists to test the compatibility thunk only.
- fp = StringIO.StringIO(dedent("""\
- Oops-Id: OOPS-A0001
- Exception-Type: NotFound
- Exception-Value: error message
- Date: 2005-04-01T00:00:00+00:00
- Page-Id: IFoo:+foo-template
- User: Sample User
- URL: http://localhost:9000/foo
- Duration: 42
-
- HTTP_USER_AGENT=Mozilla/5.0
- HTTP_REFERER=http://localhost:9000/
- name%3Dfoo=hello%0Aworld
-
- 00001-00005@store_a SELECT 1
- 00005-00010@store_b SELECT 2
-
- traceback-text"""))
- entry = ErrorReport.read(fp)
- self.assertEqual(entry.id, 'OOPS-A0001')
- self.assertEqual(entry.type, 'NotFound')
- self.assertEqual(entry.value, 'error message')
- self.assertEqual(
- entry.time, datetime.datetime(2005, 4, 1, tzinfo=UTC))
- self.assertEqual(entry.topic, 'IFoo:+foo-template')
- self.assertEqual(entry.tb_text, 'traceback-text')
- self.assertEqual(entry.username, 'Sample User')
- self.assertEqual(entry.url, 'http://localhost:9000/foo')
- self.assertEqual(entry.duration, 42)
- self.assertEqual({
- 'HTTP_USER_AGENT': 'Mozilla/5.0',
- 'HTTP_REFERER': 'http://localhost:9000/',
- 'name=foo': 'hello\nworld'},
- entry.req_vars)
- self.assertEqual(len(entry.timeline), 2)
- self.assertEqual(entry.timeline[0], [1, 5, 'store_a', 'SELECT 1'])
- self.assertEqual(entry.timeline[1], [5, 10, 'store_b', 'SELECT 2'])
-
-
class TestErrorReportingUtility(testtools.TestCase):
# want rabbit
=== modified file 'lib/lp/services/webapp/tests/test_servers.py'
--- lib/lp/services/webapp/tests/test_servers.py 2016-06-24 11:31:44 +0000
+++ lib/lp/services/webapp/tests/test_servers.py 2016-09-14 11:56:46 +0000
@@ -386,7 +386,7 @@
def test_baserequest_revision_header(self):
response = LaunchpadBrowserRequest(StringIO.StringIO(''), {}).response
self.assertEqual(
- versioninfo.revno, response.getHeader('X-Launchpad-Revision'))
+ versioninfo.revision, response.getHeader('X-Launchpad-Revision'))
def test_baserequest_recovers_from_bad_path_info_encoding(self):
# The request object recodes PATH_INFO to ensure sane_environment
=== modified file 'lib/lp/services/webhooks/model.py'
--- lib/lp/services/webhooks/model.py 2016-01-19 17:41:11 +0000
+++ lib/lp/services/webhooks/model.py 2016-09-14 11:56:46 +0000
@@ -43,8 +43,8 @@
)
from zope.security.proxy import removeSecurityProxy
+from lp.app import versioninfo
from lp.app.interfaces.security import IAuthorization
-import lp.app.versioninfo
from lp.registry.interfaces.role import IPersonRoles
from lp.registry.model.person import Person
from lp.services.config import config
@@ -488,7 +488,7 @@
transaction.commit()
raise WebhookDeliveryFailure(self.error_message)
user_agent = '%s-Webhooks/r%s' % (
- config.vhost.mainsite.hostname, lp.app.versioninfo.revno)
+ config.vhost.mainsite.hostname, versioninfo.revision)
secret = self.webhook.secret
result = getUtility(IWebhookClient).deliver(
self.webhook.delivery_url, config.webhooks.http_proxy,
=== modified file 'lib/lp/services/webhooks/tests/test_job.py'
--- lib/lp/services/webhooks/tests/test_job.py 2015-11-11 18:12:24 +0000
+++ lib/lp/services/webhooks/tests/test_job.py 2016-09-14 11:56:46 +0000
@@ -1,4 +1,4 @@
-# Copyright 2015 Canonical Ltd. This software is licensed under the
+# Copyright 2015-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Tests for `WebhookJob`s."""
@@ -37,7 +37,7 @@
from zope.component import getUtility
from zope.security.proxy import removeSecurityProxy
-from lp.app.versioninfo import revno
+from lp.app import versioninfo
from lp.services.features.testing import FeatureFixture
from lp.services.job.interfaces.job import JobStatus
from lp.services.job.runner import JobRunner
@@ -371,7 +371,8 @@
self.assertEqual([
('POST', 'http://example.com/ep',
{'Content-Type': 'application/json',
- 'User-Agent': 'launchpad.dev-Webhooks/r%s' % revno,
+ 'User-Agent': 'launchpad.dev-Webhooks/r%s' % (
+ versioninfo.revision),
'X-Launchpad-Event-Type': 'test',
'X-Launchpad-Delivery': str(job.job_id)}),
], reqs)
@@ -386,7 +387,8 @@
self.assertEqual([
('POST', 'http://example.com/ep',
{'Content-Type': 'application/json',
- 'User-Agent': 'launchpad.dev-Webhooks/r%s' % revno,
+ 'User-Agent': 'launchpad.dev-Webhooks/r%s' % (
+ versioninfo.revision),
'X-Hub-Signature':
'sha1=de75f136c37d89f5eb24834468c1ecd602fa95dd',
'X-Launchpad-Event-Type': 'test',
=== modified file 'lib/lp/services/webservice/configuration.py'
--- lib/lp/services/webservice/configuration.py 2012-01-31 01:22:32 +0000
+++ lib/lp/services/webservice/configuration.py 2016-09-14 11:56:46 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""A configuration class describing the Launchpad web service."""
@@ -58,7 +58,7 @@
@property
def code_revision(self):
- return str(versioninfo.revno)
+ return str(versioninfo.revision)
def createRequest(self, body_instream, environ):
"""See `IWebServiceConfiguration`."""
=== modified file 'lib/lp/testing/yuixhr.py'
--- lib/lp/testing/yuixhr.py 2015-07-08 16:05:11 +0000
+++ lib/lp/testing/yuixhr.py 2016-09-14 11:56:46 +0000
@@ -1,4 +1,4 @@
-# Copyright 2011-2013 Canonical Ltd. This software is licensed under the
+# Copyright 2011-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Fixture code for YUITest + XHR integration testing."""
@@ -33,7 +33,7 @@
from zope.security.proxy import removeSecurityProxy
from zope.session.interfaces import IClientIdManager
-from lp.app.versioninfo import revno
+from lp.app import versioninfo
from lp.services.config import config
from lp.services.webapp.interfaces import (
IOpenLaunchBag,
@@ -207,7 +207,7 @@
href="/+yuitest/build/js/yui/console/assets/skins/sam/console.css"/>
<link rel="stylesheet"
href="/+yuitest/build/js/yui/test/assets/skins/sam/test.css"/>
- <link rel="stylesheet" href="/+icing/rev%(revno)s/combo.css"/>
+ <link rel="stylesheet" href="/+icing/rev%(revision)s/combo.css"/>
<script type="text/javascript" src="%(test_module)s"></script>
</head>
<body class="yui3-skin-sam">
@@ -234,7 +234,7 @@
<title>YUI XHR Tests</title>
<link rel="stylesheet"
href="/+icing/yui/assets/skins/sam/skin.css"/>
- <link rel="stylesheet" href="/+icing/rev%(revno)s/combo.css"/>
+ <link rel="stylesheet" href="/+icing/rev%(revision)s/combo.css"/>
<style>
ul {
text-align: left;
@@ -358,7 +358,7 @@
warning = ' <span class="warning">%s</span>' % warning
test_lines.append('<li>%s%s</li>' % (link, warning))
return self.index_template % {
- 'revno': revno,
+ 'revision': versioninfo.revision,
'tests': '\n'.join(test_lines)}
def renderCOMBOFILE(self):
@@ -390,7 +390,7 @@
return self.page_template % dict(
test_module='/+yuitest/%s.js' % self.traversed_path,
test_namespace=self.traversed_path.replace('/', '.'),
- revno=revno,
+ revision=versioninfo.revision,
javascript_block=self.renderYUI())
def renderSETUP(self):
@@ -445,7 +445,7 @@
"""
return self.yui_block_combo % dict(
- revno=revno,
+ revision=versioninfo.revision,
combo_url=self.combo_url)
def render(self):
=== modified file 'lib/lp/translations/utilities/gettext_po_parser.py'
--- lib/lp/translations/utilities/gettext_po_parser.py 2015-07-08 16:05:11 +0000
+++ lib/lp/translations/utilities/gettext_po_parser.py 2016-09-14 11:56:46 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2014 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
# Originally based on code from msgfmt.py (available from python source
@@ -23,7 +23,7 @@
from zope import datetime as zope_datetime
from zope.interface import implementer
-from lp.app.versioninfo import revno
+from lp.app import versioninfo
from lp.translations.interfaces.translationcommonformat import (
ITranslationHeaderData,
)
@@ -352,10 +352,10 @@
elif key == 'x-generator':
# Note the revision number so it would help for debugging
# problems with bad exports.
- if revno is None:
+ if versioninfo.revision is None:
build = 'Unknown'
else:
- build = revno
+ build = versioninfo.revision
raw_content_list.append(
'%s: Launchpad (build %s)\n' % (value, build))
else:
=== renamed file 'scripts/update-bzr-version-info.sh' => 'scripts/update-version-info.sh'
--- scripts/update-bzr-version-info.sh 2009-10-16 01:54:41 +0000
+++ scripts/update-version-info.sh 2016-09-14 11:56:46 +0000
@@ -1,35 +1,57 @@
#!/bin/bash
#
-# Copyright 2009 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
#
-# Update bzr-version-info.py -- but only if the revision number has
+# Update version-info.py -- but only if the revision number has
# changed
#
-if ! which bzr > /dev/null || ! test -x $(which bzr); then
- echo "No working 'bzr' executable found"
+newfile=version-info-${RANDOM}.py
+
+if [ -d .git ]; then
+ branch_nick="$(git rev-parse --abbrev-ref HEAD)"
+ revision_id="$(git rev-parse HEAD)"
+ cat > $newfile <<EOF
+#! /usr/bin/env python
+
+from __future__ import print_function
+
+version_info = {
+ 'branch_nick': u'$branch_nick',
+ 'revision_id': u'$revision_id',
+ }
+
+if __name__ == '__main__':
+ print('revision id: %(revision_id)s' % version_info)
+EOF
+elif [ -d .bzr ]; then
+ if ! which bzr > /dev/null || ! test -x $(which bzr); then
+ echo "No working 'bzr' executable found" >&2
+ exit 1
+ fi
+
+ bzr version-info --format=python > $newfile 2>/dev/null
+else
+ echo "Not in a Git or Bazaar working tree" >&2
exit 1
fi
-newfile=bzr-version-info-${RANDOM}.py
-bzr version-info --format=python > $newfile 2>/dev/null;
-# There's a leading space here that I don't care to trim..
-revno=$(python $newfile | grep revision: | cut -d: -f2)
-if ! [ -f bzr-version-info.py ]; then
- echo "Creating bzr-version-info.py at revno$revno"
- mv ${newfile} bzr-version-info.py
+revision_id=$(python $newfile | sed -n 's/^revision id: //p')
+if ! [ -f version-info.py ]; then
+ echo "Creating version-info.py at revision $revision_id"
+ mv ${newfile} version-info.py
else
# Here we compare the actual output instead of the contents of the
# file because bzr includes a build-date that is actually updated
# every time you run bzr version-info.
newcontents=$(python $newfile)
- oldcontents=$(python bzr-version-info.py)
+ oldcontents=$(python version-info.py)
if [ "$newcontents" != "$oldcontents" ]; then
- echo "Updating bzr-version-info.py to revno$revno"
- mv ${newfile} bzr-version-info.py
+ echo "Updating version-info.py to revision $revision_id"
+ mv ${newfile} version-info.py
else
- echo "Skipping bzr-version-info.py update; already at revno$revno"
+ echo "Skipping version-info.py update; already at revision $revision_id"
rm ${newfile}
fi
fi
=== modified file 'utilities/create-lp-wadl-and-apidoc.py'
--- utilities/create-lp-wadl-and-apidoc.py 2013-04-10 09:27:24 +0000
+++ utilities/create-lp-wadl-and-apidoc.py 2016-09-14 11:56:46 +0000
@@ -1,6 +1,6 @@
#! /usr/bin/python -S
#
-# Copyright 2010 Canonical Ltd. This software is licensed under the
+# Copyright 2010-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Create a static WADL file describing the current webservice.
@@ -15,6 +15,7 @@
from multiprocessing import Process
import optparse
import os
+import subprocess
import sys
import bzrlib
@@ -137,10 +138,16 @@
# Get the time of the last commit. We will use this as the mtime for the
# generated files so that we can safely use it as part of Apache's etag
# generation in the face of multiple servers/filesystems.
- with bzrlib.initialize():
- branch = Branch.open(os.path.dirname(os.path.dirname(__file__)))
- timestamp = branch.repository.get_revision(
- branch.last_revision()).timestamp
+ top = os.path.dirname(os.path.dirname(__file__))
+ if os.path.exists(os.path.join(top, ".git")):
+ timestamp = int(subprocess.check_output(
+ ["git", "log", "-1", "--format=%ct", "HEAD"],
+ universal_newlines=True))
+ else:
+ with bzrlib.initialize():
+ branch = Branch.open(top)
+ timestamp = branch.repository.get_revision(
+ branch.last_revision()).timestamp
# Start a process to build each set of WADL and HTML files.
processes = []
Follow ups