Merge lp:~abentley/bzr/config-branchname into lp:bzr

Proposed by Aaron Bentley
Status: Merged
Approved by: John A Meinel
Approved revision: no longer in the source branch.
Merged at revision: 6526
Proposed branch: lp:~abentley/bzr/config-branchname
Merge into: lp:bzr
Diff against target: 111 lines (+49/-4)
3 files modified
bzrlib/config.py (+14/-4)
bzrlib/help_topics/en/configuration.txt (+12/-0)
bzrlib/tests/test_config.py (+23/-0)
To merge this branch: bzr merge lp:~abentley/bzr/config-branchname
Reviewer Review Type Date Requested Status
John A Meinel Approve
Review via email: mp+110825@code.launchpad.net

Commit message

Support branchname config variable.

Description of the change

This branch adds a "branchname" automatic config variable, which is the name of a native colocated branch, as specified by the "branch=" portion of its url. This allows the user to configure urls to reflect the branch name, just as they would use relpath or basename to configure other types of branches.

I have used it like so, in order to push this branch:
[/home/abentley/hacking/bzr]
push_location = bzr+ssh://bazaar.launchpad.net/~abentley/bzr/{branchname}

This is an itch that I am scratching. For me, the biggest advantage of bzr-colo colocation is that, since it uses standard branches, it can automatically configure the push and public locations. With this change, native colo branches will have parity in terms of configuration.

To post a comment you must log in.
Revision history for this message
James Westby (james-w) wrote :

On Mon, 18 Jun 2012 14:00:27 -0000, Aaron Bentley <email address hidden> wrote:
> +Another such option is ``branchname``, which refers to the name of a colocated
> +branch. It can be used like this::

Is it just colocated branches, or does it work for all local branches?
It seems like this could work for pipelines with much the same
configuration if it does?

Thanks,

James

Revision history for this message
Aaron Bentley (abentley) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 12-06-18 10:28 AM, James Westby wrote:
> On Mon, 18 Jun 2012 14:00:27 -0000, Aaron Bentley
> <email address hidden> wrote:
>> +Another such option is ``branchname``, which refers to the name
>> of a colocated +branch. It can be used like this::
>
> Is it just colocated branches, or does it work for all local
> branches?

No, it only works for branches which have names specified in their url
via ",branch=$NAME". Only colocated branches have URLs like that.
But I don't think they are required to be local.

> It seems like this could work for pipelines with much the same
> configuration if it does?

For bzr-colo style pipelines, the "basename" config variable will work
just as well. But pipelines can also be used with native-colocated
branches.

Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk/fPPoACgkQ0F+nu1YWqI2zHwCeLpkIo+iTs1kBIiM3261w5+l3
3YUAoIcg/aupDuQQNYkzSmd5SI4v2PV+
=3pFD
-----END PGP SIGNATURE-----

Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 6/18/2012 4:40 PM, Aaron Bentley wrote:
> On 12-06-18 10:28 AM, James Westby wrote:
>> On Mon, 18 Jun 2012 14:00:27 -0000, Aaron Bentley
>> <email address hidden> wrote:
>>> +Another such option is ``branchname``, which refers to the
>>> name of a colocated +branch. It can be used like this::
>
>> Is it just colocated branches, or does it work for all local
>> branches?
>
> No, it only works for branches which have names specified in their
> url via ",branch=$NAME". Only colocated branches have URLs like
> that. But I don't think they are required to be local.
>
>> It seems like this could work for pipelines with much the same
>> configuration if it does?
>
> For bzr-colo style pipelines, the "basename" config variable will
> work just as well. But pipelines can also be used with
> native-colocated branches.
>
> Aaron

Would it be possible to have 'nick' available as a config variable
rather than 'branchname'? It seems that having to write things as
(basename or branchname) and not having a universal value is a bit odd.

John
=:->

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk/gh0AACgkQJdeBCYSNAAPaZQCgyB5ZRRYA+KDbx5jI7tDI19JB
a7IAnRqkPwxChQJhABs642462wOxftzC
=XsVC
-----END PGP SIGNATURE-----

Revision history for this message
Aaron Bentley (abentley) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

> Would it be possible to have 'nick' available as a config variable
> rather than 'branchname'? It seems that having to write things as
> (basename or branchname) and not having a universal value is a bit
> odd.

I agree that it would be nice to have a single thing that worked for
all of them.

It's possible to use 'nick', but that's expensive, changes the
locations.conf paradigm and introduces new failure modes.

It's expensive because of explicit nicks. It requires opening a
branch, and it can cause network traffic.

locations.conf has always configured locations, not branches, and this
would change that paradigm.

It would mean that locations.conf would need to handle branch-opening
failures, something it's never considered before.

Maybe we should drop the concept of explicit nicks. I think they're
pretty rarely used. If nicks could be calculated from URL alone, all
the above issues go away.

Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk/gjgIACgkQ0F+nu1YWqI1pHQCePUU3JoBb8yFBACOx0ON/EM92
8eAAn19kIIMLT+/f1uIyaKGeuQTPHi0m
=iq4E
-----END PGP SIGNATURE-----

Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 6/19/2012 4:37 PM, Aaron Bentley wrote:
>> Would it be possible to have 'nick' available as a config
>> variable rather than 'branchname'? It seems that having to write
>> things as (basename or branchname) and not having a universal
>> value is a bit odd.
>
> I agree that it would be nice to have a single thing that worked
> for all of them.
>
> It's possible to use 'nick', but that's expensive, changes the
> locations.conf paradigm and introduces new failure modes.
>
> It's expensive because of explicit nicks. It requires opening a
> branch, and it can cause network traffic.
>
> locations.conf has always configured locations, not branches, and
> this would change that paradigm.
>
> It would mean that locations.conf would need to handle
> branch-opening failures, something it's never considered before.
>
> Maybe we should drop the concept of explicit nicks. I think
> they're pretty rarely used. If nicks could be calculated from URL
> alone, all the above issues go away.
>
> Aaron

We could call it 'branchshortname' or something along those lines,
that would be essentially (basename or branchname).

I would be happy enough to have 'branchname' that worked along those
lines. (if ,branch=? then ?, else basename)

John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk/gkIMACgkQJdeBCYSNAAPJ9ACfd49jxU2EdK7E/IKKctYc9+Aa
kc4AoK3LAhELgZ5soq771eyD+jixmPVO
=YUXp
-----END PGP SIGNATURE-----

Revision history for this message
Aaron Bentley (abentley) wrote :

I've made the changes you requested.

Revision history for this message
John A Meinel (jameinel) wrote :

Offhand it feels like we would need to unescape the basename if we are unescaping the branch portion. However your test seems to clearly state that isn't the case. That indicates we prob have an API issue (similar commands return different types, eg escaped URLs vs Unicode). But that isn't something you need to fix in this branch.

The doc seems a bit incomplete as it only indicates branchname works with Colo branches.

review: Approve
Revision history for this message
Aaron Bentley (abentley) wrote :

> Offhand it feels like we would need to unescape the basename if we are
> unescaping the branch portion. However your test seems to clearly state that
> isn't the case. That indicates we prob have an API issue (similar commands
> return different types, eg escaped URLs vs Unicode). But that isn't something
> you need to fix in this branch.

We don't need to unescape the basename because for file:/// URLs, self.location is set to a filesystem path. This matches the behaviour of our existing config mechamism. However, I've realized it's really a bug, because it means that unescaping is not done for other URL types. I've filed bug #1015570 about this.

> The doc seems a bit incomplete as it only indicates branchname works with Colo
> branches.

I added this to the docs: For non-colocated branches, it behaves like basename.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/config.py'
2--- bzrlib/config.py 2012-05-16 08:54:21 +0000
3+++ bzrlib/config.py 2012-06-20 15:19:22 +0000
4@@ -3444,11 +3444,14 @@
5
6 class LocationSection(Section):
7
8- def __init__(self, section, extra_path):
9+ def __init__(self, section, extra_path, branch_name=None):
10 super(LocationSection, self).__init__(section.id, section.options)
11 self.extra_path = extra_path
12+ if branch_name is None:
13+ branch_name = ''
14 self.locals = {'relpath': extra_path,
15- 'basename': urlutils.basename(extra_path)}
16+ 'basename': urlutils.basename(extra_path),
17+ 'branchname': branch_name}
18
19 def get(self, name, default=None, expand=True):
20 value = super(LocationSection, self).get(name, default)
21@@ -3524,9 +3527,15 @@
22
23 def __init__(self, store, location):
24 super(LocationMatcher, self).__init__(store)
25+ url, params = urlutils.split_segment_parameters(location)
26 if location.startswith('file://'):
27 location = urlutils.local_path_from_url(location)
28 self.location = location
29+ branch_name = params.get('branch')
30+ if branch_name is None:
31+ self.branch_name = urlutils.basename(self.location)
32+ else:
33+ self.branch_name = urlutils.unescape(branch_name)
34
35 def _get_matching_sections(self):
36 """Get all sections matching ``location``."""
37@@ -3558,8 +3567,9 @@
38 while True:
39 section = iter_all_sections.next()
40 if section_id == section.id:
41- matching_sections.append(
42- (length, LocationSection(section, extra_path)))
43+ section = LocationSection(section, extra_path,
44+ self.branch_name)
45+ matching_sections.append((length, section))
46 break
47 return matching_sections
48
49
50=== modified file 'bzrlib/help_topics/en/configuration.txt'
51--- bzrlib/help_topics/en/configuration.txt 2011-11-14 16:36:31 +0000
52+++ bzrlib/help_topics/en/configuration.txt 2012-06-20 15:19:22 +0000
53@@ -333,6 +333,18 @@
54 itself is defined as the relative path between the section name and the
55 location it matches.
56
57+Another such option is ``branchname``, which refers to the name of a colocated
58+branch. For non-colocated branches, it behaves like basename. It can be used
59+like this::
60+
61+ [/home/vila/src/bzr/bugs]
62+ mypush = lp:~vila/bzr/{branchname}
63+
64+When used with a colocated branch named ``832013-expand-in-stack``, we'll get::
65+
66+ bzr config mypush
67+ lp:~vila/bzr/832013-expand-in-stack
68+
69 When an option is local to a Section, it cannot be referred to from option
70 values in any other section from the same ``Store`` nor from any other
71 ``Store``.
72
73=== modified file 'bzrlib/tests/test_config.py'
74--- bzrlib/tests/test_config.py 2012-06-18 11:43:07 +0000
75+++ bzrlib/tests/test_config.py 2012-06-20 15:19:22 +0000
76@@ -17,6 +17,7 @@
77 """Tests for finding and reading the bzr config file[s]."""
78 # import system imports here
79 from cStringIO import StringIO
80+from textwrap import dedent
81 import os
82 import sys
83 import threading
84@@ -3418,6 +3419,28 @@
85 matcher = config.LocationMatcher(store, expected_url)
86 self.assertEquals(expected_location, matcher.location)
87
88+ def test_branch_name_colo(self):
89+ store = self.get_store(self)
90+ store._load_from_string(dedent("""\
91+ [/]
92+ push_location=my{branchname}
93+ """))
94+ matcher = config.LocationMatcher(store, 'file:///,branch=example%3c')
95+ self.assertEqual('example<', matcher.branch_name)
96+ ((_, section),) = matcher.get_sections()
97+ self.assertEqual('example<', section.locals['branchname'])
98+
99+ def test_branch_name_basename(self):
100+ store = self.get_store(self)
101+ store._load_from_string(dedent("""\
102+ [/]
103+ push_location=my{branchname}
104+ """))
105+ matcher = config.LocationMatcher(store, 'file:///parent/example%3c')
106+ self.assertEqual('example<', matcher.branch_name)
107+ ((_, section),) = matcher.get_sections()
108+ self.assertEqual('example<', section.locals['branchname'])
109+
110
111 class TestStartingPathMatcher(TestStore):
112