Merge lp:~abentley/launchpad/recipe-index into lp:launchpad
- recipe-index
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Edwin Grubbs |
Approved revision: | no longer in the source branch. |
Merged at revision: | not available |
Proposed branch: | lp:~abentley/launchpad/recipe-index |
Merge into: | lp:launchpad |
Diff against target: |
1151 lines (+457/-87) 24 files modified
configs/development/build-from-branch.zcml (+36/-0) lib/lp/buildmaster/interfaces/buildbase.py (+6/-6) lib/lp/buildmaster/model/builder.py (+2/-2) lib/lp/code/browser/sourcepackagerecipe.py (+61/-0) lib/lp/code/browser/tests/test_sourcepackagerecipe.py (+128/-0) lib/lp/code/configure.zcml (+8/-1) lib/lp/code/interfaces/sourcepackagerecipe.py (+23/-2) lib/lp/code/model/sourcepackagerecipe.py (+27/-8) lib/lp/code/model/sourcepackagerecipedata.py (+4/-4) lib/lp/code/templates/sourcepackagerecipe-index.pt (+80/-0) lib/lp/registry/browser/person.py (+5/-0) lib/lp/registry/interfaces/person.py (+3/-0) lib/lp/registry/model/person.py (+6/-0) lib/lp/soyuz/doc/build-failedtoupload-workflow.txt (+1/-1) lib/lp/soyuz/doc/build-notification.txt (+2/-2) lib/lp/soyuz/doc/build.txt (+1/-1) lib/lp/soyuz/doc/buildd-mass-retry.txt (+4/-4) lib/lp/soyuz/doc/buildd-slavescanner.txt (+6/-6) lib/lp/soyuz/doc/gina.txt (+1/-1) lib/lp/soyuz/stories/ppa/xx-copy-packages.txt (+1/-1) lib/lp/soyuz/stories/soyuz/xx-build-record.txt (+11/-10) lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt (+30/-30) lib/lp/soyuz/stories/soyuz/xx-private-builds.txt (+1/-1) lib/lp/testing/factory.py (+10/-7) |
To merge this branch: | bzr merge lp:~abentley/launchpad/recipe-index |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Nelson (community) | ui | Approve | |
Guilherme Salgado (community) | Approve | ||
Paul Hummer (community) | ui* | Approve | |
Canonical Launchpad Engineering | code | Pending | |
Review via email: mp+21730@code.launchpad.net |
Commit message
Description of the change
= Summary =
Provide an index page for recipes
== Proposed fix ==
== Pre-implementation notes ==
Mostly discussed with rockstar, some with thumper
== Implementation details ==
Because we do not want to provide an unfinished UI to Edge users, this page
is only enabled for the test runner and devel.
As well as a view for recipes, a view for builds was provided, so that we can
get user-facing information the view class.
It was determined, in discussion with Muharem, that the default of creating
builders with manual=True is not a sane default for test purposes. This has an
impact on ETA calculations, because manual builders are ignored in such
calculations. Therefore, I added the ability to control the manual flag in
IBuilderSet.new, and forced it to False in the factory method.
In consultation with Michael Hudson, I determined that
_SourcePackageR
view and manipulate directly. However, it needs to remain a separate class
because it is common to recipes and manifests. So I had SourcePackageRecipe
delegate to it.
There were miscellaneous lint fixes, like calling Storm.__init__ in subclasses.
I adjusted LaunchpadObject
displayname for distroseries. I adjusted makeSourcePacka
allow specifying a build. These changes helped me provide a consistent
homepage for tests.
== Tests ==
bin/test -v test_sourcepack
== Demo and Q/A ==
Cannot be Q/A'ed until more pieces are in place.
= Launchpad lint =
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files:
lib/lp/
lib/lp/
lib/lp/
configs/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
== Pylint notices ==
lib/lp/
14: [F0401] Unable to import 'bzrlib.
17: [F0401] Unable to import 'lazr.enum' (No module named enum)
lib/lp/
1710: [F0401, LaunchpadObject
lib/lp/
523: [C0301] Line too long (80/78)
53: [F0401] Unable to import 'lazr.enum' (No module named enum)
54: [F0401] Unable to import 'lazr.lifecycle
55: [F0401] Unable to import 'lazr.restful.
56: [F0401] Unable to import 'lazr.restful.
63: [F0401] Unable to import 'lazr.restful.
410: [E1002, PersonNameField
1414: [C0322, IPersonEditRest
status=
^
comment=
@export_
def addMember(person, reviewer, status=
comment=None, force_team_
may_
1455: [C0322, IPersonEditRest
comment=Text())
^
@export_
def acceptInvitatio
1467: [C0322, IPersonEditRest
comment=Text())
^
@export_
def declineInvitati
1765: [C0322, IPersonSet.newTeam] Operator not preceded by a space
defaultmemb
^
defaultrene
@operation_
subscriptio
title=
required=False, default=
@export_
ITeam, ['name', 'displayname', 'teamdescription',
'defaultmem
def newTeam(teamowner, name, displayname, teamdescription
subscriptio
defaultmemb
1834: [C0322, IPersonSet.
created_
^
title=
created_
title=
)
@operation_
@export_
def findPerson(text="", exclude_
must_
created_
lib/lp/
11: [F0401] Unable to import 'lazr.delegates' (No module named delegates)
lib/lp/
125: [C0301] Line too long (79/78)
lib/lp/
17: [F0401] Unable to import 'lazr.restful.
lib/lp/
117: [F0401] Unable to import 'lazr.delegates' (No module named delegates)
118: [F0401] Unable to import 'lazr.config' (No module named config)
119: [F0401] Unable to import 'lazr.restful.
120: [F0401] Unable to import 'lazr.restful.
230: [F0401] Unable to import 'lazr.uri' (No module named uri)
Aaron Bentley (abentley) wrote : | # |
Guilherme Salgado (salgado) wrote : | # |
This looks good but I have a few questions/
review needsfixing
On Fri, 2010-03-19 at 14:53 +0000, Aaron Bentley wrote:
>
> = Summary =
> Provide an index page for recipes
>
> == Proposed fix ==
>
> == Pre-implementation notes ==
> Mostly discussed with rockstar, some with thumper
>
> == Implementation details ==
> Because we do not want to provide an unfinished UI to Edge users, this
> page
> is only enabled for the test runner and devel.
>
> As well as a view for recipes, a view for builds was provided, so that
> we can
> get user-facing information the view class.
>
> It was determined, in discussion with Muharem, that the default of
> creating
> builders with manual=True is not a sane default for test purposes.
> This has an
> impact on ETA calculations, because manual builders are ignored in
> such
> calculations. Therefore, I added the ability to control the manual
> flag in
> IBuilderSet.new, and forced it to False in the factory method.
>
> In consultation with Michael Hudson, I determined that
> _SourcePackageR
> sense to
> view and manipulate directly. However, it needs to remain a separate
> class
> because it is common to recipes and manifests. So I had
> SourcePackageRecipe
> delegate to it.
>
> There were miscellaneous lint fixes, like calling Storm.__init__ in
> subclasses.
>
> I adjusted LaunchpadObject
> specifying a
> displayname for distroseries. I adjusted
> makeSourcePacka
> allow specifying a build. These changes helped me provide a
> consistent
> homepage for tests.
>
> == Tests ==
> bin/test -v test_sourcepack
>
> == Demo and Q/A ==
> Cannot be Q/A'ed until more pieces are in place.
>
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
> @@ -6,3 +6,79 @@
> __metaclass__ = type
>
> __all__ = []
> +
> +
> +from canonical.
> + LaunchpadView)
> +from lp.buildmaster.
> +
> +
> +class SourcePackageRe
> + """Default view of a SourcePackageRe
> +
> + @property
> + def title(self):
> + return self.context.name
> +
> + label = title
> +
> + @property
> + def builds(self):
> + """A list of interesting builds.
> +
> + All pending builds are shown, as well as 1-5 recent builds.
> + Recent builds are ordered by date completed.
> + """
> + builds = list(self.
> + for build in self.context.
> + builds.
> + if len(builds) >= 5:
> + break
> + builds.reverse()
> + return builds
> +
> +
> +class SourcePackageRe
> + """Default view of a SourcePackageRe
> +
> + @property
> + def status(self):
> + """A human-friendly status string."""
> + description = {
> + BuildStatus.
Aaron Bentley (abentley) wrote : | # |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Guilherme Salgado wrote:
>> + @property
>> + def status(self):
>> + """A human-friendly status string."""
>> + description = {
>> + BuildStatus.
>> + BuildStatus.
>> + BuildStatus.
>> + BuildStatus.
>> + 'Could not build because of missing dependencies',
>> + BuildStatus.
>> + 'Could not build because of chroot issues',
>> + BuildStatus.
>> + 'Could not build because source package was superseded',
>> + BuildStatus.
>> + 'Currently building',
>> + BuildStatus.
>> + 'Could not be uploaded correctly',
>
> Would it not make sense to have these strings as the title of the items
> in the BuildStatus enum?
That's Soyuz code, and I don't want to change it unnecessarily. I don't
know how the existing titles are used, and whether these strings would
make sense in that context.
>> === added file 'lib/lp/
>> --- lib/lp/
>> +++ lib/lp/
>> +class TestSourcePacka
>
> Judging by the test class' name, I was expecting to see a test for
> SourcePackageRe
> about renaming the test class to TestSourcePacka
Done.
>
>> +
>> + layer = DatabaseFunctio
>> +
>> + def makeRecipe(self):
>> + chef = self.factory.
>> + name='chef')
>> + chocolate = self.factory.
>> + cake_branch = self.factory.
>> + product=chocolate)
>
> Mind moving all arguments into the same line, in the calls to
> makeProductBranch and makePerson above? They should either be on a line
> by themselves or be aligned...
Done.
>> + def getMainText(self, recipe):
>> + browser = self.getUserBro
>> + return extract_
>> +
>> + def test_index(self):
>> + recipe = self.makeRecipe()
>> + build = removeSecurityP
>> + recipe=recipe))
>> + build.buildstate = BuildStatus.
>> + build.datebuilt = datetime(2010, 03, 16, tzinfo=utc)
>> + pattern = re.compile(
>> + Master Chef
>> + Branches
>> + Description
>> + This recipe .*changes.
>> + Recipe Information
>> + Owner:
>> + Master Chef
>> + Base branch:
>> + lp://dev/
>> + Debian version:
>> + 1.0
>> + Distros:
>> + Secret Squirrel
>> + Build reco...
1 | === modified file 'lib/lp/code/browser/tests/test_sourcepackagerecipe.py' |
2 | --- lib/lp/code/browser/tests/test_sourcepackagerecipe.py 2010-03-18 19:41:22 +0000 |
3 | +++ lib/lp/code/browser/tests/test_sourcepackagerecipe.py 2010-03-22 13:50:35 +0000 |
4 | @@ -15,14 +15,13 @@ |
5 | from zope.security.proxy import removeSecurityProxy |
6 | |
7 | from canonical.launchpad.webapp import canonical_url |
8 | -from canonical.launchpad.webapp.servers import LaunchpadTestRequest |
9 | from canonical.launchpad.testing.pages import extract_text, find_main_content |
10 | from lp.buildmaster.interfaces.buildbase import BuildStatus |
11 | from lp.code.browser.sourcepackagerecipe import SourcePackageRecipeView |
12 | from lp.testing import (TestCaseWithFactory) |
13 | |
14 | |
15 | -class TestSourcePackageRecipe(TestCaseWithFactory): |
16 | +class TestSourcePackageRecipeView(TestCaseWithFactory): |
17 | |
18 | layer = DatabaseFunctionalLayer |
19 | |
20 | @@ -30,8 +29,8 @@ |
21 | chef = self.factory.makePersonNoCommit(displayname='Master Chef', |
22 | name='chef') |
23 | chocolate = self.factory.makeProduct(name='chocolate') |
24 | - cake_branch = self.factory.makeProductBranch(owner=chef, name='cake', |
25 | - product=chocolate) |
26 | + cake_branch = self.factory.makeProductBranch( |
27 | + owner=chef, name='cake', product=chocolate) |
28 | distroseries = self.factory.makeDistroSeries( |
29 | displayname='Secret Squirrel') |
30 | return self.factory.makeSourcePackageRecipe( |
31 | @@ -98,7 +97,7 @@ |
32 | self.assertTrue(pattern.search(main_text), main_text) |
33 | |
34 | def test_builds(self): |
35 | - """Ensure SourcePackageRecipe.builds is as described.""" |
36 | + """Ensure SourcePackageRecipeView.builds is as described.""" |
37 | recipe = self.makeRecipe() |
38 | build1 = self.makeBuildJob(recipe=recipe) |
39 | build2 = self.makeBuildJob(recipe=recipe) |
40 | @@ -106,7 +105,7 @@ |
41 | build4 = self.makeBuildJob(recipe=recipe) |
42 | build5 = self.makeBuildJob(recipe=recipe) |
43 | build6 = self.makeBuildJob(recipe=recipe) |
44 | - view = SourcePackageRecipeView(recipe, LaunchpadTestRequest) |
45 | + view = SourcePackageRecipeView(recipe, None) |
46 | self.assertEqual( |
47 | set([build1, build2, build3, build4, build5, build6]), |
48 | set(view.builds)) |
49 | @@ -115,6 +114,8 @@ |
50 | 2010, 03, day, tzinfo=utc) |
51 | set_day(build1, 16) |
52 | set_day(build2, 15) |
53 | + # When there are 4+ pending builds, only the the most |
54 | + # recently-completed build is returned (i.e. build1, not build2) |
55 | self.assertEqual( |
56 | set([build1, build3, build4, build5, build6]), |
57 | set(view.builds)) |
58 | |
59 | === modified file 'lib/lp/code/interfaces/sourcepackagerecipe.py' |
60 | --- lib/lp/code/interfaces/sourcepackagerecipe.py 2010-03-19 14:35:22 +0000 |
61 | +++ lib/lp/code/interfaces/sourcepackagerecipe.py 2010-03-22 13:53:14 +0000 |
62 | @@ -105,7 +105,11 @@ |
63 | """ |
64 | |
65 | def getBuilds(pending=False): |
66 | - """Return a ResultSet of all the specified builds.""" |
67 | + """Return a ResultSet of all the builds in the given state. |
68 | + |
69 | + :param pending: If True, select all builds that are pending. If |
70 | + False, select all builds that are not pending. |
71 | + """ |
72 | |
73 | |
74 | class ISourcePackageRecipeSource(Interface): |
75 | |
76 | === modified file 'lib/lp/code/model/sourcepackagerecipe.py' |
77 | --- lib/lp/code/model/sourcepackagerecipe.py 2010-03-18 19:41:22 +0000 |
78 | +++ lib/lp/code/model/sourcepackagerecipe.py 2010-03-22 13:55:25 +0000 |
79 | @@ -120,6 +120,7 @@ |
80 | return build |
81 | |
82 | def getBuilds(self, pending=False): |
83 | + """See `ISourcePackageRecipe`.""" |
84 | if pending: |
85 | clauses = [SourcePackageRecipeBuild.datebuilt == None] |
86 | else: |
87 | |
88 | === modified file 'lib/lp/code/model/sourcepackagerecipedata.py' |
89 | --- lib/lp/code/model/sourcepackagerecipedata.py 2010-03-18 19:41:22 +0000 |
90 | +++ lib/lp/code/model/sourcepackagerecipedata.py 2010-03-22 13:58:17 +0000 |
91 | @@ -50,7 +50,7 @@ |
92 | |
93 | def __init__(self, name, type, comment, line_number, branch, revspec, |
94 | directory, recipe_data, parent_instruction): |
95 | - super( _SourcePackageRecipeDataInstruction, self).__init__() |
96 | + super(_SourcePackageRecipeDataInstruction, self).__init__() |
97 | self.name = unicode(name) |
98 | self.type = type |
99 | self.comment = comment |
Paul Hummer (rockstar) wrote : | # |
I don't have any comments because we've been iterating over this for a week, making changes here and there. This is exactly as we have discussed over the last week.
Guilherme Salgado (salgado) wrote : | # |
On Mon, 2010-03-22 at 14:09 +0000, Aaron Bentley wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Guilherme Salgado wrote:
> >> + @property
> >> + def status(self):
> >> + """A human-friendly status string."""
> >> + description = {
> >> + BuildStatus.
> >> + BuildStatus.
> >> + BuildStatus.
> >> + BuildStatus.
> >> + 'Could not build because of missing dependencies',
> >> + BuildStatus.
> >> + 'Could not build because of chroot issues',
> >> + BuildStatus.
> >> + 'Could not build because source package was superseded',
> >> + BuildStatus.
> >> + 'Currently building',
> >> + BuildStatus.
> >> + 'Could not be uploaded correctly',
> >
> > Would it not make sense to have these strings as the title of the items
> > in the BuildStatus enum?
>
> That's Soyuz code, and I don't want to change it unnecessarily. I don't
> know how the existing titles are used, and whether these strings would
> make sense in that context.
>
Being able to use the enum's titles both here and in soyuz code will
make for more consistent UI and avoid this extra code, so we all win.
Have you checked what the current title is for them? Maybe you could
use what's there already?
Julian, what do you think?
> >> === modified file 'lib/lp/
> >> --- lib/lp/
> >> +++ lib/lp/
> >> @@ -9,7 +9,7 @@
> >> """
> >>
> >> __metaclass__ = type
> >> -__all__ = ['_SourcePackag
> >> +__all__ = ['SourcePackage
> >
> > Why did you rename it?
>
> It has become part of the public API, no longer an implementation
> detail, because it manages data that is useful to address directly.
>
Ok.
> >> from bzrlib.
> >> BaseRecipeBranch, MergeInstruction, NestInstruction, RecipeBranch)
> >> @@ -50,6 +50,7 @@
> >>
> >> def __init__(self, name, type, comment, line_number, branch, revspec,
> >> directory, recipe_data, parent_
> >> + super( _SourcePackageR
> >
> > Is there a whitespace preceding the class name above?
>
> There was. Gone now.
>
> >> + <dl id="distros">
> >> + <dt>Distros:</dt>
> >
> > Is this really meant to be in the plural? Judging by the code below,
> > I'd expect to see a single distribution series here.
>
> Yes, it is meant to be in the plural. There is a database patch that is
> just waiting for Bjorn's review to change the relationship to a
> many-to-many:
> https:/
>
Ok, cool.
> > Also, we shouldn't
> > be using 'Distros' in the UI, should we?
>
> Okay, so what should we be using?
Distributions, perha...
Aaron Bentley (abentley) wrote : | # |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Guilherme Salgado wrote:
> Being able to use the enum's titles both here and in soyuz code will
> make for more consistent UI and avoid this extra code, so we all win.
> Have you checked what the current title is for them? Maybe you could
> use what's there already?
I have looked at what's there, and it's not appropriate for us. That
suggests our text won't be appropriate in Soyuz contexts.
Also, we are attempting to land this without any impact on end-users.
Changing the enum titles would have an impact.
> Distributions, perhaps? I know we shouldn't use abbreviations in the
> UI, but maybe 'Distros' is an exception? The UI reviewer ought to know.
Okay.
Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://
iEYEARECAAYFAku
iUMAnjYRuLh1ZQQ
=6O54
-----END PGP SIGNATURE-----
Michael Nelson (michael.nelson) wrote : | # |
Hi Aaron and Paul,
This is looking great! First, sorry if I'm re-asking questions that may have already been discussed by you both. But as I don't know the history of the discussions, I'll ask them anyway.
To test this out in the UI, I've put a breakpoint at the end of test_index, and run a devserver using the testrunner config (it'd be great to include instructions like this when requesting a ui review).
The layout looks great - nice and clean. There are a few small things that popped into mind:
The first thing that stands out is that I need to include a %20 in the url to be able to traverse to the recipe... is that intentional? So the url I'm using is:
https:/
Normally we have a human readable displayname, and name is normally cake_recipe, but perhaps you guys decided against this for good reason (we should slugify the displayname for the initial name right?). The mockup for recipe creation assumed it would be a slug: http://
It's unfortunate that branch names are so long - it's the one thing that looks very squashed in your screenshot (looks fine locally with a wider browser of course), but I guess you always have to deal with that :) Is it possible to use a short name here?
Now I'm sure this *is* something you've discussed - but why isn't the traversal for a recipe (or recipes) off the base branch? (is it in case the base-branch is modified?). I'm just looking at the bread-crumbs and wondering whether it will be: "person >> branches >> recipes >> recipe_
Similar to Guilherme, I think "Distros" should be "Distribution series" (as it's the series to which you're linking). This is consistent with the product-packages.pt template. There are some cases where we simply use "Series" but that's only when the context is already a distribution.
On a related note: I also agree that we should not need to re-define the buildstate titles/descriptions (what's wrong with "Successfully built 7 minutes ago" in the UI?). I don't see why we can't define a good set of common titles and descriptions (that's why we moved BuildBase and BuildStatus to lp.buildmaster). The main issue seems to be that the current ones (BuildStatus) are still soyuz-specific and I guess changing them will blow this branch out (due to test failures). Can you create a bug and XXX here so that we don't forget. Another option you might consider (still with an XXX) is to augment the current ones here, rather than create a new set with some duplication? (eg. code_specific_
Again, something you've probably already discussed, but in the mockups we were planning on presenting the "Packaging branch" (just a merge statement with the name 'packaging') if one was defined for the recipe (optional, as an advanced recipe might specify multiple packaging related branches). Is it worth adding it to the "Recipe information" portlet? (which should actually be ...
Julian Edwards (julian-edwards) wrote : | # |
On Monday 22 March 2010 18:12:40 Guilherme Salgado wrote:
> On Mon, 2010-03-22 at 14:09 +0000, Aaron Bentley wrote:
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA1
> >
> > Guilherme Salgado wrote:
> > >> + @property
> > >> + def status(self):
> > >> + """A human-friendly status string."""
> > >> + description = {
> > >> + BuildStatus.
> > >> + BuildStatus.
> > >> + BuildStatus.
> > >> + BuildStatus.
> > >> + 'Could not build because of missing dependencies',
> > >> + BuildStatus.
> > >> + 'Could not build because of chroot issues',
> > >> + BuildStatus.
> > >> + 'Could not build because source package was
> > >> superseded', + BuildStatus.
> > >> + 'Currently building',
> > >> + BuildStatus.
> > >> + 'Could not be uploaded correctly',
> > >
> > > Would it not make sense to have these strings as the title of the items
> > > in the BuildStatus enum?
> >
> > That's Soyuz code, and I don't want to change it unnecessarily. I don't
> > know how the existing titles are used, and whether these strings would
> > make sense in that context.
>
> Being able to use the enum's titles both here and in soyuz code will
> make for more consistent UI and avoid this extra code, so we all win.
> Have you checked what the current title is for them? Maybe you could
> use what's there already?
>
> Julian, what do you think?
I think that using the enum titles is absolutely the right thing to do.
There are some templates that use the existing titles (grep for
"buildstate/
still make sense, but I fully support anything that makes the UI more
readable!
> > >> + def getRecipe(name):
> > > I wonder if we shouldn't call this getSourcePackag
> > > Although it's a lot longer it doesn't leave one wondering what sort of
> > > recipe could a person have.
> >
> > IMO, SourcePackageRecipe is way too long, and the fewer places we use
> > it, the better. I think the confusion will be short-lived, and less
> > typing is a win.
>
> Ok
FWIW I think getSourcePackag
kinds of recipes in the future? And all editors I've used have auto-complete
:)
J
Aaron Bentley (abentley) wrote : | # |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Michael Nelson wrote:
> Normally we have a human readable displayname, and name is normally
> cake_recipe, but perhaps you guys decided against this for good
> reason (we should slugify the displayname for the initial name
> right?). The mockup for recipe creation assumed it would be a slug:
> http://
The table does not provide a displayname, so I used the name. It was an
error to use "Cake Recipe" as the name. I should have used
"cake_recipe" or similar.
> It's unfortunate that branch names are so long - it's the one thing
> that looks very squashed in your screenshot (looks fine locally with
> a wider browser of course), but I guess you always have to deal with
> that :) Is it possible to use a short name here?
We use short names automatically when they are available, but most
branches don't have short names.
> Now I'm sure this *is* something you've discussed - but why isn't the
> traversal for a recipe (or recipes) off the base branch?
The canonical URL is already defined in stable/dbstable; it was not
introduced by this branch. Tim proposed the current URL and no one
disagreed, so it was documented in
https:/
As you note, branch names are long, which is a disadvantage.
Sourcepackagebr
change the base branch in a recipe, so varying the name according to the
base branch would make URLs volatile.
> Similar to Guilherme, I think "Distros" should be "Distribution
> series" (as it's the series to which you're linking). This is
> consistent with the product-packages.pt template. There are some
> cases where we simply use "Series" but that's only when the context
> is already a distribution.
Done
> On a related note: I also agree that we should not need to re-define
> the buildstate titles/descriptions (what's wrong with "Successfully
> built 7 minutes ago" in the UI?)
It's not the UI that I was tasked to implement:
http://
>. I don't see why we can't define a
> good set of common titles and descriptions (that's why we moved
> BuildBase and BuildStatus to lp.buildmaster). The main issue seems to
> be that the current ones (BuildStatus) are still soyuz-specific and I
> guess changing them will blow this branch out (due to test failures).
I find the existing ones hard to understand. That's the biggest issue
from my point of view. But they also didn't match the grammar in the UI
mockup.
> Can you create a bug and XXX here so that we don't forget.
Per Julian, I have changed all the enums to match what Code needs.
> Again, something you've probably already discussed, but in the
> mockups we were planning on presenting the "Packaging branch"
We believe that's not required for the initial cut. We are going for
the simplest thing that could possibly work.
Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://
iEYEARECAAYFAku
ncoAnj4u3smwkzE
1 | === modified file 'lib/lp/buildmaster/interfaces/buildbase.py' |
2 | --- lib/lp/buildmaster/interfaces/buildbase.py 2010-03-08 12:54:32 +0000 |
3 | +++ lib/lp/buildmaster/interfaces/buildbase.py 2010-03-23 14:16:15 +0000 |
4 | @@ -40,7 +40,7 @@ |
5 | """ |
6 | |
7 | NEEDSBUILD = DBItem(0, """ |
8 | - Needs building |
9 | + Pending build |
10 | |
11 | Build record is fresh and needs building. Nothing is yet known to |
12 | block this build and it is a candidate for building on any free |
13 | @@ -48,7 +48,7 @@ |
14 | """) |
15 | |
16 | FULLYBUILT = DBItem(1, """ |
17 | - Successfully built |
18 | + Successful build |
19 | |
20 | Build record is an historic account of the build. The build is complete |
21 | and needs no further work to complete it. The build log etc are all |
22 | @@ -65,7 +65,7 @@ |
23 | """) |
24 | |
25 | MANUALDEPWAIT = DBItem(3, """ |
26 | - Dependency wait |
27 | + Could not build because of missing dependencies |
28 | |
29 | Build record represents a package whose build dependencies cannot |
30 | currently be satisfied within the relevant DistroArchSeries. This |
31 | @@ -74,7 +74,7 @@ |
32 | """) |
33 | |
34 | CHROOTWAIT = DBItem(4, """ |
35 | - Chroot problem |
36 | + Could not build because of chroot problem |
37 | |
38 | Build record represents a build which needs a chroot currently known |
39 | to be damaged or bad in some way. The buildd maintainer will have to |
40 | @@ -83,7 +83,7 @@ |
41 | """) |
42 | |
43 | SUPERSEDED = DBItem(5, """ |
44 | - Build for superseded Source |
45 | + Could not build because source package was superseded |
46 | |
47 | Build record represents a build which never got to happen because the |
48 | source package release for the build was superseded before the job |
49 | @@ -99,7 +99,7 @@ |
50 | """) |
51 | |
52 | FAILEDTOUPLOAD = DBItem(7, """ |
53 | - Failed to upload |
54 | + Could not be uploaded correctly |
55 | |
56 | Build record is an historic account of a build that could not be |
57 | uploaded correctly. It's mainly genereated by failures in |
58 | |
59 | === modified file 'lib/lp/code/browser/sourcepackagerecipe.py' |
60 | --- lib/lp/code/browser/sourcepackagerecipe.py 2010-03-19 14:35:22 +0000 |
61 | +++ lib/lp/code/browser/sourcepackagerecipe.py 2010-03-23 14:10:34 +0000 |
62 | @@ -44,25 +44,10 @@ |
63 | @property |
64 | def status(self): |
65 | """A human-friendly status string.""" |
66 | - description = { |
67 | - BuildStatus.NEEDSBUILD: 'Pending build', |
68 | - BuildStatus.FULLYBUILT: 'Successful build', |
69 | - BuildStatus.FAILEDTOBUILD: 'Failed to build', |
70 | - BuildStatus.MANUALDEPWAIT: |
71 | - 'Could not build because of missing dependencies', |
72 | - BuildStatus.CHROOTWAIT: |
73 | - 'Could not build because of chroot issues', |
74 | - BuildStatus.SUPERSEDED: |
75 | - 'Could not build because source package was superseded', |
76 | - BuildStatus.BUILDING: |
77 | - 'Currently building', |
78 | - BuildStatus.FAILEDTOUPLOAD: |
79 | - 'Could not be uploaded correctly', |
80 | - } |
81 | if self.context.buildstate == BuildStatus.NEEDSBUILD: |
82 | if self.eta is None: |
83 | return 'No suitable builders' |
84 | - return description[self.context.buildstate] |
85 | + return self.context.buildstate.title |
86 | |
87 | @property |
88 | def eta(self): |
89 | |
90 | === modified file 'lib/lp/code/browser/tests/test_sourcepackagerecipe.py' |
91 | --- lib/lp/code/browser/tests/test_sourcepackagerecipe.py 2010-03-22 14:06:06 +0000 |
92 | +++ lib/lp/code/browser/tests/test_sourcepackagerecipe.py 2010-03-23 14:29:36 +0000 |
93 | @@ -34,7 +34,7 @@ |
94 | distroseries = self.factory.makeDistroSeries( |
95 | displayname='Secret Squirrel') |
96 | return self.factory.makeSourcePackageRecipe( |
97 | - None, chef, distroseries, None, u'Cake Recipe', cake_branch) |
98 | + None, chef, distroseries, None, u'cake_recipe', cake_branch) |
99 | |
100 | def getMainText(self, recipe): |
101 | browser = self.getUserBrowser(canonical_url(recipe)) |
102 | @@ -51,14 +51,14 @@ |
103 | Branches |
104 | Description |
105 | This recipe .*changes. |
106 | - Recipe Information |
107 | + Recipe information |
108 | Owner: |
109 | Master Chef |
110 | Base branch: |
111 | lp://dev/~chef/chocolate/cake |
112 | Debian version: |
113 | 1.0 |
114 | - Distros: |
115 | + Distribution series: |
116 | Secret Squirrel |
117 | Build records |
118 | Successful build.on 2010-03-16 |
119 | @@ -66,7 +66,7 @@ |
120 | # bzr-builder format 0.2 deb-version 1.0 |
121 | lp://dev/~chef/chocolate/cake"""), re.S) |
122 | main_text = self.getMainText(recipe) |
123 | - self.assertTrue(pattern.search(main_text), main_text) |
124 | + self.assertTrue(pattern.search(main_text), repr(main_text)) |
125 | |
126 | def test_index_no_suitable_builders(self): |
127 | recipe = self.makeRecipe() |
128 | |
129 | === modified file 'lib/lp/code/templates/sourcepackagerecipe-index.pt' |
130 | --- lib/lp/code/templates/sourcepackagerecipe-index.pt 2010-03-18 19:41:22 +0000 |
131 | +++ lib/lp/code/templates/sourcepackagerecipe-index.pt 2010-03-23 14:04:57 +0000 |
132 | @@ -31,7 +31,7 @@ |
133 | <div class="yui-g"> |
134 | <div class="yui-u first"> |
135 | <div class="portlet"> |
136 | - <h2>Recipe Information</h2> |
137 | + <h2>Recipe information</h2> |
138 | <div class="two-column-list"> |
139 | <dl id="owner"> |
140 | <dt>Owner:</dt> |
141 | @@ -46,7 +46,7 @@ |
142 | <dd tal:content="context/deb_version_template" /> |
143 | </dl> |
144 | <dl id="distros"> |
145 | - <dt>Distros:</dt> |
146 | + <dt>Distribution series:</dt> |
147 | <dd> |
148 | <ul> |
149 | <li tal:content="structure context/distroseries/fmt:link" /> |
Aaron Bentley (abentley) wrote : | # |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Julian Edwards wrote:
> I think that using the enum titles is absolutely the right thing to do.
Okay, I have changed the enum titles.
Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://
iEYEARECAAYFAku
hmwAni08pSXCzY8
=w0Jz
-----END PGP SIGNATURE-----
Guilherme Salgado (salgado) : | # |
Michael Nelson (michael.nelson) wrote : | # |
Thanks for filling me in on all the info Aaron.
On Tue, Mar 23, 2010 at 3:51 PM, Aaron Bentley <email address hidden> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Michael Nelson wrote:
>> Normally we have a human readable displayname, and name is normally
>> cake_recipe, but perhaps you guys decided against this for good
>> reason (we should slugify the displayname for the initial name
>> right?). The mockup for recipe creation assumed it would be a slug:
>> http://
>
> The table does not provide a displayname, so I used the name. Â It was an
> error to use "Cake Recipe" as the name. Â I should have used
> "cake_recipe" or similar.
OK, so the create validation will need to enforce this I guess. Great.
>> Now I'm sure this *is* something you've discussed - but why isn't the
>> traversal for a recipe (or recipes) off the base branch?
>
> The canonical URL is already defined in stable/dbstable; it was not
> introduced by this branch. Â Tim proposed the current URL and no one
> disagreed, so it was documented in
> https:/
>
> As you note, branch names are long, which is a disadvantage.
> Sourcepackagebr
> change the base branch in a recipe, so varying the name according to the
> base branch would make URLs volatile.
I got to chat briefly with Tim and he had a few other points too, so
just for the record in case anyone else asks the same question (I'll
try to document this on the wiki as a FAQ or something):
{{{
08:43 < noodles775> The only reason I could think of (which Aaron also
highlighted) is that it would be fragile if the base branch changes
etc., but the original mockups didn't allow you to change the base
branch of a recipe.
08:43 < thumper> noodles775: and I picked something
08:44 < noodles775> thumper: no problem, as long as you guys have
thought about it.
08:44 < thumper> noodles775: but what about changing the name of a branch?
08:44 < thumper> noodles775: or changing the owner
08:44 < thumper> noodles775: both of those change the unique name of the branch
08:44 < thumper> noodles775: and since the branch is accessed through
the id, the recipe url would chnage
08:45 < thumper> noodles775: also ~user/+recipe/name is short
08:45 < noodles775> thumper: I see, whereas both of those things
wouldn't change the recipe url where it is currently? Great.
08:45 * thumper nods
}}}
>
>> On a related note: I also agree that we should not need to re-define
>> the buildstate titles/descriptions (what's wrong with "Successfully
>> built 7 minutes ago" in the UI?)
>
> It's not the UI that I was tasked to implement:
> http://
Right, if Paul specifically chose "Successful build" because he
thought "Successfully built" was incorrect, then I think it's worth
updating the BuildStatus as you've done, to improve it.
>
>>. I don't see why we can't define a
>> good set of common titles and descriptions (that's why we moved
>> BuildBase and BuildStatus to lp.buildmaster). The main issue seems to
>> be that the current ones (BuildSta...
Michael Nelson (michael.nelson) : | # |
Preview Diff
1 | === added file 'configs/development/build-from-branch.zcml' |
2 | --- configs/development/build-from-branch.zcml 1970-01-01 00:00:00 +0000 |
3 | +++ configs/development/build-from-branch.zcml 2010-04-05 18:28:37 +0000 |
4 | @@ -0,0 +1,36 @@ |
5 | +<!-- Copyright 2010 Canonical Ltd. This software is licensed under the |
6 | + GNU Affero General Public License version 3 (see the file LICENSE). |
7 | +--> |
8 | + |
9 | +<configure |
10 | + xmlns="http://namespaces.zope.org/zope" |
11 | + xmlns:browser="http://namespaces.zope.org/browser" |
12 | + xmlns:i18n="http://namespaces.zope.org/i18n" |
13 | + xmlns:xmlrpc="http://namespaces.zope.org/xmlrpc" |
14 | + i18n_domain="launchpad"> |
15 | + <facet facet="branches"> |
16 | + |
17 | + <browser:defaultView |
18 | + for="lp.code.interfaces.sourcepackagerecipe.ISourcePackageRecipe" |
19 | + name="+index" |
20 | + layer="canonical.launchpad.layers.CodeLayer"/> |
21 | + <browser:page |
22 | + for="lp.code.interfaces.sourcepackagerecipe.ISourcePackageRecipe" |
23 | + class="lp.code.browser.sourcepackagerecipe.SourcePackageRecipeView" |
24 | + name="+index" |
25 | + template="../../lib/lp/code/templates/sourcepackagerecipe-index.pt" |
26 | + permission="zope.Public"/> |
27 | + </facet> |
28 | + <facet facet="branches"> |
29 | + <browser:defaultView |
30 | + for="lp.code.interfaces.sourcepackagerecipebuild.ISourcePackageRecipeBuild" |
31 | + name="+index" |
32 | + layer="canonical.launchpad.layers.CodeLayer"/> |
33 | + <browser:page |
34 | + for="lp.code.interfaces.sourcepackagerecipebuild.ISourcePackageRecipeBuild" |
35 | + class="lp.code.browser.sourcepackagerecipe.SourcePackageRecipeBuildView" |
36 | + name="+index" |
37 | + template="../../lib/lp/code/templates/sourcepackagerecipe-index.pt" |
38 | + permission="zope.Public"/> |
39 | + </facet> |
40 | +</configure> |
41 | |
42 | === added symlink 'configs/testrunner/build-from-branch.zcml' |
43 | === target is u'../development/build-from-branch.zcml' |
44 | === modified file 'lib/lp/buildmaster/interfaces/buildbase.py' |
45 | --- lib/lp/buildmaster/interfaces/buildbase.py 2010-03-25 14:38:25 +0000 |
46 | +++ lib/lp/buildmaster/interfaces/buildbase.py 2010-04-05 18:28:37 +0000 |
47 | @@ -40,7 +40,7 @@ |
48 | """ |
49 | |
50 | NEEDSBUILD = DBItem(0, """ |
51 | - Needs building |
52 | + Pending build |
53 | |
54 | Build record is fresh and needs building. Nothing is yet known to |
55 | block this build and it is a candidate for building on any free |
56 | @@ -48,7 +48,7 @@ |
57 | """) |
58 | |
59 | FULLYBUILT = DBItem(1, """ |
60 | - Successfully built |
61 | + Successful build |
62 | |
63 | Build record is an historic account of the build. The build is complete |
64 | and needs no further work to complete it. The build log etc are all |
65 | @@ -65,7 +65,7 @@ |
66 | """) |
67 | |
68 | MANUALDEPWAIT = DBItem(3, """ |
69 | - Dependency wait |
70 | + Could not build because of missing dependencies |
71 | |
72 | Build record represents a package whose build dependencies cannot |
73 | currently be satisfied within the relevant DistroArchSeries. This |
74 | @@ -74,7 +74,7 @@ |
75 | """) |
76 | |
77 | CHROOTWAIT = DBItem(4, """ |
78 | - Chroot problem |
79 | + Could not build because of chroot problem |
80 | |
81 | Build record represents a build which needs a chroot currently known |
82 | to be damaged or bad in some way. The buildd maintainer will have to |
83 | @@ -83,7 +83,7 @@ |
84 | """) |
85 | |
86 | SUPERSEDED = DBItem(5, """ |
87 | - Build for superseded Source |
88 | + Could not build because source package was superseded |
89 | |
90 | Build record represents a build which never got to happen because the |
91 | source package release for the build was superseded before the job |
92 | @@ -99,7 +99,7 @@ |
93 | """) |
94 | |
95 | FAILEDTOUPLOAD = DBItem(7, """ |
96 | - Failed to upload |
97 | + Could not be uploaded correctly |
98 | |
99 | Build record is an historic account of a build that could not be |
100 | uploaded correctly. It's mainly genereated by failures in |
101 | |
102 | === modified file 'lib/lp/buildmaster/model/builder.py' |
103 | --- lib/lp/buildmaster/model/builder.py 2010-03-31 02:15:04 +0000 |
104 | +++ lib/lp/buildmaster/model/builder.py 2010-04-05 18:28:37 +0000 |
105 | @@ -664,12 +664,12 @@ |
106 | raise NotFoundError(name) |
107 | |
108 | def new(self, processor, url, name, title, description, owner, |
109 | - active=True, virtualized=False, vm_host=None): |
110 | + active=True, virtualized=False, vm_host=None, manual=True): |
111 | """See IBuilderSet.""" |
112 | return Builder(processor=processor, url=url, name=name, title=title, |
113 | description=description, owner=owner, active=active, |
114 | virtualized=virtualized, vm_host=vm_host, |
115 | - builderok=True, manual=True) |
116 | + builderok=True, manual=manual) |
117 | |
118 | def get(self, builder_id): |
119 | """See IBuilderSet.""" |
120 | |
121 | === modified file 'lib/lp/code/browser/sourcepackagerecipe.py' |
122 | --- lib/lp/code/browser/sourcepackagerecipe.py 2010-03-12 18:53:55 +0000 |
123 | +++ lib/lp/code/browser/sourcepackagerecipe.py 2010-04-05 18:28:37 +0000 |
124 | @@ -6,3 +6,64 @@ |
125 | __metaclass__ = type |
126 | |
127 | __all__ = [] |
128 | + |
129 | + |
130 | +from canonical.launchpad.webapp import ( |
131 | + LaunchpadView) |
132 | +from lp.buildmaster.interfaces.buildbase import BuildStatus |
133 | + |
134 | + |
135 | +class SourcePackageRecipeView(LaunchpadView): |
136 | + """Default view of a SourcePackageRecipe.""" |
137 | + |
138 | + @property |
139 | + def title(self): |
140 | + return self.context.name |
141 | + |
142 | + label = title |
143 | + |
144 | + @property |
145 | + def builds(self): |
146 | + """A list of interesting builds. |
147 | + |
148 | + All pending builds are shown, as well as 1-5 recent builds. |
149 | + Recent builds are ordered by date completed. |
150 | + """ |
151 | + builds = list(self.context.getBuilds(pending=True)) |
152 | + for build in self.context.getBuilds(): |
153 | + builds.append(build) |
154 | + if len(builds) >= 5: |
155 | + break |
156 | + builds.reverse() |
157 | + return builds |
158 | + |
159 | + |
160 | +class SourcePackageRecipeBuildView(LaunchpadView): |
161 | + """Default view of a SourcePackageRecipeBuild.""" |
162 | + |
163 | + @property |
164 | + def status(self): |
165 | + """A human-friendly status string.""" |
166 | + if self.context.buildstate == BuildStatus.NEEDSBUILD: |
167 | + if self.eta is None: |
168 | + return 'No suitable builders' |
169 | + return self.context.buildstate.title |
170 | + |
171 | + @property |
172 | + def eta(self): |
173 | + """The datetime when the build job is estimated to begin.""" |
174 | + if self.context.buildqueue_record is None: |
175 | + return None |
176 | + return self.context.buildqueue_record.getEstimatedJobStartTime() |
177 | + |
178 | + @property |
179 | + def date(self): |
180 | + """The date when the build complete or will begin.""" |
181 | + if self.estimate: |
182 | + return self.eta |
183 | + return self.context.datebuilt |
184 | + |
185 | + @property |
186 | + def estimate(self): |
187 | + """If true, the date value is an estimate.""" |
188 | + return (self.context.datebuilt is None and self.eta is not None) |
189 | |
190 | === added file 'lib/lp/code/browser/tests/test_sourcepackagerecipe.py' |
191 | --- lib/lp/code/browser/tests/test_sourcepackagerecipe.py 1970-01-01 00:00:00 +0000 |
192 | +++ lib/lp/code/browser/tests/test_sourcepackagerecipe.py 2010-04-05 18:28:37 +0000 |
193 | @@ -0,0 +1,128 @@ |
194 | +# Copyright 2010 Canonical Ltd. This software is licensed under the |
195 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
196 | + |
197 | +"""Tests for the product view classes and templates.""" |
198 | + |
199 | +__metaclass__ = type |
200 | + |
201 | + |
202 | +from datetime import datetime |
203 | +from textwrap import dedent |
204 | +import re |
205 | + |
206 | +from pytz import utc |
207 | +from canonical.testing import DatabaseFunctionalLayer |
208 | +from zope.security.proxy import removeSecurityProxy |
209 | + |
210 | +from canonical.launchpad.webapp import canonical_url |
211 | +from canonical.launchpad.testing.pages import extract_text, find_main_content |
212 | +from lp.buildmaster.interfaces.buildbase import BuildStatus |
213 | +from lp.code.browser.sourcepackagerecipe import SourcePackageRecipeView |
214 | +from lp.testing import (TestCaseWithFactory) |
215 | + |
216 | + |
217 | +class TestSourcePackageRecipeView(TestCaseWithFactory): |
218 | + |
219 | + layer = DatabaseFunctionalLayer |
220 | + |
221 | + def makeRecipe(self): |
222 | + chef = self.factory.makePersonNoCommit(displayname='Master Chef', |
223 | + name='chef') |
224 | + chocolate = self.factory.makeProduct(name='chocolate') |
225 | + cake_branch = self.factory.makeProductBranch( |
226 | + owner=chef, name='cake', product=chocolate) |
227 | + distroseries = self.factory.makeDistroSeries( |
228 | + displayname='Secret Squirrel') |
229 | + return self.factory.makeSourcePackageRecipe( |
230 | + None, chef, distroseries, None, u'cake_recipe', |
231 | + u'This recipe builds a foo for disto bar, with my Secret Squirrel' |
232 | + ' changes.', cake_branch) |
233 | + |
234 | + def getMainText(self, recipe): |
235 | + browser = self.getUserBrowser(canonical_url(recipe)) |
236 | + return extract_text(find_main_content(browser.contents)) |
237 | + |
238 | + def test_index(self): |
239 | + recipe = self.makeRecipe() |
240 | + build = removeSecurityProxy(self.factory.makeSourcePackageRecipeBuild( |
241 | + recipe=recipe)) |
242 | + build.buildstate = BuildStatus.FULLYBUILT |
243 | + build.datebuilt = datetime(2010, 03, 16, tzinfo=utc) |
244 | + pattern = re.compile(dedent("""\ |
245 | + Master Chef |
246 | + Branches |
247 | + Description |
248 | + This recipe .*changes. |
249 | + Recipe information |
250 | + Owner: |
251 | + Master Chef |
252 | + Base branch: |
253 | + lp://dev/~chef/chocolate/cake |
254 | + Debian version: |
255 | + 1.0 |
256 | + Distribution series: |
257 | + Secret Squirrel |
258 | + Build records |
259 | + Successful build.on 2010-03-16 |
260 | + Recipe contents |
261 | + # bzr-builder format 0.2 deb-version 1.0 |
262 | + lp://dev/~chef/chocolate/cake"""), re.S) |
263 | + main_text = self.getMainText(recipe) |
264 | + self.assertTrue(pattern.search(main_text), repr(main_text)) |
265 | + |
266 | + def test_index_no_suitable_builders(self): |
267 | + recipe = self.makeRecipe() |
268 | + build = removeSecurityProxy(self.factory.makeSourcePackageRecipeBuild( |
269 | + recipe=recipe)) |
270 | + pattern = re.compile(dedent("""\ |
271 | + Build records |
272 | + No suitable builders |
273 | + Recipe contents"""), re.S) |
274 | + main_text = self.getMainText(recipe) |
275 | + self.assertTrue(pattern.search(main_text), main_text) |
276 | + |
277 | + def makeBuildJob(self, recipe): |
278 | + build = self.factory.makeSourcePackageRecipeBuild(recipe=recipe) |
279 | + buildjob = self.factory.makeSourcePackageRecipeBuildJob( |
280 | + recipe_build=build) |
281 | + return build |
282 | + |
283 | + def test_index_pending(self): |
284 | + recipe = self.makeRecipe() |
285 | + buildjob = self.makeBuildJob(recipe) |
286 | + builder = self.factory.makeBuilder() |
287 | + pattern = re.compile(dedent("""\ |
288 | + Build records |
289 | + Pending build.in .*\(estimated\) |
290 | + Recipe contents"""), re.S) |
291 | + main_text = self.getMainText(recipe) |
292 | + self.assertTrue(pattern.search(main_text), main_text) |
293 | + |
294 | + def test_builds(self): |
295 | + """Ensure SourcePackageRecipeView.builds is as described.""" |
296 | + recipe = self.makeRecipe() |
297 | + build1 = self.makeBuildJob(recipe=recipe) |
298 | + build2 = self.makeBuildJob(recipe=recipe) |
299 | + build3 = self.makeBuildJob(recipe=recipe) |
300 | + build4 = self.makeBuildJob(recipe=recipe) |
301 | + build5 = self.makeBuildJob(recipe=recipe) |
302 | + build6 = self.makeBuildJob(recipe=recipe) |
303 | + view = SourcePackageRecipeView(recipe, None) |
304 | + self.assertEqual( |
305 | + set([build1, build2, build3, build4, build5, build6]), |
306 | + set(view.builds)) |
307 | + def set_day(build, day): |
308 | + removeSecurityProxy(build).datebuilt = datetime( |
309 | + 2010, 03, day, tzinfo=utc) |
310 | + set_day(build1, 16) |
311 | + set_day(build2, 15) |
312 | + # When there are 4+ pending builds, only the the most |
313 | + # recently-completed build is returned (i.e. build1, not build2) |
314 | + self.assertEqual( |
315 | + set([build1, build3, build4, build5, build6]), |
316 | + set(view.builds)) |
317 | + set_day(build3, 14) |
318 | + set_day(build4, 13) |
319 | + set_day(build5, 12) |
320 | + set_day(build6, 11) |
321 | + self.assertEqual([build5, build4, build3, build2, build1], view.builds) |
322 | |
323 | === modified file 'lib/lp/code/configure.zcml' |
324 | --- lib/lp/code/configure.zcml 2010-03-25 19:55:16 +0000 |
325 | +++ lib/lp/code/configure.zcml 2010-04-05 18:28:37 +0000 |
326 | @@ -1004,10 +1004,17 @@ |
327 | <adapter factory="lp.code.model.recipebuilder.RecipeBuildBehavior" |
328 | permission="zope.Public" /> |
329 | |
330 | + <!-- SourcePackageRecipeData --> |
331 | + <class |
332 | + class="lp.code.model.sourcepackagerecipedata.SourcePackageRecipeData"> |
333 | + <allow |
334 | + interface="lp.code.interfaces.sourcepackagerecipe.ISourcePackageRecipeData"/> |
335 | + </class> |
336 | <!-- SourcePackageRecipe --> |
337 | <class |
338 | class="lp.code.model.sourcepackagerecipe.SourcePackageRecipe"> |
339 | - <allow interface="lp.code.interfaces.sourcepackagerecipe.ISourcePackageRecipe"/> |
340 | + <allow |
341 | + interface="lp.code.interfaces.sourcepackagerecipe.ISourcePackageRecipe"/> |
342 | <require |
343 | permission="launchpad.Edit" |
344 | set_attributes="builder_recipe build_daily"/> |
345 | |
346 | === modified file 'lib/lp/code/interfaces/sourcepackagerecipe.py' |
347 | --- lib/lp/code/interfaces/sourcepackagerecipe.py 2010-03-26 19:29:56 +0000 |
348 | +++ lib/lp/code/interfaces/sourcepackagerecipe.py 2010-04-05 18:28:37 +0000 |
349 | @@ -13,6 +13,7 @@ |
350 | __all__ = [ |
351 | 'ForbiddenInstruction', |
352 | 'ISourcePackageRecipe', |
353 | + 'ISourcePackageRecipeData', |
354 | 'ISourcePackageRecipeSource', |
355 | 'TooNewRecipeFormat', |
356 | ] |
357 | @@ -21,7 +22,7 @@ |
358 | from lazr.restful.fields import CollectionField, Reference |
359 | |
360 | from zope.interface import Attribute, Interface |
361 | -from zope.schema import Bool, Datetime, Text, TextLine |
362 | +from zope.schema import Bool, Datetime, Object, TextLine, Text |
363 | |
364 | from canonical.launchpad import _ |
365 | from canonical.launchpad.validators.name import name_validator |
366 | @@ -50,7 +51,20 @@ |
367 | self.newest_supported = newest_supported |
368 | |
369 | |
370 | -class ISourcePackageRecipe(IHasOwner): |
371 | +class ISourcePackageRecipeData(Interface): |
372 | + """A recipe as database data, not text.""" |
373 | + |
374 | + base_branch = Object( |
375 | + schema=IBranch, title=_("Base branch"), description=_( |
376 | + "The base branch to use when building the recipe.")) |
377 | + |
378 | + deb_version_template = TextLine( |
379 | + title=_('deb-version template'), |
380 | + description = _( |
381 | + 'The template that will be used to generate a deb version.'),) |
382 | + |
383 | + |
384 | +class ISourcePackageRecipe(IHasOwner, ISourcePackageRecipeData): |
385 | """An ISourcePackageRecipe describes how to build a source package. |
386 | |
387 | More precisely, it describes how to combine a number of branches into a |
388 | @@ -105,6 +119,13 @@ |
389 | able to upload to the archive. |
390 | """ |
391 | |
392 | + def getBuilds(pending=False): |
393 | + """Return a ResultSet of all the builds in the given state. |
394 | + |
395 | + :param pending: If True, select all builds that are pending. If |
396 | + False, select all builds that are not pending. |
397 | + """ |
398 | + |
399 | |
400 | class ISourcePackageRecipeSource(Interface): |
401 | """A utility of this interface can be used to create and access recipes. |
402 | |
403 | === modified file 'lib/lp/code/model/sourcepackagerecipe.py' |
404 | --- lib/lp/code/model/sourcepackagerecipe.py 2010-03-26 19:29:56 +0000 |
405 | +++ lib/lp/code/model/sourcepackagerecipe.py 2010-04-05 18:28:37 +0000 |
406 | @@ -8,8 +8,10 @@ |
407 | 'SourcePackageRecipe', |
408 | ] |
409 | |
410 | +from lazr.delegates import delegates |
411 | + |
412 | from storm.locals import ( |
413 | - Bool, Int, Reference, ReferenceSet, Store, Storm, Unicode) |
414 | + Bool, Desc, Int, Reference, ReferenceSet, Store, Storm, Unicode) |
415 | |
416 | from zope.component import getUtility |
417 | from zope.interface import classProvides, implements |
418 | @@ -19,10 +21,12 @@ |
419 | |
420 | from lp.archiveuploader.permission import check_upload_to_archive |
421 | from lp.code.interfaces.sourcepackagerecipe import ( |
422 | - ISourcePackageRecipe, ISourcePackageRecipeSource) |
423 | + ISourcePackageRecipe, ISourcePackageRecipeSource, |
424 | + ISourcePackageRecipeData) |
425 | from lp.code.interfaces.sourcepackagerecipebuild import ( |
426 | ISourcePackageRecipeBuildSource) |
427 | -from lp.code.model.sourcepackagerecipedata import _SourcePackageRecipeData |
428 | +from lp.code.model.sourcepackagerecipebuild import SourcePackageRecipeBuild |
429 | +from lp.code.model.sourcepackagerecipedata import SourcePackageRecipeData |
430 | from lp.registry.model.distroseries import DistroSeries |
431 | from lp.soyuz.interfaces.archive import ArchivePurpose |
432 | from lp.soyuz.interfaces.component import IComponentSet |
433 | @@ -48,8 +52,11 @@ |
434 | __storm_table__ = 'SourcePackageRecipe' |
435 | |
436 | implements(ISourcePackageRecipe) |
437 | + |
438 | classProvides(ISourcePackageRecipeSource) |
439 | |
440 | + delegates(ISourcePackageRecipeData, context='_recipe_data') |
441 | + |
442 | id = Int(primary=True) |
443 | |
444 | date_created = UtcDateTimeCol(notNull=True) |
445 | @@ -77,15 +84,15 @@ |
446 | @property |
447 | def _recipe_data(self): |
448 | return Store.of(self).find( |
449 | - _SourcePackageRecipeData, |
450 | - _SourcePackageRecipeData.sourcepackage_recipe == self).one() |
451 | + SourcePackageRecipeData, |
452 | + SourcePackageRecipeData.sourcepackage_recipe == self).one() |
453 | |
454 | def _get_builder_recipe(self): |
455 | - """Accesses of the recipe go to the _SourcePackageRecipeData.""" |
456 | + """Accesses of the recipe go to the SourcePackageRecipeData.""" |
457 | return self._recipe_data.getRecipe() |
458 | |
459 | def _set_builder_recipe(self, value): |
460 | - """Setting of the recipe goes to the _SourcePackageRecipeData.""" |
461 | + """Setting of the recipe goes to the SourcePackageRecipeData.""" |
462 | self._recipe_data.setRecipe(value) |
463 | |
464 | builder_recipe = property(_get_builder_recipe, _set_builder_recipe) |
465 | @@ -104,7 +111,7 @@ |
466 | """See `ISourcePackageRecipeSource.new`.""" |
467 | store = IMasterStore(SourcePackageRecipe) |
468 | sprecipe = SourcePackageRecipe() |
469 | - _SourcePackageRecipeData(builder_recipe, sprecipe) |
470 | + SourcePackageRecipeData(builder_recipe, sprecipe) |
471 | sprecipe.registrant = registrant |
472 | sprecipe.owner = owner |
473 | sprecipe.sourcepackagename = sourcepackagename |
474 | @@ -132,3 +139,15 @@ |
475 | self, requester, archive) |
476 | build.queueBuild() |
477 | return build |
478 | + |
479 | + def getBuilds(self, pending=False): |
480 | + """See `ISourcePackageRecipe`.""" |
481 | + if pending: |
482 | + clauses = [SourcePackageRecipeBuild.datebuilt == None] |
483 | + else: |
484 | + clauses = [SourcePackageRecipeBuild.datebuilt != None] |
485 | + result = Store.of(self).find( |
486 | + SourcePackageRecipeBuild, SourcePackageRecipeBuild.recipe==self, |
487 | + *clauses) |
488 | + result.order_by(Desc(SourcePackageRecipeBuild.datebuilt)) |
489 | + return result |
490 | |
491 | === modified file 'lib/lp/code/model/sourcepackagerecipedata.py' |
492 | --- lib/lp/code/model/sourcepackagerecipedata.py 2010-03-11 15:15:51 +0000 |
493 | +++ lib/lp/code/model/sourcepackagerecipedata.py 2010-04-05 18:28:37 +0000 |
494 | @@ -9,7 +9,7 @@ |
495 | """ |
496 | |
497 | __metaclass__ = type |
498 | -__all__ = ['_SourcePackageRecipeData'] |
499 | +__all__ = ['SourcePackageRecipeData'] |
500 | |
501 | from bzrlib.plugins.builder.recipe import ( |
502 | BaseRecipeBranch, MergeInstruction, NestInstruction, RecipeBranch) |
503 | @@ -79,7 +79,7 @@ |
504 | directory = Unicode(allow_none=True) |
505 | |
506 | recipe_data_id = Int(name='recipe_data', allow_none=False) |
507 | - recipe_data = Reference(recipe_data_id, '_SourcePackageRecipeData.id') |
508 | + recipe_data = Reference(recipe_data_id, 'SourcePackageRecipeData.id') |
509 | |
510 | parent_instruction_id = Int(name='parent_instruction', allow_none=True) |
511 | parent_instruction = Reference( |
512 | @@ -98,7 +98,7 @@ |
513 | return branch |
514 | |
515 | |
516 | -class _SourcePackageRecipeData(Storm): |
517 | +class SourcePackageRecipeData(Storm): |
518 | """The database representation of a BaseRecipeBranch from bzr-builder. |
519 | |
520 | This is referenced from the SourcePackageRecipe table as the 'recipe_data' |
521 | @@ -216,7 +216,7 @@ |
522 | def __init__(self, recipe, sourcepackage_recipe): |
523 | """Initialize from the bzr-builder recipe and link it to a db recipe. |
524 | """ |
525 | - super(_SourcePackageRecipeData, self).__init__() |
526 | + super(SourcePackageRecipeData, self).__init__() |
527 | self.setRecipe(recipe) |
528 | self.sourcepackage_recipe = sourcepackage_recipe |
529 | |
530 | |
531 | === added file 'lib/lp/code/templates/sourcepackagerecipe-index.pt' |
532 | --- lib/lp/code/templates/sourcepackagerecipe-index.pt 1970-01-01 00:00:00 +0000 |
533 | +++ lib/lp/code/templates/sourcepackagerecipe-index.pt 2010-04-05 18:28:37 +0000 |
534 | @@ -0,0 +1,80 @@ |
535 | +<html |
536 | + xmlns="http://www.w3.org/1999/xhtml" |
537 | + xmlns:tal="http://xml.zope.org/namespaces/tal" |
538 | + xmlns:metal="http://xml.zope.org/namespaces/metal" |
539 | + xmlns:i18n="http://xml.zope.org/namespaces/i18n" |
540 | + metal:use-macro="view/macro:page/main_side" |
541 | + i18n:domain="launchpad" |
542 | +> |
543 | + |
544 | + |
545 | +<body> |
546 | + |
547 | +<tal:registering metal:fill-slot="registering"> |
548 | + Created by |
549 | + <tal:registrant replace="structure context/registrant/fmt:link" /> |
550 | + on |
551 | + <tal:created-on replace="structure context/date_created/fmt:date" /> |
552 | + and last modified on |
553 | + <tal:last-modified replace="structure context/date_last_modified/fmt:date" /> |
554 | +</tal:registering> |
555 | + |
556 | + |
557 | +<div metal:fill-slot="main"> |
558 | + <div class="yui-g first"> |
559 | + <div class="portlet"> |
560 | + <h2>Description</h2> |
561 | + <tal:description replace="context/description" /> |
562 | + </div> |
563 | + </div> |
564 | + <div class="yui-g"> |
565 | + <div class="yui-u first"> |
566 | + <div class="portlet"> |
567 | + <h2>Recipe information</h2> |
568 | + <div class="two-column-list"> |
569 | + <dl id="owner"> |
570 | + <dt>Owner:</dt> |
571 | + <dd tal:content="structure context/owner/fmt:link" /> |
572 | + </dl> |
573 | + <dl id="base-branch"> |
574 | + <dt>Base branch:</dt> |
575 | + <dd tal:content="structure context/base_branch/fmt:link" /> |
576 | + </dl> |
577 | + <dl id="debian-version"> |
578 | + <dt>Debian version:</dt> |
579 | + <dd tal:content="context/deb_version_template" /> |
580 | + </dl> |
581 | + <dl id="distros"> |
582 | + <dt>Distribution series:</dt> |
583 | + <dd> |
584 | + <ul> |
585 | + <li tal:repeat="curseries context/distroseries" |
586 | + tal:content="structure curseries/fmt:link" /> |
587 | + </ul> |
588 | + </dd> |
589 | + </dl> |
590 | + </div> |
591 | + </div> |
592 | + </div> |
593 | + <div class="yui-u"> |
594 | + <div class="portlet"> |
595 | + <h2>Build records</h2> |
596 | + <ul> |
597 | + <li tal:repeat="build view/builds"> |
598 | + <tal:status replace="build/@@+index/status" /> |
599 | + <tal:date replace="build/@@+index/date/fmt:displaydate" /> |
600 | + <tal:estimate condition="build/@@+index/estimate"> |
601 | + (estimated) |
602 | + </tal:estimate> |
603 | + </li> |
604 | + </ul> |
605 | + </div> |
606 | + </div> |
607 | + </div> |
608 | + <div class='portlet'> |
609 | + <h2>Recipe contents</h2> |
610 | + <pre tal:content="context/builder_recipe" /> |
611 | + </div> |
612 | + </div> |
613 | +</body> |
614 | +</html> |
615 | |
616 | === modified file 'lib/lp/registry/browser/person.py' |
617 | --- lib/lp/registry/browser/person.py 2010-03-25 14:50:31 +0000 |
618 | +++ lib/lp/registry/browser/person.py 2010-04-05 18:28:37 +0000 |
619 | @@ -446,6 +446,11 @@ |
620 | return queryMultiAdapter( |
621 | (self.context, self.request), name ="+archivesubscriptions") |
622 | |
623 | + @stepthrough('+recipe') |
624 | + def traverse_recipe(self, name): |
625 | + """Traverse to this person's recipes.""" |
626 | + return self.context.getRecipe(name) |
627 | + |
628 | |
629 | class TeamNavigation(PersonNavigation): |
630 | |
631 | |
632 | === modified file 'lib/lp/registry/interfaces/person.py' |
633 | --- lib/lp/registry/interfaces/person.py 2010-03-25 14:17:56 +0000 |
634 | +++ lib/lp/registry/interfaces/person.py 2010-04-05 18:28:37 +0000 |
635 | @@ -872,6 +872,9 @@ |
636 | not teams can be converted into teams. |
637 | """ |
638 | |
639 | + def getRecipe(name): |
640 | + """Return the person's recipe with the given name.""" |
641 | + |
642 | def getInvitedMemberships(): |
643 | """Return all TeamMemberships of this team with the INVITED status. |
644 | |
645 | |
646 | === modified file 'lib/lp/registry/model/person.py' |
647 | --- lib/lp/registry/model/person.py 2010-03-30 17:25:52 +0000 |
648 | +++ lib/lp/registry/model/person.py 2010-04-05 18:28:37 +0000 |
649 | @@ -2258,6 +2258,12 @@ |
650 | |
651 | return rset |
652 | |
653 | + def getRecipe(self, name): |
654 | + from lp.code.model.sourcepackagerecipe import SourcePackageRecipe |
655 | + return Store.of(self).find( |
656 | + SourcePackageRecipe, SourcePackageRecipe.owner == self, |
657 | + SourcePackageRecipe.name == name).one() |
658 | + |
659 | def isUploader(self, distribution): |
660 | """See `IPerson`.""" |
661 | permissions = getUtility(IArchivePermissionSet).componentsForUploader( |
662 | |
663 | === modified file 'lib/lp/soyuz/doc/build-failedtoupload-workflow.txt' |
664 | --- lib/lp/soyuz/doc/build-failedtoupload-workflow.txt 2010-02-16 02:27:24 +0000 |
665 | +++ lib/lp/soyuz/doc/build-failedtoupload-workflow.txt 2010-04-05 18:28:37 +0000 |
666 | @@ -85,7 +85,7 @@ |
667 | * Architecture: i386 |
668 | * Archive: ubuntu primary archive |
669 | * Component: main |
670 | - * State: Failed to upload |
671 | + * State: Could not be uploaded correctly |
672 | * Duration: a minute |
673 | * Build Log: http://launchpad.dev/ubuntu/+source/cdrkit/1.0/+build/22/+fil= |
674 | es/netapplet-1.0.0.tar.gz |
675 | |
676 | === modified file 'lib/lp/soyuz/doc/build-notification.txt' |
677 | --- lib/lp/soyuz/doc/build-notification.txt 2010-03-06 04:57:40 +0000 |
678 | +++ lib/lp/soyuz/doc/build-notification.txt 2010-04-05 18:28:37 +0000 |
679 | @@ -178,7 +178,7 @@ |
680 | * Architecture: i386 |
681 | * Archive: ubuntu primary archive |
682 | * Component: main |
683 | - * State: Needs building |
684 | + * State: Pending build |
685 | * Duration: not available |
686 | * Build Log: not available |
687 | * Builder: not available |
688 | @@ -314,7 +314,7 @@ |
689 | * Architecture: i386 |
690 | * Archive: ubuntu primary archive |
691 | * Component: main |
692 | - * State: Build for superseded Source |
693 | + * State: Could not build because source package was superseded |
694 | * Duration: not available |
695 | * Build Log: not available |
696 | * Builder: not available |
697 | |
698 | === modified file 'lib/lp/soyuz/doc/build.txt' |
699 | --- lib/lp/soyuz/doc/build.txt 2010-03-06 04:57:40 +0000 |
700 | +++ lib/lp/soyuz/doc/build.txt 2010-04-05 18:28:37 +0000 |
701 | @@ -63,7 +63,7 @@ |
702 | CHROOTWAIT, SUPERSEDED and FAILEDTOUPLOAD). |
703 | |
704 | >>> firefox_build.buildstate |
705 | - <DBItem BuildStatus.FULLYBUILT, (1) Successfully built> |
706 | + <DBItem BuildStatus.FULLYBUILT, (1) Successful build> |
707 | |
708 | Builds which were already processed also offer additional information |
709 | about its process such as the time it was started and finished and its |
710 | |
711 | === modified file 'lib/lp/soyuz/doc/buildd-mass-retry.txt' |
712 | --- lib/lp/soyuz/doc/buildd-mass-retry.txt 2009-04-28 12:59:43 +0000 |
713 | +++ lib/lp/soyuz/doc/buildd-mass-retry.txt 2010-04-05 18:28:37 +0000 |
714 | @@ -40,9 +40,9 @@ |
715 | DEBUG Intitialising connection. |
716 | INFO Initialising Build Mass-Retry for 'The Hoary Hedgehog Release/RELEASE' |
717 | INFO Processing builds in 'Failed to build' |
718 | - INFO Processing builds in 'Dependency wait' |
719 | + INFO Processing builds in 'Could not build because of missing dependencies' |
720 | INFO Retrying i386 build of libstdc++ b8p in ubuntu hoary RELEASE (12) |
721 | - INFO Processing builds in 'Chroot problem' |
722 | + INFO Processing builds in 'Could not build because of chroot problem' |
723 | INFO Success. |
724 | INFO Dry-run. |
725 | <BLANKLINE> |
726 | @@ -62,8 +62,8 @@ |
727 | DEBUG Intitialising connection. |
728 | INFO Initialising Build Mass-Retry for 'The Hoary Hedgehog Release for hppa (hppa)/RELEASE' |
729 | INFO Processing builds in 'Failed to build' |
730 | - INFO Processing builds in 'Dependency wait' |
731 | - INFO Processing builds in 'Chroot problem' |
732 | + INFO Processing builds in 'Could not build because of missing dependencies' |
733 | + INFO Processing builds in 'Could not build because of chroot problem' |
734 | INFO Success. |
735 | INFO Dry-run. |
736 | <BLANKLINE> |
737 | |
738 | === modified file 'lib/lp/soyuz/doc/buildd-slavescanner.txt' |
739 | --- lib/lp/soyuz/doc/buildd-slavescanner.txt 2010-03-24 04:51:25 +0000 |
740 | +++ lib/lp/soyuz/doc/buildd-slavescanner.txt 2010-04-05 18:28:37 +0000 |
741 | @@ -298,7 +298,7 @@ |
742 | >>> build.dependencies |
743 | u'baz (>= 1.0.1)' |
744 | >>> build.buildstate.title |
745 | - 'Dependency wait' |
746 | + 'Could not build because of missing dependencies' |
747 | |
748 | WAITING - CHROOTFAIL -> the Chroot for this distroseries is damage, nor |
749 | builder, but right state stored in Build entry: |
750 | @@ -325,7 +325,7 @@ |
751 | >>> check_mail_sent(last_stub_mail_count) |
752 | True |
753 | >>> build.buildstate.title |
754 | - 'Chroot problem' |
755 | + 'Could not build because of chroot problem' |
756 | |
757 | WAITING - BUILDERFAIL -> builder has failed by internal error, job is available for next build round: |
758 | |
759 | @@ -352,7 +352,7 @@ |
760 | False |
761 | >>> build = getUtility(IBuildSet).getByQueueEntry(bqItem6) |
762 | >>> print build.buildstate.title |
763 | - Needs building |
764 | + Pending build |
765 | >>> job = bqItem6.specific_job.job |
766 | >>> print job.status.title |
767 | Waiting |
768 | @@ -473,7 +473,7 @@ |
769 | >>> check_mail_sent(last_stub_mail_count) |
770 | True |
771 | >>> build.buildstate.title |
772 | - 'Failed to upload' |
773 | + 'Could not be uploaded correctly' |
774 | |
775 | Let's check the emails generated by this 'failure' |
776 | (see build-failedtoupload-workflow.txt for more information): |
777 | @@ -564,7 +564,7 @@ |
778 | >>> build.buildlog is not None |
779 | True |
780 | >>> build.buildstate.title |
781 | - 'Successfully built' |
782 | + 'Successful build' |
783 | >>> check_mail_sent(last_stub_mail_count) |
784 | False |
785 | |
786 | @@ -602,7 +602,7 @@ |
787 | False |
788 | >>> build = getUtility(IBuildSet).getByQueueEntry(bqItem11) |
789 | >>> print build.buildstate.title |
790 | - Needs building |
791 | + Pending build |
792 | >>> job = bqItem11.specific_job.job |
793 | >>> print job.status.title |
794 | Waiting |
795 | |
796 | === modified file 'lib/lp/soyuz/doc/gina.txt' |
797 | --- lib/lp/soyuz/doc/gina.txt 2010-03-17 05:48:45 +0000 |
798 | +++ lib/lp/soyuz/doc/gina.txt 2010-04-05 18:28:37 +0000 |
799 | @@ -366,7 +366,7 @@ |
800 | >>> print ed.build.processor.name |
801 | 386 |
802 | >>> print ed.build.buildstate |
803 | - Successfully built |
804 | + Successful build |
805 | >>> print ed.build.distroarchseries.processorfamily.name |
806 | x86 |
807 | >>> print ed.build.distroarchseries.architecturetag |
808 | |
809 | === modified file 'lib/lp/soyuz/stories/ppa/xx-copy-packages.txt' |
810 | --- lib/lp/soyuz/stories/ppa/xx-copy-packages.txt 2010-03-10 13:28:55 +0000 |
811 | +++ lib/lp/soyuz/stories/ppa/xx-copy-packages.txt 2010-04-05 18:28:37 +0000 |
812 | @@ -299,7 +299,7 @@ |
813 | James Blackwell |
814 | PPA for James Blackwell |
815 | i386 build of pmount 0.1-1 |
816 | - Build status Needs building |
817 | + Build status Pending build |
818 | Start (2505) What's this? |
819 | Build details |
820 | Source: pmount - 0.1-1 |
821 | |
822 | === modified file 'lib/lp/soyuz/stories/soyuz/xx-build-record.txt' |
823 | --- lib/lp/soyuz/stories/soyuz/xx-build-record.txt 2010-03-10 13:28:55 +0000 |
824 | +++ lib/lp/soyuz/stories/soyuz/xx-build-record.txt 2010-04-05 18:28:37 +0000 |
825 | @@ -62,7 +62,7 @@ |
826 | i386 build of testing 1.0 in ubuntutest breezy-autotest RELEASE |
827 | ... |
828 | Build status |
829 | - Needs building |
830 | + Pending build |
831 | Start in ... (2505) What's this? |
832 | Build details |
833 | Source: testing - 1.0 |
834 | @@ -82,7 +82,7 @@ |
835 | i386 build of testing 1.0 in ubuntutest breezy-autotest RELEASE |
836 | ... |
837 | Build status |
838 | - Needs building |
839 | + Pending build |
840 | Build details |
841 | Source: testing - 1.0 |
842 | Archive: Primary Archive for Ubuntu Test |
843 | @@ -134,7 +134,7 @@ |
844 | |
845 | >>> print extract_text(find_tag_by_id(admin_browser.contents, 'status')) |
846 | Build status |
847 | - Needs building |
848 | + Pending build |
849 | Start in ... (0) Rescore build What's this? |
850 | |
851 | Eventually a pending build record will get started, and while it's |
852 | @@ -203,7 +203,7 @@ |
853 | >>> print extract_text( |
854 | ... find_tag_by_id(anon_browser.contents, 'status')) |
855 | Build status |
856 | - Failed to upload on Bob The Builder |
857 | + Could not be uploaded correctly on Bob The Builder |
858 | Started ... ago |
859 | Finished ... (took 1 minute, 0.0 seconds) |
860 | buildlog (7 bytes) |
861 | @@ -229,7 +229,8 @@ |
862 | >>> print extract_text( |
863 | ... find_tag_by_id(admin_browser.contents, 'status')) |
864 | Build status |
865 | - Failed to upload on Bob The Builder Retry this build |
866 | + Could not be uploaded correctly |
867 | + on Bob The Builder Retry this build |
868 | Started ... ago |
869 | Finished ... (took 1 minute, 0.0 seconds) |
870 | buildlog (7 bytes) |
871 | @@ -246,7 +247,7 @@ |
872 | Retry i386 build of testing 1.0 in ubuntutest breezy-autotest RELEASE |
873 | ... |
874 | The status of i386 build of testing 1.0 in ubuntutest |
875 | - breezy-autotest RELEASE is Failed to upload. |
876 | + breezy-autotest RELEASE is Could not be uploaded correctly. |
877 | Retrying this build will destroy its history and logs. |
878 | By default, this build will be retried only after other pending |
879 | builds; please contact a build daemon administrator if you need |
880 | @@ -260,7 +261,7 @@ |
881 | >>> print extract_text( |
882 | ... find_tag_by_id(admin_browser.contents, 'status')) |
883 | Build status |
884 | - Failed to upload on Bob The Builder Retry this build |
885 | + Could not be uploaded correctly on Bob The Builder Retry this build |
886 | Started ... ago |
887 | Finished ... (took 1 minute, 0.0 seconds) |
888 | buildlog (7 bytes) |
889 | @@ -278,7 +279,7 @@ |
890 | |
891 | >>> print extract_text(find_tag_by_id(admin_browser.contents, 'status')) |
892 | Build status |
893 | - Needs building |
894 | + Pending build |
895 | Start in ... (0) Rescore build What's this? |
896 | |
897 | >>> admin_browser.getLink("Retry this build").click() |
898 | @@ -315,7 +316,7 @@ |
899 | >>> print extract_text( |
900 | ... find_tag_by_id(anon_browser.contents, 'status')) |
901 | Build status |
902 | - Successfully built on Bob The Builder |
903 | + Successful build on Bob The Builder |
904 | Started on 2008-01-01 |
905 | Finished on 2008-01-01 (took 5 minutes, 0.0 seconds) |
906 | buildlog (6 bytes) |
907 | @@ -452,7 +453,7 @@ |
908 | |
909 | >>> print extract_text(find_tag_by_id(anon_browser.contents, 'status')) |
910 | Build status |
911 | - Successfully built on Bob The Builder |
912 | + Successful build on Bob The Builder |
913 | Started on ... |
914 | Finished on ... (took 5 minutes, 0.0 seconds) |
915 | buildlog (6 bytes) |
916 | |
917 | === modified file 'lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt' |
918 | --- lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt 2010-03-08 09:19:45 +0000 |
919 | +++ lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt 2010-04-05 18:28:37 +0000 |
920 | @@ -136,17 +136,17 @@ |
921 | |
922 | >>> print_build_rows(anon_browser.contents) |
923 | ------------------------------ |
924 | - Successfully built |
925 | + Successful build |
926 | hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE |
927 | Build started on 2007-08-10 on Bob The Builder and finished on 2007-08-10 |
928 | taking 15 seconds — see the log |
929 | ------------------------------ |
930 | - Successfully built |
931 | + Successful build |
932 | i386 build of commercialpackage 1.0-1 in ubuntu breezy-autotest RELEASE |
933 | Build started at an unknown time on an unknown build machine and finished |
934 | on 2007-08-09 taking |
935 | ------------------------------ |
936 | - Failed to upload |
937 | + Could not be uploaded correctly |
938 | i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE |
939 | Build started on 2007-04-19 on Bob The Builder and finished on 2007-04-20 |
940 | taking a minute — see the log |
941 | @@ -164,23 +164,23 @@ |
942 | >>> anon_browser.getLink("Next").click() |
943 | >>> print_build_rows(anon_browser.contents) |
944 | ------------------------------ |
945 | - Build for superseded Source |
946 | + Could not build because source package was superseded |
947 | i386 build of at 0.00 in ubuntu warty RELEASE |
948 | ------------------------------ |
949 | - Build for superseded Source |
950 | + Could not build because source package was superseded |
951 | i386 build of linux-source-2.6.15 2.6.15.3 in ubuntu warty RELEASE |
952 | ------------------------------ |
953 | - Build for superseded Source |
954 | + Could not build because source package was superseded |
955 | i386 build of netapplet 0.99.6-1 in ubuntu warty RELEASE |
956 | ------------------------------ |
957 | - Dependency wait |
958 | + Could not build because of missing dependencies |
959 | i386 build of libstdc++ b8p in ubuntu hoary RELEASE |
960 | Missing dependencies: |
961 | cpp (>= 4:4.0.1-3), gcc-4.0 (>= 4.0.1-2) |
962 | Build started on 2006-02-27 on Bob The Builder and finished on 2006-02-28 |
963 | taking six minutes — see the log |
964 | ------------------------------ |
965 | - Needs building |
966 | + Pending build |
967 | i386 build of alsa-utils 1.0.9a-4ubuntu1 in ubuntu hoary RELEASE |
968 | Pending (10) |
969 | ------------------------------ |
970 | @@ -193,27 +193,27 @@ |
971 | >>> anon_browser.getControl("Filter").click() |
972 | >>> print_build_rows(anon_browser.contents) |
973 | ------------------------------ |
974 | - Successfully built |
975 | + Successful build |
976 | hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE |
977 | Build started on 2007-08-10 on Bob The Builder and finished on 2007-08-10 |
978 | taking 15 seconds — see the log |
979 | ------------------------------ |
980 | - Successfully built |
981 | + Successful build |
982 | i386 build of commercialpackage 1.0-1 in ubuntu breezy-autotest RELEASE |
983 | Build started at an unknown time on an unknown build machine and finished |
984 | on 2007-08-09 taking |
985 | ------------------------------ |
986 | - Successfully built |
987 | + Successful build |
988 | i386 build of pmount 0.1-1 in ubuntu hoary RELEASE |
989 | Build started on 2005-03-24 on Bob The Builder and finished on 2005-03-25 |
990 | taking a minute — see the log |
991 | ------------------------------ |
992 | - Successfully built |
993 | + Successful build |
994 | hppa build of pmount 0.1-1 in ubuntu hoary RELEASE |
995 | Build started on 2005-03-24 on Bob The Builder and finished on 2005-03-25 |
996 | taking a minute — see the log |
997 | ------------------------------ |
998 | - Successfully built |
999 | + Successful build |
1000 | i386 build of pmount 0.1-1 in ubuntu breezy-autotest RELEASE |
1001 | Build started on 2005-03-24 on Bob The Builder and finished on 2005-03-25 |
1002 | taking a minute — see the log |
1003 | @@ -223,7 +223,7 @@ |
1004 | >>> anon_browser.getControl("Filter").click() |
1005 | >>> print_build_rows(anon_browser.contents) |
1006 | ------------------------------ |
1007 | - Dependency wait |
1008 | + Could not build because of missing dependencies |
1009 | i386 build of libstdc++ b8p in ubuntu hoary RELEASE |
1010 | Missing dependencies: |
1011 | cpp (>= 4:4.0.1-3), gcc-4.0 (>= 4.0.1-2) |
1012 | @@ -301,17 +301,17 @@ |
1013 | |
1014 | >>> print_build_rows(anon_browser.contents) |
1015 | ------------------------------ |
1016 | - Successfully built |
1017 | - hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE |
1018 | - Build started on 2007-08-10 and finished on 2007-08-10 |
1019 | - taking 15 seconds — see the log |
1020 | - ------------------------------ |
1021 | - Successfully built |
1022 | - hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE |
1023 | - Build started on 2007-08-10 and finished on 2007-08-10 |
1024 | - taking 15 seconds — see the log |
1025 | - ------------------------------ |
1026 | - Successfully built |
1027 | + Successful build |
1028 | + hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE |
1029 | + Build started on 2007-08-10 and finished on 2007-08-10 |
1030 | + taking 15 seconds — see the log |
1031 | + ------------------------------ |
1032 | + Successful build |
1033 | + hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE |
1034 | + Build started on 2007-08-10 and finished on 2007-08-10 |
1035 | + taking 15 seconds — see the log |
1036 | + ------------------------------ |
1037 | + Successful build |
1038 | i386 build of pmount 0.1-1 in ubuntu warty RELEASE |
1039 | Build started on 2007-07-23 and finished on 2007-07-24 |
1040 | taking a minute — see the log |
1041 | @@ -334,7 +334,7 @@ |
1042 | >>> anon_browser.getLink("Next").click() |
1043 | >>> print_build_rows(anon_browser.contents) |
1044 | ------------------------------ |
1045 | - Failed to upload |
1046 | + Could not be uploaded correctly |
1047 | i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE |
1048 | Build started on 2007-04-19 and finished on 2007-04-20 |
1049 | taking a minute — see the log |
1050 | @@ -344,13 +344,13 @@ |
1051 | Build started on 2006-12-01 and finished on 2006-12-01 |
1052 | taking 1 second — see the log |
1053 | ------------------------------ |
1054 | - Build for superseded Source |
1055 | + Could not build because source package was superseded |
1056 | i386 build of netapplet 0.99.6-1 in ubuntu warty RELEASE |
1057 | ------------------------------ |
1058 | - Build for superseded Source |
1059 | + Could not build because source package was superseded |
1060 | i386 build of linux-source-2.6.15 2.6.15.3 in ubuntu warty RELEASE |
1061 | ------------------------------ |
1062 | - Build for superseded Source |
1063 | + Could not build because source package was superseded |
1064 | i386 build of at 0.00 in ubuntu warty RELEASE |
1065 | ------------------------------ |
1066 | |
1067 | @@ -360,7 +360,7 @@ |
1068 | >>> anon_browser.getLink("Next").click() |
1069 | >>> print_build_rows(anon_browser.contents) |
1070 | ------------------------------ |
1071 | - Dependency wait |
1072 | + Could not build because of missing dependencies |
1073 | i386 build of libstdc++ b8p in ubuntu hoary RELEASE |
1074 | Missing dependencies: |
1075 | cpp (>= 4:4.0.1-3), gcc-4.0 (>= 4.0.1-2) |
1076 | |
1077 | === modified file 'lib/lp/soyuz/stories/soyuz/xx-private-builds.txt' |
1078 | --- lib/lp/soyuz/stories/soyuz/xx-private-builds.txt 2010-03-08 13:07:07 +0000 |
1079 | +++ lib/lp/soyuz/stories/soyuz/xx-private-builds.txt 2010-04-05 18:28:37 +0000 |
1080 | @@ -338,7 +338,7 @@ |
1081 | >>> portlet = find_portlet(browser.contents, 'Builds') |
1082 | >>> print extract_text(portlet) |
1083 | Builds |
1084 | - breezy-autotest i386 Successfully built |
1085 | + breezy-autotest i386 Successful build |
1086 | |
1087 | >>> print browser.getLink('i386').url |
1088 | http://launchpad.dev/~cprov/+archive/p3a/+build/... |
1089 | |
1090 | === modified file 'lib/lp/testing/factory.py' |
1091 | --- lib/lp/testing/factory.py 2010-04-05 17:40:35 +0000 |
1092 | +++ lib/lp/testing/factory.py 2010-04-05 18:28:37 +0000 |
1093 | @@ -1622,12 +1622,14 @@ |
1094 | |
1095 | def makeDistroRelease(self, distribution=None, version=None, |
1096 | status=SeriesStatus.DEVELOPMENT, |
1097 | - parent_series=None, name=None): |
1098 | + parent_series=None, name=None, displayname=None): |
1099 | """Make a new distro release.""" |
1100 | if distribution is None: |
1101 | distribution = self.makeDistribution() |
1102 | if name is None: |
1103 | name = self.getUniqueString() |
1104 | + if displayname is None: |
1105 | + displayname = name.capitalize() |
1106 | if version is None: |
1107 | version = "%s.0" % self.getUniqueInteger() |
1108 | |
1109 | @@ -1637,7 +1639,7 @@ |
1110 | series = naked_distribution.newSeries( |
1111 | version=version, |
1112 | name=name, |
1113 | - displayname=name.capitalize(), |
1114 | + displayname=displayname, |
1115 | title=self.getUniqueString(), summary=self.getUniqueString(), |
1116 | description=self.getUniqueString(), |
1117 | parent_series=parent_series, owner=distribution.owner) |
1118 | @@ -1716,7 +1718,7 @@ |
1119 | |
1120 | def makeBuilder(self, processor=None, url=None, name=None, title=None, |
1121 | description=None, owner=None, active=True, |
1122 | - virtualized=True, vm_host=None): |
1123 | + virtualized=True, vm_host=None, manual=False): |
1124 | """Make a new builder for i386 virtualized builds by default. |
1125 | |
1126 | Note: the builder returned will not be able to actually build - |
1127 | @@ -1740,7 +1742,7 @@ |
1128 | |
1129 | return getUtility(IBuilderSet).new( |
1130 | processor, url, name, title, description, owner, active, |
1131 | - virtualized, vm_host) |
1132 | + virtualized, vm_host, manual=manual) |
1133 | |
1134 | def makeRecipe(self, *branches): |
1135 | """Make a builder recipe that references `branches`. |
1136 | @@ -1800,11 +1802,12 @@ |
1137 | |
1138 | def makeSourcePackageRecipeBuildJob( |
1139 | self, score=9876, virtualized=True, estimated_duration=64, |
1140 | - sourcename=None): |
1141 | + sourcename=None, recipe_build=None): |
1142 | """Create a `SourcePackageRecipeBuildJob` and a `BuildQueue` for |
1143 | testing.""" |
1144 | - recipe_build = self.makeSourcePackageRecipeBuild( |
1145 | - sourcename=sourcename) |
1146 | + if recipe_build is None: |
1147 | + recipe_build = self.makeSourcePackageRecipeBuild( |
1148 | + sourcename=sourcename) |
1149 | recipe_build_job = recipe_build.makeJob() |
1150 | |
1151 | store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR) |
Screenshot: people. canonical. com/~abentley/ recipe- index-review. png
http://