launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #18172
[Merge] lp:~cjwatson/launchpad/git-ref-ui into lp:launchpad
Colin Watson has proposed merging lp:~cjwatson/launchpad/git-ref-ui into lp:launchpad with lp:~cjwatson/launchpad/git-ref-scanner-commits as a prerequisite.
Commit message:
Add a git sprite. Flesh out GitRef:+index a little bit, and add a branch listing to GitRepository:+index.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #1032731 in Launchpad itself: "Support for Launchpad-hosted Git repositories"
https://bugs.launchpad.net/launchpad/+bug/1032731
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/git-ref-ui/+merge/253550
Add a git sprite. Flesh out GitRef:+index a little bit, and add a branch listing to GitRepository:+index.
This is still pretty basic, but is functional. There are a couple of screenshots here:
https://bugs.launchpad.net/launchpad/+bug/1032731/+attachment/4350129/+files/gitref-listing-grub.png
https://bugs.launchpad.net/launchpad/+bug/1032731/+attachment/4350130/+files/gitref-index-grub.png
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/git-ref-ui into lp:launchpad.
=== modified file 'LICENSE'
--- LICENSE 2015-01-30 10:13:51 +0000
+++ LICENSE 2015-03-19 17:09:23 +0000
@@ -13,6 +13,11 @@
The Launchpad name and logo are trademarks of Canonical, and may not
be used without the prior written permission of Canonical.
+The Git logo in lib/canonical/launchpad/images/src/git.eps and
+lib/canonical/launchpad/images/git.png is copyright Jason Long, and is
+licensed under the Creative Commons Attribution 3.0 Unported License (CC BY
+3.0), reproduced in the LICENSE.CC-BY-3.0 file.
+
Third-party copyright in this distribution is noted where applicable.
All rights not expressly granted are reserved.
=== added file 'LICENSE.CC-BY-3.0'
--- LICENSE.CC-BY-3.0 1970-01-01 00:00:00 +0000
+++ LICENSE.CC-BY-3.0 2015-03-19 17:09:23 +0000
@@ -0,0 +1,331 @@
+The Git logo in lib/canonical/launchpad/images/src/git.eps and
+lib/canonical/launchpad/images/git.png is copyright Jason Long, and is
+licensed under the Creative Commons Attribution 3.0 Unported License (CC BY
+3.0), reproduced below.
+
+This does not apply to other files in Launchpad. For those, see the LICENSE
+file.
+
+=========================================================================
+
+Creative Commons Legal Code
+
+Attribution 3.0 Unported
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+ REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
+ DAMAGES RESULTING FROM ITS USE.
+
+License
+
+THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
+COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
+COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
+AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+
+BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
+TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
+BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
+CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
+CONDITIONS.
+
+1. Definitions
+
+ a. "Adaptation" means a work based upon the Work, or upon the Work and
+ other pre-existing works, such as a translation, adaptation,
+ derivative work, arrangement of music or other alterations of a
+ literary or artistic work, or phonogram or performance and includes
+ cinematographic adaptations or any other form in which the Work may be
+ recast, transformed, or adapted including in any form recognizably
+ derived from the original, except that a work that constitutes a
+ Collection will not be considered an Adaptation for the purpose of
+ this License. For the avoidance of doubt, where the Work is a musical
+ work, performance or phonogram, the synchronization of the Work in
+ timed-relation with a moving image ("synching") will be considered an
+ Adaptation for the purpose of this License.
+ b. "Collection" means a collection of literary or artistic works, such as
+ encyclopedias and anthologies, or performances, phonograms or
+ broadcasts, or other works or subject matter other than works listed
+ in Section 1(f) below, which, by reason of the selection and
+ arrangement of their contents, constitute intellectual creations, in
+ which the Work is included in its entirety in unmodified form along
+ with one or more other contributions, each constituting separate and
+ independent works in themselves, which together are assembled into a
+ collective whole. A work that constitutes a Collection will not be
+ considered an Adaptation (as defined above) for the purposes of this
+ License.
+ c. "Distribute" means to make available to the public the original and
+ copies of the Work or Adaptation, as appropriate, through sale or
+ other transfer of ownership.
+ d. "Licensor" means the individual, individuals, entity or entities that
+ offer(s) the Work under the terms of this License.
+ e. "Original Author" means, in the case of a literary or artistic work,
+ the individual, individuals, entity or entities who created the Work
+ or if no individual or entity can be identified, the publisher; and in
+ addition (i) in the case of a performance the actors, singers,
+ musicians, dancers, and other persons who act, sing, deliver, declaim,
+ play in, interpret or otherwise perform literary or artistic works or
+ expressions of folklore; (ii) in the case of a phonogram the producer
+ being the person or legal entity who first fixes the sounds of a
+ performance or other sounds; and, (iii) in the case of broadcasts, the
+ organization that transmits the broadcast.
+ f. "Work" means the literary and/or artistic work offered under the terms
+ of this License including without limitation any production in the
+ literary, scientific and artistic domain, whatever may be the mode or
+ form of its expression including digital form, such as a book,
+ pamphlet and other writing; a lecture, address, sermon or other work
+ of the same nature; a dramatic or dramatico-musical work; a
+ choreographic work or entertainment in dumb show; a musical
+ composition with or without words; a cinematographic work to which are
+ assimilated works expressed by a process analogous to cinematography;
+ a work of drawing, painting, architecture, sculpture, engraving or
+ lithography; a photographic work to which are assimilated works
+ expressed by a process analogous to photography; a work of applied
+ art; an illustration, map, plan, sketch or three-dimensional work
+ relative to geography, topography, architecture or science; a
+ performance; a broadcast; a phonogram; a compilation of data to the
+ extent it is protected as a copyrightable work; or a work performed by
+ a variety or circus performer to the extent it is not otherwise
+ considered a literary or artistic work.
+ g. "You" means an individual or entity exercising rights under this
+ License who has not previously violated the terms of this License with
+ respect to the Work, or who has received express permission from the
+ Licensor to exercise rights under this License despite a previous
+ violation.
+ h. "Publicly Perform" means to perform public recitations of the Work and
+ to communicate to the public those public recitations, by any means or
+ process, including by wire or wireless means or public digital
+ performances; to make available to the public Works in such a way that
+ members of the public may access these Works from a place and at a
+ place individually chosen by them; to perform the Work to the public
+ by any means or process and the communication to the public of the
+ performances of the Work, including by public digital performance; to
+ broadcast and rebroadcast the Work by any means including signs,
+ sounds or images.
+ i. "Reproduce" means to make copies of the Work by any means including
+ without limitation by sound or visual recordings and the right of
+ fixation and reproducing fixations of the Work, including storage of a
+ protected performance or phonogram in digital form or other electronic
+ medium.
+
+2. Fair Dealing Rights. Nothing in this License is intended to reduce,
+limit, or restrict any uses free from copyright or rights arising from
+limitations or exceptions that are provided for in connection with the
+copyright protection under copyright law or other applicable laws.
+
+3. License Grant. Subject to the terms and conditions of this License,
+Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
+perpetual (for the duration of the applicable copyright) license to
+exercise the rights in the Work as stated below:
+
+ a. to Reproduce the Work, to incorporate the Work into one or more
+ Collections, and to Reproduce the Work as incorporated in the
+ Collections;
+ b. to create and Reproduce Adaptations provided that any such Adaptation,
+ including any translation in any medium, takes reasonable steps to
+ clearly label, demarcate or otherwise identify that changes were made
+ to the original Work. For example, a translation could be marked "The
+ original work was translated from English to Spanish," or a
+ modification could indicate "The original work has been modified.";
+ c. to Distribute and Publicly Perform the Work including as incorporated
+ in Collections; and,
+ d. to Distribute and Publicly Perform Adaptations.
+ e. For the avoidance of doubt:
+
+ i. Non-waivable Compulsory License Schemes. In those jurisdictions in
+ which the right to collect royalties through any statutory or
+ compulsory licensing scheme cannot be waived, the Licensor
+ reserves the exclusive right to collect such royalties for any
+ exercise by You of the rights granted under this License;
+ ii. Waivable Compulsory License Schemes. In those jurisdictions in
+ which the right to collect royalties through any statutory or
+ compulsory licensing scheme can be waived, the Licensor waives the
+ exclusive right to collect such royalties for any exercise by You
+ of the rights granted under this License; and,
+ iii. Voluntary License Schemes. The Licensor waives the right to
+ collect royalties, whether individually or, in the event that the
+ Licensor is a member of a collecting society that administers
+ voluntary licensing schemes, via that society, from any exercise
+ by You of the rights granted under this License.
+
+The above rights may be exercised in all media and formats whether now
+known or hereafter devised. The above rights include the right to make
+such modifications as are technically necessary to exercise the rights in
+other media and formats. Subject to Section 8(f), all rights not expressly
+granted by Licensor are hereby reserved.
+
+4. Restrictions. The license granted in Section 3 above is expressly made
+subject to and limited by the following restrictions:
+
+ a. You may Distribute or Publicly Perform the Work only under the terms
+ of this License. You must include a copy of, or the Uniform Resource
+ Identifier (URI) for, this License with every copy of the Work You
+ Distribute or Publicly Perform. You may not offer or impose any terms
+ on the Work that restrict the terms of this License or the ability of
+ the recipient of the Work to exercise the rights granted to that
+ recipient under the terms of the License. You may not sublicense the
+ Work. You must keep intact all notices that refer to this License and
+ to the disclaimer of warranties with every copy of the Work You
+ Distribute or Publicly Perform. When You Distribute or Publicly
+ Perform the Work, You may not impose any effective technological
+ measures on the Work that restrict the ability of a recipient of the
+ Work from You to exercise the rights granted to that recipient under
+ the terms of the License. This Section 4(a) applies to the Work as
+ incorporated in a Collection, but this does not require the Collection
+ apart from the Work itself to be made subject to the terms of this
+ License. If You create a Collection, upon notice from any Licensor You
+ must, to the extent practicable, remove from the Collection any credit
+ as required by Section 4(b), as requested. If You create an
+ Adaptation, upon notice from any Licensor You must, to the extent
+ practicable, remove from the Adaptation any credit as required by
+ Section 4(b), as requested.
+ b. If You Distribute, or Publicly Perform the Work or any Adaptations or
+ Collections, You must, unless a request has been made pursuant to
+ Section 4(a), keep intact all copyright notices for the Work and
+ provide, reasonable to the medium or means You are utilizing: (i) the
+ name of the Original Author (or pseudonym, if applicable) if supplied,
+ and/or if the Original Author and/or Licensor designate another party
+ or parties (e.g., a sponsor institute, publishing entity, journal) for
+ attribution ("Attribution Parties") in Licensor's copyright notice,
+ terms of service or by other reasonable means, the name of such party
+ or parties; (ii) the title of the Work if supplied; (iii) to the
+ extent reasonably practicable, the URI, if any, that Licensor
+ specifies to be associated with the Work, unless such URI does not
+ refer to the copyright notice or licensing information for the Work;
+ and (iv) , consistent with Section 3(b), in the case of an Adaptation,
+ a credit identifying the use of the Work in the Adaptation (e.g.,
+ "French translation of the Work by Original Author," or "Screenplay
+ based on original Work by Original Author"). The credit required by
+ this Section 4 (b) may be implemented in any reasonable manner;
+ provided, however, that in the case of a Adaptation or Collection, at
+ a minimum such credit will appear, if a credit for all contributing
+ authors of the Adaptation or Collection appears, then as part of these
+ credits and in a manner at least as prominent as the credits for the
+ other contributing authors. For the avoidance of doubt, You may only
+ use the credit required by this Section for the purpose of attribution
+ in the manner set out above and, by exercising Your rights under this
+ License, You may not implicitly or explicitly assert or imply any
+ connection with, sponsorship or endorsement by the Original Author,
+ Licensor and/or Attribution Parties, as appropriate, of You or Your
+ use of the Work, without the separate, express prior written
+ permission of the Original Author, Licensor and/or Attribution
+ Parties.
+ c. Except as otherwise agreed in writing by the Licensor or as may be
+ otherwise permitted by applicable law, if You Reproduce, Distribute or
+ Publicly Perform the Work either by itself or as part of any
+ Adaptations or Collections, You must not distort, mutilate, modify or
+ take other derogatory action in relation to the Work which would be
+ prejudicial to the Original Author's honor or reputation. Licensor
+ agrees that in those jurisdictions (e.g. Japan), in which any exercise
+ of the right granted in Section 3(b) of this License (the right to
+ make Adaptations) would be deemed to be a distortion, mutilation,
+ modification or other derogatory action prejudicial to the Original
+ Author's honor and reputation, the Licensor will waive or not assert,
+ as appropriate, this Section, to the fullest extent permitted by the
+ applicable national law, to enable You to reasonably exercise Your
+ right under Section 3(b) of this License (right to make Adaptations)
+ but not otherwise.
+
+5. Representations, Warranties and Disclaimer
+
+UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
+OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
+KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
+INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
+FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
+LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
+WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION
+OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
+
+6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
+LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
+ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
+ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. Termination
+
+ a. This License and the rights granted hereunder will terminate
+ automatically upon any breach by You of the terms of this License.
+ Individuals or entities who have received Adaptations or Collections
+ from You under this License, however, will not have their licenses
+ terminated provided such individuals or entities remain in full
+ compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
+ survive any termination of this License.
+ b. Subject to the above terms and conditions, the license granted here is
+ perpetual (for the duration of the applicable copyright in the Work).
+ Notwithstanding the above, Licensor reserves the right to release the
+ Work under different license terms or to stop distributing the Work at
+ any time; provided, however that any such election will not serve to
+ withdraw this License (or any other license that has been, or is
+ required to be, granted under the terms of this License), and this
+ License will continue in full force and effect unless terminated as
+ stated above.
+
+8. Miscellaneous
+
+ a. Each time You Distribute or Publicly Perform the Work or a Collection,
+ the Licensor offers to the recipient a license to the Work on the same
+ terms and conditions as the license granted to You under this License.
+ b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
+ offers to the recipient a license to the original Work on the same
+ terms and conditions as the license granted to You under this License.
+ c. If any provision of this License is invalid or unenforceable under
+ applicable law, it shall not affect the validity or enforceability of
+ the remainder of the terms of this License, and without further action
+ by the parties to this agreement, such provision shall be reformed to
+ the minimum extent necessary to make such provision valid and
+ enforceable.
+ d. No term or provision of this License shall be deemed waived and no
+ breach consented to unless such waiver or consent shall be in writing
+ and signed by the party to be charged with such waiver or consent.
+ e. This License constitutes the entire agreement between the parties with
+ respect to the Work licensed here. There are no understandings,
+ agreements or representations with respect to the Work not specified
+ here. Licensor shall not be bound by any additional provisions that
+ may appear in any communication from You. This License may not be
+ modified without the mutual written agreement of the Licensor and You.
+ f. The rights granted under, and the subject matter referenced, in this
+ License were drafted utilizing the terminology of the Berne Convention
+ for the Protection of Literary and Artistic Works (as amended on
+ September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
+ Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996
+ and the Universal Copyright Convention (as revised on July 24, 1971).
+ These rights and subject matter take effect in the relevant
+ jurisdiction in which the License terms are sought to be enforced
+ according to the corresponding provisions of the implementation of
+ those treaty provisions in the applicable national law. If the
+ standard suite of rights granted under applicable copyright law
+ includes additional rights not granted under this License, such
+ additional rights are deemed to be included in the License; this
+ License is not intended to restrict the license of any rights under
+ applicable law.
+
+
+Creative Commons Notice
+
+ Creative Commons is not a party to this License, and makes no warranty
+ whatsoever in connection with the Work. Creative Commons will not be
+ liable to You or any party on any legal theory for any damages
+ whatsoever, including without limitation any general, special,
+ incidental or consequential damages arising in connection to this
+ license. Notwithstanding the foregoing two (2) sentences, if Creative
+ Commons has expressly identified itself as the Licensor hereunder, it
+ shall have all rights and obligations of Licensor.
+
+ Except for the limited purpose of indicating to the public that the
+ Work is licensed under the CCPL, Creative Commons does not authorize
+ the use by either party of the trademark "Creative Commons" or any
+ related trademark or logo of Creative Commons without the prior
+ written consent of Creative Commons. Any permitted use will be in
+ compliance with Creative Commons' then-current trademark usage
+ guidelines, as may be published on its website or otherwise made
+ available upon request from time to time. For the avoidance of doubt,
+ this trademark restriction does not form part of this License.
+
+ Creative Commons may be contacted at https://creativecommons.org/.
+
+=========================================================================
=== modified file 'lib/canonical/launchpad/icing/inline-sprites-1.css.in'
--- lib/canonical/launchpad/icing/inline-sprites-1.css.in 2012-07-08 16:42:08 +0000
+++ lib/canonical/launchpad/icing/inline-sprites-1.css.in 2015-03-19 17:09:23 +0000
@@ -85,6 +85,10 @@
background-image: url(/@@/branch.png); /* sprite-ref: icon-sprites */
background-repeat: no-repeat;
}
+.git {
+ background-image: url(/@@/git.png); /* sprite-ref: icon-sprites */
+ background-repeat: no-repeat;
+ }
.distribution {
background-image: url(/@@/distribution.png); /* sprite-ref: icon-sprites */
background-repeat: no-repeat;
=== added file 'lib/canonical/launchpad/images/git.png'
Binary files lib/canonical/launchpad/images/git.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/git.png 2015-03-19 17:09:23 +0000 differ
=== added file 'lib/canonical/launchpad/images/src/git.eps'
Binary files lib/canonical/launchpad/images/src/git.eps 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/src/git.eps 2015-03-19 17:09:23 +0000 differ
=== modified file 'lib/lp/app/browser/tales.py'
--- lib/lp/app/browser/tales.py 2015-03-17 16:22:56 +0000
+++ lib/lp/app/browser/tales.py 2015-03-19 17:09:23 +0000
@@ -61,6 +61,7 @@
from lp.bugs.interfaces.bug import IBug
from lp.buildmaster.enums import BuildStatus
from lp.code.interfaces.branch import IBranch
+from lp.code.interfaces.gitrepository import IGitRepository
from lp.layers import LaunchpadLayer
from lp.registry.interfaces.distribution import IDistribution
from lp.registry.interfaces.distributionsourcepackage import (
@@ -767,6 +768,8 @@
sprite_string = 'distribution'
elif IBranch.providedBy(context):
sprite_string = 'branch'
+ elif IGitRepository.providedBy(context):
+ sprite_string = 'git'
elif ISpecification.providedBy(context):
sprite_string = 'blueprint'
elif IBinaryAndSourcePackageName.providedBy(context):
=== modified file 'lib/lp/app/doc/tales.txt'
--- lib/lp/app/doc/tales.txt 2015-03-13 14:13:53 +0000
+++ lib/lp/app/doc/tales.txt 2015-03-19 17:09:23 +0000
@@ -532,7 +532,8 @@
... repository = factory.makeGitRepository(
... owner=eric, target=fooix, name=u'bar')
... print test_tales("repository/fmt:link", repository=repository)
- <a href=".../~eric/fooix/+git/bar">lp:~eric/fooix/+git/bar</a>
+ <a href=".../~eric/fooix/+git/bar"
+ class="sprite git">lp:~eric/fooix/+git/bar</a>
Bugs
=== modified file 'lib/lp/code/browser/configure.zcml'
--- lib/lp/code/browser/configure.zcml 2015-03-13 14:15:24 +0000
+++ lib/lp/code/browser/configure.zcml 2015-03-19 17:09:23 +0000
@@ -806,12 +806,27 @@
path_expression="string:+ref/${path}"
attribute_to_parent="repository"
rootsite="code"/>
- <browser:page
+ <browser:pages
for="lp.code.interfaces.gitref.IGitRef"
class="lp.code.browser.gitref.GitRefView"
- permission="launchpad.View"
- name="+index"
- template="../templates/gitref-index.pt"/>
+ permission="launchpad.View">
+ <browser:page
+ name="+index"
+ template="../templates/gitref-index.pt"/>
+ <browser:page
+ name="++ref-commits"
+ template="../templates/gitref-commits.pt"/>
+ </browser:pages>
+ <browser:page
+ for="lp.code.interfaces.gitref.IGitRef"
+ name="+macros"
+ permission="zope.Public"
+ template="../templates/gitref-macros.pt"/>
+ <browser:page
+ for="lp.code.interfaces.gitref.IGitRefBatchNavigator"
+ permission="zope.Public"
+ name="+ref-listing"
+ template="../templates/gitref-listing.pt"/>
<browser:menus
classes="ProductBranchesMenu"
=== modified file 'lib/lp/code/browser/gitref.py'
--- lib/lp/code/browser/gitref.py 2015-03-13 14:15:24 +0000
+++ lib/lp/code/browser/gitref.py 2015-03-19 17:09:23 +0000
@@ -17,3 +17,12 @@
@property
def label(self):
return self.context.display_name
+
+ @property
+ def tip_commit_info(self):
+ return {
+ "sha1": self.context.commit_sha1,
+ "author": self.context.author,
+ "author_date": self.context.author_date,
+ "commit_message": self.context.commit_message,
+ }
=== modified file 'lib/lp/code/browser/gitrepository.py'
--- lib/lp/code/browser/gitrepository.py 2015-03-13 14:15:24 +0000
+++ lib/lp/code/browser/gitrepository.py 2015-03-19 17:09:23 +0000
@@ -18,6 +18,7 @@
from lp.app.browser.informationtype import InformationTypePortletMixin
from lp.app.errors import NotFoundError
+from lp.code.interfaces.gitref import IGitRefBatchNavigator
from lp.code.interfaces.gitrepository import IGitRepository
from lp.services.config import config
from lp.services.webapp import (
@@ -31,6 +32,7 @@
check_permission,
precache_permission_for_objects,
)
+from lp.services.webapp.batching import TableBatchNavigator
from lp.services.webapp.breadcrumb import NameBreadcrumb
from lp.services.webapp.interfaces import ICanonicalUrlData
@@ -90,6 +92,28 @@
return Link(url, text, icon="info")
+class GitRefBatchNavigator(TableBatchNavigator):
+ """Batch up the branch listings."""
+ implements(IGitRefBatchNavigator)
+
+ def __init__(self, view):
+ super(GitRefBatchNavigator, self).__init__(
+ view.context.branches, view.request,
+ size=config.launchpad.branchlisting_batch_size)
+ self.view = view
+ self.column_count = 3
+
+ @property
+ def table_class(self):
+ # XXX: MichaelHudson 2007-10-18 bug=153894: This means there are two
+ # ways of sorting a one-page branch listing, which is confusing and
+ # incoherent.
+ if self.has_multiple_pages:
+ return "listing"
+ else:
+ return "listing sortable"
+
+
class GitRepositoryView(InformationTypePortletMixin, LaunchpadView):
@property
@@ -128,3 +152,7 @@
def user_can_push(self):
"""Whether the user can push to this branch."""
return check_permission("launchpad.Edit", self.context)
+
+ def branches(self):
+ """All branches in this repository, sorted for display."""
+ return GitRefBatchNavigator(self)
=== modified file 'lib/lp/code/interfaces/gitref.py'
--- lib/lp/code/interfaces/gitref.py 2015-03-19 17:09:23 +0000
+++ lib/lp/code/interfaces/gitref.py 2015-03-19 17:09:23 +0000
@@ -22,6 +22,7 @@
from lp import _
from lp.code.enums import GitObjectType
+from lp.services.webapp.interfaces import ITableBatchNavigator
class IGitRef(Interface):
@@ -65,3 +66,11 @@
display_name = TextLine(
title=_("Display name"), required=True, readonly=True,
description=_("Display name of the reference."))
+
+ commit_message_first_line = TextLine(
+ title=_("The first line of the commit message."),
+ required=True, readonly=True)
+
+
+class IGitRefBatchNavigator(ITableBatchNavigator):
+ pass
=== modified file 'lib/lp/code/interfaces/gitrepository.py'
--- lib/lp/code/interfaces/gitrepository.py 2015-03-19 17:09:23 +0000
+++ lib/lp/code/interfaces/gitrepository.py 2015-03-19 17:09:23 +0000
@@ -188,6 +188,8 @@
refs = Attribute("The references present in this repository.")
+ branches = Attribute("The branch references present in this repository.")
+
def getRefByPath(path):
"""Look up a single reference in this repository by path.
=== modified file 'lib/lp/code/model/gitref.py'
--- lib/lp/code/model/gitref.py 2015-03-19 17:09:23 +0000
+++ lib/lp/code/model/gitref.py 2015-03-19 17:09:23 +0000
@@ -53,3 +53,7 @@
@property
def display_name(self):
return self.path.split("/", 2)[-1]
+
+ @property
+ def commit_message_first_line(self):
+ return self.commit_message.split("\n", 1)[0]
=== modified file 'lib/lp/code/model/gitrepository.py'
--- lib/lp/code/model/gitrepository.py 2015-03-19 17:09:23 +0000
+++ lib/lp/code/model/gitrepository.py 2015-03-19 17:09:23 +0000
@@ -311,8 +311,16 @@
@cachedproperty
def refs(self):
"""See `IGitRepository`."""
- return list(Store.of(self).find(
- GitRef, GitRef.repository_id == self.id).order_by(GitRef.path))
+ return Store.of(self).find(
+ GitRef, GitRef.repository_id == self.id).order_by(GitRef.path)
+
+ @cachedproperty
+ def branches(self):
+ """See `IGitRepository`."""
+ return Store.of(self).find(
+ GitRef,
+ GitRef.repository_id == self.id,
+ GitRef.path.startswith(u"refs/heads/")).order_by(GitRef.path)
def getRefByPath(self, path):
return Store.of(self).find(
@@ -414,6 +422,7 @@
created = []
del get_property_cache(self).refs
+ del get_property_cache(self).branches
if get_objects:
return bulk.load(GitRef, updated + created)
@@ -423,6 +432,7 @@
GitRef,
GitRef.repository == self, GitRef.path.is_in(paths)).remove()
del get_property_cache(self).refs
+ del get_property_cache(self).branches
def planRefChanges(self, hosting_client, hosting_path, logger=None):
"""See `IGitRepository`."""
=== modified file 'lib/lp/code/model/tests/test_gitjob.py'
--- lib/lp/code/model/tests/test_gitjob.py 2015-03-19 17:09:23 +0000
+++ lib/lp/code/model/tests/test_gitjob.py 2015-03-19 17:09:23 +0000
@@ -154,7 +154,7 @@
with self.expectedLog(expected_message):
with dbuser("branchscanner"):
job.run()
- self.assertEqual([], repository.refs)
+ self.assertEqual([], list(repository.refs))
# XXX cjwatson 2015-03-12: We should test that the job works via Celery too,
=== modified file 'lib/lp/code/model/tests/test_gitrepository.py'
--- lib/lp/code/model/tests/test_gitrepository.py 2015-03-19 17:09:23 +0000
+++ lib/lp/code/model/tests/test_gitrepository.py 2015-03-19 17:09:23 +0000
@@ -482,7 +482,7 @@
def test_create(self):
repository = self.factory.makeGitRepository()
- self.assertEqual([], repository.refs)
+ self.assertEqual([], list(repository.refs))
paths = (u"refs/heads/master", u"refs/tags/1.0")
self.factory.makeGitRefs(repository=repository, paths=paths)
self.assertRefsMatch(repository.refs, repository, paths)
=== added file 'lib/lp/code/templates/gitref-commits.pt'
--- lib/lp/code/templates/gitref-commits.pt 1970-01-01 00:00:00 +0000
+++ lib/lp/code/templates/gitref-commits.pt 2015-03-19 17:09:23 +0000
@@ -0,0 +1,27 @@
+<div
+ xmlns:tal="http://xml.zope.org/namespaces/tal"
+ xmlns:metal="http://xml.zope.org/namespaces/metal"
+ xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+
+ <p tal:condition="not: context/committer_date">
+ <metal:no-commit-message use-macro="context/@@+macros/no-commit-message" />
+ </p>
+
+ <tal:has_commit condition="context/committer_date">
+ <style type="text/css">
+ .subordinate {
+ margin-left: 1em;
+ }
+ </style>
+ <dl class="revision">
+ <tal:comment condition="nothing">
+ XXX cjwatson 2015-03-19: This should display more commits once we
+ have them. For now, we only have the tip commit.
+ </tal:comment>
+ <tal:tip define="commit_info view/tip_commit_info">
+ <metal:commit-text use-macro="context/@@+macros/commit-text" />
+ </tal:tip>
+ </dl>
+ </tal:has_commit>
+
+</div>
=== modified file 'lib/lp/code/templates/gitref-index.pt'
--- lib/lp/code/templates/gitref-index.pt 2015-03-13 14:15:24 +0000
+++ lib/lp/code/templates/gitref-index.pt 2015-03-19 17:09:23 +0000
@@ -9,6 +9,11 @@
<body>
+<tal:registering metal:fill-slot="registering">
+ Last commit made on
+ <tal:committer-date replace="structure context/committer_date/fmt:date" />
+</tal:registering>
+
<div metal:fill-slot="main">
<div class="yui-g">
@@ -28,6 +33,13 @@
</div>
</div>
+ <div class="yui-g">
+ <div class="portlet" id="recent-commits">
+ <h2>Recent commits</h2>
+ <tal:commits replace="structure context/@@++ref-commits" />
+ </div>
+ </div>
+
</div>
</body>
=== added file 'lib/lp/code/templates/gitref-listing.pt'
--- lib/lp/code/templates/gitref-listing.pt 1970-01-01 00:00:00 +0000
+++ lib/lp/code/templates/gitref-listing.pt 2015-03-19 17:09:23 +0000
@@ -0,0 +1,84 @@
+<script type="text/javascript">
+function show_git_commit(id) {
+ var div = document.getElementById('git-ref-' + id);
+ if (div) {
+ div.style.display = "block";
+ }
+}
+function hide_git_commit(id) {
+ var div = document.getElementById('git-ref-' + id);
+ if (div) {
+ div.style.display = "none";
+ }
+}
+</script>
+
+<div
+ xmlns:tal="http://xml.zope.org/namespaces/tal"
+ xmlns:metal="http://xml.zope.org/namespaces/metal"
+ xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+
+ <tal:needs-batch condition="context/has_multiple_pages">
+ <div id="branch-batch-links">
+ <tal:navigation replace="structure context/@@+navigation-links-upper" />
+ </div>
+ </tal:needs-batch>
+
+ <table tal:attributes="class context/table_class" id="branchtable">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Last Modified</th>
+ <th>Last Commit</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr tal:repeat="ref context/currentBatch">
+ <td>
+ <a tal:attributes="href ref/fmt:url"
+ tal:content="structure ref/display_name/fmt:break-long-words"
+ class="sprite git">Name</a>
+ </td>
+ <tal:no_commit condition="not: ref/committer_date">
+ <td colspan="2">
+ <metal:no-commit-message use-macro="context/@@+macros/no-commit-message" />
+ </td>
+ </tal:no_commit>
+ <tal:has_commit condition="ref/committer_date">
+ <td>
+ <span class="sortkey"
+ tal:content="ref/committer_date/fmt:datetime" />
+ <span tal:attributes="title ref/committer_date/fmt:datetime"
+ tal:content="ref/committer_date/fmt:approximatedate" />
+ </td>
+ <td tal:attributes="onmouseover string:show_git_commit(${repeat/ref/index});
+ onmouseout string:hide_git_commit(${repeat/ref/index});">
+ <div class="lastCommit">
+ <tal:revision-log replace="ref/commit_message_first_line/fmt:shorten/80" />
+ </div>
+ <div class="popupTitle"
+ tal:attributes="id string:git-ref-${repeat/ref/index};
+ onmouseover string:hide_commit(${repeat/ref/index});">
+ <p>
+ <strong>Author:</strong>
+ <tal:author replace="structure ref/author/fmt:link" />
+ <br />
+ <strong>Author Date:</strong>
+ <tal:author replace="structure ref/author_date/fmt:datetime" />
+ </p>
+ <tal:commit-msg replace="structure ref/commit_message/fmt:text-to-html" />
+ </div>
+ </td>
+ </tal:has_commit>
+ </tr>
+ <tr tal:condition="not: context/batch/total">
+ <td colspan="3">
+ This repository has no branches.
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <tal:navigation replace="structure context/@@+navigation-links-lower" />
+
+</div>
=== added file 'lib/lp/code/templates/gitref-macros.pt'
--- lib/lp/code/templates/gitref-macros.pt 1970-01-01 00:00:00 +0000
+++ lib/lp/code/templates/gitref-macros.pt 2015-03-19 17:09:23 +0000
@@ -0,0 +1,44 @@
+<tal:root
+ xmlns:tal="http://xml.zope.org/namespaces/tal"
+ xmlns:metal="http://xml.zope.org/namespaces/metal"
+ omit-tag="">
+
+<metal:commit-text define-macro="commit-text">
+
+ <tal:comment condition="nothing">
+ This macro requires the following defined variable:
+ commit_info - a dict of the commit information (sha1, author,
+ author_date, commit_message) to be displayed.
+
+ It is expected that this macro is called from within a definition list
+ (<dl></dl>).
+ </tal:comment>
+ <dt class="commit-details"
+ tal:define="
+ sha1 python:commit_info['sha1'];
+ author python:commit_info['author'];
+ author_date python:commit_info['author_date']">
+ <tal:sha1 replace="sha1/fmt:shorten/10" />
+ by
+ <tal:known-person condition="author/person">
+ <tal:person-link replace="structure author/person/fmt:link" />
+ </tal:known-person>
+ <tal:unknown-person condition="not: author/person">
+ <strong tal:content="author/name/fmt:obfuscate-email" />
+ </tal:unknown-person>
+ <span tal:attributes="title author_date/fmt:datetime"
+ tal:content="author_date/fmt:displaydate" />
+ </dt>
+ <dd class="subordinate commit-message"
+ tal:define="commit_message python:commit_info['commit_message']">
+ <tal:commit-message
+ replace="structure commit_message/fmt:obfuscate-email/fmt:text-to-html" />
+ </dd>
+
+</metal:commit-text>
+
+<metal:no-commit-message define-macro="no-commit-message">
+ This branch has not been scanned yet.
+</metal:no-commit-message>
+
+</tal:root>
=== modified file 'lib/lp/code/templates/gitrepository-index.pt'
--- lib/lp/code/templates/gitrepository-index.pt 2015-03-04 16:49:42 +0000
+++ lib/lp/code/templates/gitrepository-index.pt 2015-03-19 17:09:23 +0000
@@ -47,6 +47,14 @@
</div>
</div>
+ <div class="yui-g">
+ <div id="repository-branches" class="portlet"
+ tal:define="branches view/branches">
+ <h2>Branches</h2>
+ <tal:repository-branches replace="structure branches/@@+ref-listing" />
+ </div>
+ </div>
+
</div>
</body>
=== modified file 'lib/lp/services/doc/sprites.txt'
--- lib/lp/services/doc/sprites.txt 2012-06-02 03:19:33 +0000
+++ lib/lp/services/doc/sprites.txt 2015-03-19 17:09:23 +0000
@@ -6,14 +6,8 @@
view a page. An individual sprite is displayed as a background image
on an element by setting the background position.
-A new image can be added to the combined file with the command::
-
- make sprite_image
-
-The resulting icon-sprites.png and icon-sprites.positioning files must
-be committed to the repository. Any changes to the CSS template will be
-automatically picked up when Launchpad is restarted. If you don't want
-to restart launchpad.dev, you can run::
+A new image can be added to the combined image file and CSS template with
+the command::
make css_combine
Follow ups