Merge lp:~blr/launchpad/ui-project-setbranch into lp:launchpad

Proposed by Kit Randel on 2015-06-25
Status: Superseded
Proposed branch: lp:~blr/launchpad/ui-project-setbranch
Merge into: lp:launchpad
Diff against target: 131 lines (+15/-11)
8 files modified
lib/lp/blueprints/browser/tests/test_specification.py (+1/-1)
lib/lp/bugs/browser/tests/test_bugtask.py (+2/-2)
lib/lp/code/browser/tests/test_branchmergeproposallisting.py (+2/-2)
lib/lp/code/browser/tests/test_gitlisting.py (+1/-1)
lib/lp/code/javascript/productseries-setbranch.js (+5/-2)
lib/lp/registry/browser/tests/pillar-views.txt (+2/-2)
lib/lp/registry/stories/webservice/xx-project-registry.txt (+1/-0)
lib/lp/registry/tests/test_product.py (+1/-1)
To merge this branch: bzr merge lp:~blr/launchpad/ui-project-setbranch
Reviewer Review Type Date Requested Status
William Grant code 2015-06-25 Approve on 2015-06-25
Review via email: mp+262942@code.launchpad.net

This proposal supersedes a proposal from 2015-05-14.

This proposal has been superseded by a proposal from 2015-06-25.

Commit Message

Add Product.ProductSetBranchView and UI support for setting product.vcs.

Description of the Change

Provides a new SetBranch view for projects, additionally allowing a default version control system to be defined.

A project's vcs will also be displayed on the product index under Project Information. If not default vcs has been provided, the vcs type is inferred from existing bzr or git branches, with git taking precedence.

Fixes bug in setTargetDefault where an exception was thrown when attempting to set the same targetdefault again.

Testfixed.

To post a comment you must log in.
William Grant (wgrant) wrote : Posted in a previous version of this proposal

Various code/style comments inline, UX design comments here:

In almost all cases the user will care about at most one VCS. Everything relating to the other VCS is just noise unless that VCS is selected (or a migration is in progress, or they're doing something weird). So the page should start by asking for the project's VCS (not a "default VCS" in the UI), defaulting to Bazaar until our Git support is more complete.

Once you've selected a VCS (not a "default VCS" in the UI) there are three options: push a new repo, choose an existing repo, or mirror a repo from elsewhere. The other VCS's config has to be available too, but it needn't be visible without an extra click.

The "push a new repo" case is handled by the push instructions. But they can be simpler, because the project owner can always create defaults if they don't exist: the Git URL should be git+ssh://user@host/project, and the Bazaar URL lp:project. The initial push instructions will also work fine to write to LP-hosted Bazaar branches or Git repositories, but they shouldn't be shown if the series Bazaar branch is already set and is an import, since those can't be written to directly.

The "choose an existing repo" case requires a selector widget, which can currently just be a textbox to specify a branch or repo path. The Bazaar case should stay as it is now, setting product.development_focus.branch, and the Git case should use setDefaultRepository.

The "mirror a repo from elsewhere" case can currently only exist for Bazaar, as we don't have Git mirroring yet. We can work out how that looks for Git when we get there.

review: Needs Fixing (code)
William Grant (wgrant) : Posted in a previous version of this proposal
review: Needs Fixing (code)
William Grant (wgrant) : Posted in a previous version of this proposal
review: Needs Fixing (code)
William Grant (wgrant) wrote : Posted in a previous version of this proposal

Just one last thing: when I suggested that is_series didn't need to be a property, I meant that it could be a plain attribute. Both implements return a constant value.

review: Approve (code)
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/blueprints/browser/tests/test_specification.py'
2--- lib/lp/blueprints/browser/tests/test_specification.py 2015-05-08 08:55:40 +0000
3+++ lib/lp/blueprints/browser/tests/test_specification.py 2015-06-25 07:41:58 +0000
4@@ -246,7 +246,7 @@
5 product = self.factory.makeProduct()
6 removeSecurityProxy(product).official_blueprints = True
7 self.factory.makeSpecification(product=product)
8- limit = BrowsesWithQueryLimit(38, product.owner, rootsite='blueprints')
9+ limit = BrowsesWithQueryLimit(42, product.owner, rootsite='blueprints')
10 self.assertThat(product, limit)
11 login_celebrity('admin')
12 [self.factory.makeSpecification(product=product) for i in range(4)]
13
14=== modified file 'lib/lp/bugs/browser/tests/test_bugtask.py'
15--- lib/lp/bugs/browser/tests/test_bugtask.py 2015-01-29 16:28:30 +0000
16+++ lib/lp/bugs/browser/tests/test_bugtask.py 2015-06-25 07:41:58 +0000
17@@ -2065,10 +2065,10 @@
18 self.invalidate_caches(bug)
19 # count with single task
20 self.getUserBrowser(url)
21- self.assertThat(recorder, HasQueryCount(LessThan(35)))
22+ self.assertThat(recorder, HasQueryCount(LessThan(36)))
23 # count with many tasks
24 self.getUserBrowser(buggy_url)
25- self.assertThat(recorder, HasQueryCount(LessThan(35)))
26+ self.assertThat(recorder, HasQueryCount(LessThan(36)))
27
28 def test_mustache_model_in_json(self):
29 """The IJSONRequestCache should contain mustache_model.
30
31=== modified file 'lib/lp/code/browser/tests/test_branchmergeproposallisting.py'
32--- lib/lp/code/browser/tests/test_branchmergeproposallisting.py 2015-05-14 13:57:51 +0000
33+++ lib/lp/code/browser/tests/test_branchmergeproposallisting.py 2015-06-25 07:41:58 +0000
34@@ -265,7 +265,7 @@
35 with StormStatementRecorder() as recorder:
36 self.getViewBrowser(
37 product, '+merges', rootsite='code', user=product.owner)
38- self.assertThat(recorder, HasQueryCount(Equals(41)))
39+ self.assertThat(recorder, HasQueryCount(Equals(42)))
40
41 def test_query_count_git(self):
42 product = self.factory.makeProduct()
43@@ -280,7 +280,7 @@
44 with StormStatementRecorder() as recorder:
45 self.getViewBrowser(
46 product, '+merges', rootsite='code', user=product.owner)
47- self.assertThat(recorder, HasQueryCount(Equals(38)))
48+ self.assertThat(recorder, HasQueryCount(Equals(40)))
49
50 def test_productseries_bzr(self):
51 target = self.factory.makeBranch()
52
53=== modified file 'lib/lp/code/browser/tests/test_gitlisting.py'
54--- lib/lp/code/browser/tests/test_gitlisting.py 2015-06-12 12:18:30 +0000
55+++ lib/lp/code/browser/tests/test_gitlisting.py 2015-06-25 07:41:58 +0000
56@@ -109,7 +109,7 @@
57 repository=other_repo, user=other_repo.owner)
58
59 self.assertThat(
60- self.target, BrowsesWithQueryLimit(32, self.owner, '+git'))
61+ self.target, BrowsesWithQueryLimit(34, self.owner, '+git'))
62
63 def test_copes_with_no_default(self):
64 self.factory.makeGitRepository(
65
66=== modified file 'lib/lp/code/javascript/productseries-setbranch.js'
67--- lib/lp/code/javascript/productseries-setbranch.js 2015-06-19 01:10:52 +0000
68+++ lib/lp/code/javascript/productseries-setbranch.js 2015-06-25 07:41:58 +0000
69@@ -122,10 +122,13 @@
70 'click', module.onclick_default_vcs);
71
72 // Set the initial state.
73- module.setup_expanders();
74 module.onclick_rcs_type();
75 module.onclick_branch_type();
76- module.onclick_default_vcs();
77+ // Only setup handlers for +configure-code
78+ if (document.getElementById('default_vcs')) {
79+ module.setup_expanders();
80+ module.onclick_default_vcs();
81+ }
82 };
83
84 }, "0.1", {"requires": ["node", "DOM"]});
85
86=== modified file 'lib/lp/registry/browser/tests/pillar-views.txt'
87--- lib/lp/registry/browser/tests/pillar-views.txt 2015-06-15 06:47:11 +0000
88+++ lib/lp/registry/browser/tests/pillar-views.txt 2015-06-25 07:41:58 +0000
89@@ -87,7 +87,7 @@
90
91 >>> for link in view.configuration_links:
92 ... print link['link'].name
93- set_branch
94+ configure_code
95 configure_bugtracker
96 configure_translations
97 configure_answers
98@@ -141,7 +141,7 @@
99
100 >>> print find_tag_by_id(rendered, 'configuration_links')
101 <table...
102- <a href="http://launchpad.dev/bread/trunk/+setbranch"...
103+ <a href="http://launchpad.dev/bread/+configure-code"...
104 <span class="sprite no action-icon">...
105 <a href="http://launchpad.dev/bread/+configure-bugtracker"...
106 <span class="sprite no action-icon">...
107
108=== modified file 'lib/lp/registry/stories/webservice/xx-project-registry.txt'
109--- lib/lp/registry/stories/webservice/xx-project-registry.txt 2015-05-13 06:28:34 +0000
110+++ lib/lp/registry/stories/webservice/xx-project-registry.txt 2015-06-25 07:41:58 +0000
111@@ -168,6 +168,7 @@
112 freshmeat_project: None
113 homepage_url: None
114 icon_link: u'http://.../firefox/icon'
115+ inferred_vcs: u'Bazaar'
116 information_type: u'Public'
117 is_permitted: True
118 license_approved: False
119
120=== modified file 'lib/lp/registry/tests/test_product.py'
121--- lib/lp/registry/tests/test_product.py 2015-06-19 01:10:52 +0000
122+++ lib/lp/registry/tests/test_product.py 2015-06-25 07:41:58 +0000
123@@ -877,7 +877,7 @@
124 'getVersionSortedSeries',
125 'has_current_commercial_subscription',
126 'has_custom_language_codes', 'has_milestones', 'homepage_content',
127- 'homepageurl', 'invitesTranslationEdits',
128+ 'homepageurl', 'inferred_vcs', 'invitesTranslationEdits',
129 'invitesTranslationSuggestions',
130 'license_info', 'license_status', 'licenses', 'milestones',
131 'mugshot', 'newCodeImport',