Merge lp:~abentley/launchpad/qa-ready into lp:launchpad

Proposed by Aaron Bentley
Status: Merged
Merged at revision: not available
Proposed branch: lp:~abentley/launchpad/qa-ready
Merge into: lp:launchpad
Diff against target: 93 lines (+89/-0)
1 file modified
utilities/qa-ready (+89/-0)
To merge this branch: bzr merge lp:~abentley/launchpad/qa-ready
Reviewer Review Type Date Requested Status
Paul Hummer (community) code Approve
Review via email: mp+20162@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Aaron Bentley (abentley) wrote :

= Summary =
Implement a script that shows when a branch is ready to be QA-ed.

== Proposed fix ==
This branch provides a new script, qa-ready that shows whether a branch has
been deployed on edge and staging.

== Pre-implementation notes ==
Briefly discussed with Thumper

== Implementation details ==
The revno-determining strategies are stolen from the existing on-edge script.
Because the Launchpad repository has ghosts revisions, bzrlib will look for
them in remote branches. So I've provided a configuration option
"local_location" that lets you specify the local location of your stable and
db-stable branches.

== Tests ==
None

== Demo and Q/A ==
None

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  utilities/qa-ready

Revision history for this message
Paul Hummer (rockstar) wrote :

<rockstar> abentley, I thought there was a page that had only the revno on it. Did that not pan out?
<abentley> rockstar, I don't think there's any such page.
<rockstar> abentley, okay.
<rockstar> abentley, the use of a bzr transport to screen scrape confuses me. What does it provide that a regular urllib or something doesn't?
<rockstar> Also, it sure would be nice if we had a successful-updates.txt for edge.
<rockstar> (not your problem though)
<abentley> rockstar, it respects all the configuration data that bzr does, so if you have proxies or things set up for bzr, those will apply to the transport also.
<rockstar> abentley, ah, okay.
<abentley> rockstar, also, it's familiar, and I don't see any reason *not* to use it.
<rockstar> abentley, that's the reason I would have suspected, but the former is also a very good reason.
<rockstar> s/suspected/expected/
<rockstar> abentley, was there a technical reason is_present appears after main?
<abentley> rockstar, no.
<rockstar> abentley, so, it's not a big deal, but I usually expect functions to be defined before I see the calls. It's still valid python, but hard to follow. Would you mind just bumping is_present above main?
<abentley> rockstar, sure.
<rockstar> abentley, r=rockstar

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'utilities/qa-ready'
2--- utilities/qa-ready 1970-01-01 00:00:00 +0000
3+++ utilities/qa-ready 2010-02-25 19:13:18 +0000
4@@ -0,0 +1,89 @@
5+#!/usr/bin/python2.5
6+#
7+# Copyright 2010 Canonical Ltd. This software is licensed under the
8+# GNU Affero General Public License version 3 (see the file LICENSE).
9+
10+import re
11+import sys
12+
13+from bzrlib.branch import Branch
14+from bzrlib.config import LocationConfig
15+from bzrlib.transport import get_transport
16+
17+
18+class UsageError(Exception):
19+ """Raised when the user makes a dumb error."""
20+
21+
22+def get_staging_revision():
23+ """Get the revision of db-stable deployed on staging.
24+
25+ :return: The staging revno as an int. Corresponds to a revision of
26+ lp:launchpad/db-stable.
27+ """
28+ t = get_transport('https://staging.launchpad.net/')
29+ last_line = t.get_bytes('successful-updates.txt').splitlines()[-1]
30+ return int(last_line.split()[-1])
31+
32+
33+def get_edge_revision():
34+ """Get the revision of stable deployed on edge.
35+
36+ :return: The edge revno as an int. Corresponds to a revision of
37+ lp:launchpad/stable.
38+ """
39+ t = get_transport('https://edge.launchpad.net/')
40+ html = t.get_bytes('index.html')
41+ revision_re = re.compile(r'\(r(\d+)\)')
42+ for line in html.splitlines():
43+ matches = revision_re.search(line)
44+ if matches:
45+ return int(matches.group(1))
46+ raise ValueError("Could not find revision number on edge home page")
47+
48+
49+def is_present(local_branch, deployed_location, deployed_revno):
50+ local_mirror = LocationConfig(deployed_location).get_user_option(
51+ 'local_location')
52+ if local_mirror is None:
53+ print (
54+ 'Please configure a local_location for %s in locations.conf '
55+ 'to improve performance.' % deployed_location)
56+ deployed_branch = Branch.open(deployed_location)
57+ else:
58+ deployed_branch = Branch.open(local_mirror)
59+ deployed_branch.lock_read()
60+ try:
61+ deployed_rev_id = deployed_branch.get_rev_id(deployed_revno)
62+ graph = local_branch.repository.get_graph(deployed_branch.repository)
63+ return graph.is_ancestor(local_branch.last_revision(), deployed_rev_id)
64+ finally:
65+ deployed_branch.unlock()
66+
67+
68+
69+stable = 'bzr+ssh://bazaar.launchpad.net/~launchpad-pqm/launchpad/stable'
70+dbstable = 'bzr+ssh://bazaar.launchpad.net/~launchpad-pqm/launchpad/db-stable'
71+def main(argv):
72+ if len(sys.argv) > 1:
73+ location = sys.argv[1]
74+ else:
75+ location = '.'
76+ b = Branch.open_containing(location)[0]
77+ b.lock_read()
78+ try:
79+ print 'Branch: %s' % b.base
80+ print 'Deployed on edge: %s' % is_present(
81+ b, stable, get_edge_revision())
82+ print 'Deployed on staging: %s' % is_present(
83+ b, dbstable, get_staging_revision())
84+ finally:
85+ b.unlock()
86+
87+
88+if __name__ == '__main__':
89+ try:
90+ sys.exit(main(sys.argv[1:]))
91+ except UsageError, e:
92+ print 'ERROR: %s' % e
93+ sys.exit(1)