Merge lp:~ian-clatworthy/bzr/411413-plugin-disable into lp:bzr
- 411413-plugin-disable
- Merge into bzr.dev
Status: | Work in progress |
---|---|
Proposed branch: | lp:~ian-clatworthy/bzr/411413-plugin-disable |
Merge into: | lp:bzr |
Diff against target: |
229 lines (+82/-14) 6 files modified
NEWS (+3/-0) bzrlib/config.py (+9/-0) bzrlib/help_topics/en/configuration.txt (+17/-5) bzrlib/plugin.py (+23/-8) bzrlib/tests/test_config.py (+29/-0) bzrlib/tests/test_plugins.py (+1/-1) |
To merge this branch: | bzr merge lp:~ian-clatworthy/bzr/411413-plugin-disable |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
John A Meinel | Needs Fixing | ||
Review via email: mp+16719@code.launchpad.net |
Commit message
Description of the change
Martin Pool (mbp) wrote : | # |
That's a nice feature, thanks for adding it.
Eventually, if a plugin is disabled, it would be nice for this to be reflected in 'bzr plugins'.
It would be nice too to have -Ddisable_
The documentation is unclear about whether you specify eg ~/.bazaar/
I think setting it to empty to mean disabled is a bit strange but not necessarily wrong.
Ian Clatworthy (ian-clatworthy) wrote : | # |
> Eventually, if a plugin is disabled, it would be nice for this to be reflected
> in 'bzr plugins'.
Agreed. That can easily come later.
> The documentation is unclear about whether you specify eg
> ~/.bazaar/
It's the parent. I had hoped the example in the doc made that clear. Matching on the parent is the easiest to code and makes the most sense for plugins that aren't modules. I do wonder whether it's what users would expect though. OTOH, the 90% game here is disabling so maybe it's not worth worrying about too much?
Robert Collins (lifeless) wrote : | # |
I suggest limiting the feature to just disabling plugins - overriding
plugins is a separately requested feature and does need to be able to
specify the exact path. Vincent and I have been talking about a
BZR_PLUGINS_PATH syntax for doing it.
-Rob
Martin Pool (mbp) wrote : | # |
2010/1/4 Robert Collins <email address hidden>:
> I suggest limiting the feature to just disabling plugins - overriding
> plugins is a separately requested feature and does need to be able to
> specify the exact path. Vincent and I have been talking about a
> BZR_PLUGINS_PATH syntax for doing it.
I'd like to not add ad-hoc environment variables for things that could
reasonably be configured elsewhere. Let's put it into the config
system and then have a way to take config from the environment.
--
Martin <http://
Robert Collins (lifeless) wrote : | # |
On Mon, 2010-01-04 at 22:08 +1100, Martin Pool wrote:
> 2010/1/4 Robert Collins <email address hidden>:
> > I suggest limiting the feature to just disabling plugins - overriding
> > plugins is a separately requested feature and does need to be able to
> > specify the exact path. Vincent and I have been talking about a
> > BZR_PLUGINS_PATH syntax for doing it.
>
> I'd like to not add ad-hoc environment variables for things that could
> reasonably be configured elsewhere. Let's put it into the config
> system and then have a way to take config from the environment.
This isn't an adhoc environment variable - it already exists.
-Rob
Martin Pool (mbp) wrote : | # |
2010/1/5 Robert Collins <email address hidden>:
> On Mon, 2010-01-04 at 22:08 +1100, Martin Pool wrote:
>> 2010/1/4 Robert Collins <email address hidden>:
>> > I suggest limiting the feature to just disabling plugins - overriding
>> > plugins is a separately requested feature and does need to be able to
>> > specify the exact path. Vincent and I have been talking about a
>> > BZR_PLUGINS_PATH syntax for doing it.
>>
>> I'd like to not add ad-hoc environment variables for things that could
>> reasonably be configured elsewhere. Let's put it into the config
>> system and then have a way to take config from the environment.
>
> This isn't an adhoc environment variable - it already exists.
s/add variables/add features controlled by environment variables
--
Martin <http://
Robert Collins (lifeless) wrote : | # |
On Tue, 2010-01-05 at 01:06 +0000, Martin Pool wrote:
> >> I'd like to not add ad-hoc environment variables for things that could
> >> reasonably be configured elsewhere. Let's put it into the config
> >> system and then have a way to take config from the environment.
> >
> > This isn't an adhoc environment variable - it already exists.
>
> s/add variables/add features controlled by environment variables
I think this is an intereseting goal, but setting config options from
the environment could be pretty complex (in terms of UI); we already
support controlling plugin loading from the environment, so I think its
entirely appropriate *in this case* to control it from the existing
variable - that or we should be aiming to deprecate this (and other)
variables.
Put another way: saying that we shouldn't do this from the existing
variable makes making this feature usable from an environment variable
hostage to an unwritten, unspecified (and AFAIK) undiscussed feature.
All the uses I've heard of up until this bug for precise controlling of
plugin paths have been for testing in precommit hooks, an environment
where using the configuration to control it will be awkward at best
(cannot use the branch config, shouldn't be making persistent changes to
the global config)
-Rob
Vincent Ladeuil (vila) wrote : | # |
>>>>> "robert" == Robert Collins <email address hidden> writes:
robert> On Tue, 2010-01-05 at 01:06 +0000, Martin Pool wrote:
>> >> I'd like to not add ad-hoc environment variables for things that could
>> >> reasonably be configured elsewhere. Let's put it into the config
>> >> system and then have a way to take config from the environment.
>> >
>> > This isn't an adhoc environment variable - it already exists.
>>
>> s/add variables/add features controlled by environment variables
robert> I think this is an intereseting goal, but setting config options from
robert> the environment could be pretty complex (in terms of UI);
Not really if we implement -O and then some more glue as Martin
suggested in bug #I-dont-remember.
robert> we already support controlling plugin loading from
robert> the environment, so I think its entirely appropriate
robert> *in this case* to control it from the existing
robert> variable - that or we should be aiming to deprecate
robert> this (and other) variables.
But I agree there.
robert> Put another way: saying that we shouldn't do this
robert> from the existing variable makes making this feature
robert> usable from an environment variable hostage to an
robert> unwritten, unspecified (and AFAIK) undiscussed
robert> feature.
And here too. I'm also uncomfortable having plugins controlled by
*both* an environment variable and configuration variables.
robert> All the uses I've heard of up until this bug for
robert> precise controlling of plugin paths have been for
robert> testing in precommit hooks, an environment where
robert> using the configuration to control it will be awkward
robert> at best (cannot use the branch config, shouldn't be
robert> making persistent changes to the global config)
Yup. plugins are loaded very early, I looked at config variables
once and avoid them precisely for this reason.
Also, setting a config variable is not really better than issuing
a 'mv plugin DISABLED/' to temporarily disable a plugin or
issuing 'ln -s whatever-path ~/.bazaar/
installing a new plugin.
It's even worse than relying on the file system since you can't
have various link farms for various plugin configurations.
So, regarding this patch:
pros:
- allows both disabling a plugin and selecting a specific version
when several are available in the path.
cons:
- still rely on BZR_PLUGIN_PATH,
- add complexity to plugins handling,
- doesn't address using a dev version of a plugin (since it
requires specifying the parent directory you still need to use
the plugin name as the directory name which is not ideal for
maintaining several versions of the same plugin),
- can't be restricted to a single bzr run (as opposed to
'BZR_
I'd much prefer we implement the feature discussed with Robert
'BZR_PLUGIN_
plugin is supposed to be loaded from.
We still need to add support to disable a particular plugin, so
may be we can override '-' for that as in 'BZR_PLUGIN_
too disable the svn plugin comple...
Martin Pool (mbp) wrote : | # |
I'm +0 on merging this; I think Vincent has good points but incremental steps are good too.
Ian Clatworthy (ian-clatworthy) wrote : | # |
> Also, setting a config variable is not really better than issuing
> a 'mv plugin DISABLED/' to temporarily disable a plugin or
> issuing 'ln -s whatever-path ~/.bazaar/
> installing a new plugin.
I disagree here. For Windows users in particular, the primary use case is disabling one or more plugins that came in the bundled installer. That's *much* nicer to do by editing bazaar.conf (either directly or via intelligence added to qplugins or qconfig) than asking users to hack zip files buried in system level directories. Or asking them to set magic environment variable for that matter.
> So, regarding this patch:
> cons:
>
> - still rely on BZR_PLUGIN_PATH,
I think it's fine to have that environment variable continue to be the path searched for plugins while also having configuration settings controlling disabling or otherwise. The question then becomes what are the sensible values for the configuration setting for a given plugin?
One option is 'on' vs 'off'.
Another is '' (disabled) vs 'use this one if multiple exist'.
I went with the latter because it was more powerful. I'm fine going with the first one (though it's a shame to dumb this feature down given your preferred alternative isn't likely to make the 2.1 IIUIC).
Robert Collins (lifeless) wrote : | # |
On Mon, 2010-01-11 at 07:48 +0000, Ian Clatworthy wrote:
>
> Another is '' (disabled) vs 'use this one if multiple exist'.
>
> I went with the latter because it was more powerful. I'm fine going
> with the first one (though it's a shame to dumb this feature down
> given your preferred alternative isn't likely to make the 2.1 IIUIC).
By default we search two places for plugins:
- the installed library
- homedir
and homedir wins over system installed plugins (or at least it used
too :)).
I don't see any need for specific selection of the installed library
plugin over homedir plugins via config options - just delete the homedir
plugin - uninstall it.
So it seems to really be just disabling that is really useful for the
use cases you're putting forward here (though I consider it a bug if a
plugin needs to be 'not loaded' to be unintrusive: we shouldn't be
shipping problematic plugins by default.)
-Rob
Vincent Ladeuil (vila) wrote : | # |
>>>>> "Ian" == Ian Clatworthy <email address hidden> writes:
>> Also, setting a config variable is not really better than
Ian> issuing
>> a 'mv plugin DISABLED/' to temporarily disable a plugin or
>> issuing 'ln -s whatever-path ~/.bazaar/
>> installing a new plugin.
Ian> I disagree here. For Windows users in particular,
That's not in particular, windows is the only platform where we
have this problem.
Ian> the primary use case is disabling one or more plugins
Ian> that came in the bundled installer. That's *much* nicer
Ian> to do by editing bazaar.conf (either directly or via
Ian> intelligence added to qplugins or qconfig) than asking
Ian> users to hack zip files buried in system level
Ian> directories.
Users shouldn't have to hack a zip file. I expressed concerns
about that weeks ago and I considered (and still consider) it a
bug in the windows installer.
Moreover it also means people installing bzr from source on
windows can't easily use the plugins embedded in the installer.
And I'm back to the idea that you're doubling file systems
operations without addressing the root cause (since epoch,
disabling a plugin has been done by moving it out of the way (the
trash being one possible target of the move :).
Ian> Or asking them to set magic environment variable for
Ian> that matter.
PATH is as magic as BZR_PLUGIN_PATH, I don't think it's relevant
here.
>> So, regarding this patch:
>> cons:
>>
>> - still rely on BZR_PLUGIN_PATH,
Ian> I think it's fine to have that environment variable continue to
Ian> be the path searched for plugins while also having configuration
Ian> settings controlling disabling or otherwise. The question then
Ian> becomes what are the sensible values for the configuration
Ian> setting for a given plugin?
You haven't even reply to the other conses....
Ian> One option is 'on' vs 'off'.
Ian> Another is '' (disabled) vs 'use this one if multiple exist'.
And you're already bringing back a feature which should clearly
be addressed by using BZR_PLUGIN_PATH.
Ian> I went with the latter because it was more powerful. I'm
Ian> fine going with the first one (though it's a shame to
Ian> dumb this feature down given your preferred alternative
Ian> isn't likely to make the 2.1 IIUIC).
Feel free to enhance BZR_PLUGIN_PATH handling :) Shame or not
there are two features that has been defined and that will
address the same needs, you can either work on them or update the
docs to explain why bzr use two different mechanisms and cross
reference the two in the docs.
I still think using two different mechanisms will confuse users
more than it will help them.
Using config variables here sets a precedent, landing that patch
means we will have to continue supporting it even if
BZR_PLUGIN_PATH handling is enhanced: more work to come.
Vincent Ladeuil (vila) wrote : | # |
>>>>> "robert" == Robert Collins <email address hidden> writes:
robert> On Mon, 2010-01-11 at 07:48 +0000, Ian Clatworthy wrote:
>>
>> Another is '' (disabled) vs 'use this one if multiple exist'.
>>
>> I went with the latter because it was more powerful. I'm fine going
>> with the first one (though it's a shame to dumb this feature down
>> given your preferred alternative isn't likely to make the 2.1 IIUIC).
robert> By default we search two places for plugins:
robert> - the installed library
robert> - homedir
Add:
- the system-wide installed plugins
While the later has been more or less a hack when it was
introduced, the net result is that it is now *used* that way when
people use distributions where bzr *and* plugins are installed
system-wide.
robert> and homedir wins over system installed plugins (or at
robert> least it used too :)).
That's still the default: user/core/site (see
bzrlib.
Windows is the only platform were things are blurry because
there is no concept of 'site' there.
I consider it a bug but couldn't get agreement from bialix nor
jam on how to address that in a simple way. The causes were 1)
windows doesn't have a package manager nor a standardized
directory layout, 2) the installer add plugins in bzrlib.zip
(mixing the 'core' and 'site' directories into a single one).
<snip/>
robert> So it seems to really be just disabling that is
robert> really useful for the use cases you're putting
robert> forward here (though I consider it a bug if a plugin
robert> needs to be 'not loaded' to be unintrusive: we
robert> shouldn't be shipping problematic plugins by
robert> default.)
Or we do, we should allow users to install fixed versions.
Ian Clatworthy (ian-clatworthy) wrote : | # |
Vincent Ladeuil wrote:
> That's not in particular, windows is the only platform where we
> have this problem.
The issues I'm looking to solve impact all platforms IMO. Even on Linux,
a user may wish to disable a plugin that's installed system-wide and
they may not have permissions to touch the system paths where that
plugin is installed.
> PATH is as magic as BZR_PLUGIN_PATH, I don't think it's relevant
> here.
I think you and I are trying to solve very different Use Cases. My
drivers are:
1. More batteries should be included out-of-the-box in installers. Some
users will want or need to disable some of those batteries and they'll
most likely want to do it "forever". In some cases, plugins will be
broken and they'll want to turn them off. Or they'll hit and bug and
want to see whether having certain plugins installed fix the problem or
otherwise. Others may simply prefer a smaller footprint, e.g. less
entries in the list of commands when running qrun, less parts that might
break or introduce errors, etc.
2. There should be a feature in qplugins for enabling/disabling plugins.
That data ought to be permanently stored somewhere sensible like
bazaar.conf. An environment variable just doesn't cut it.
My focus is end-users, e.g. someone who clicks on a plugin in qplugins
and is given the option to disable it or to select a particular instance
of it found on the plugins path. Your focus seems to be test runners and
plugin developers where the needs are far more short term.
> You haven't even reply to the other conses....
Fair enough:
* "adds complexity" is a motherhood statement. Of course it does.
So do 99% of other new features.
* "Developers can't give an explicit path". Agreed. I could
fix that. OTOH, current mechanisms (like symlinks) works fine
right now so it didn't feel worth it.
* "Restriction to a single run". I like your idea of environment
variables for that case. You could just as nicely solve it by
using an environment variable pointing to a custom bazaar.conf, yes?
In that case, you could more easily test any custom settings in
bazaar.conf, not just custom plugin paths.
> And you're already bringing back a feature which should clearly
> be addressed by using BZR_PLUGIN_PATH.
I'm sorry but that statement is simply not true. For your Use Cases,
environment variables sound fine. For mine, they are the wrong choice.
Having multiple mechanisms may indeed be the right answer here, given
the different problems we're trying to address. Regardless, having zero
mechanisms isn't the right number. :-)
Ian C.
Christophe Simonis (OpenERP) (kangol) wrote : | # |
How handle the case of a plugin enable for just one repository ?
Robert Collins (lifeless) wrote : | # |
On Mon, 2010-01-11 at 11:08 +0000, Christophe (OpenERP) wrote:
> How handle the case of a plugin enable for just one repository ?
There are two different things for plugins:
- being loaded (enabled/disabled)
- being active for a branch/repository
Plugins that you want active on one repository should look for a
configuration option about the repository (or branch).
Doing it this way avoids a bunch of issues related to security and
safety that turn up when repositories or branches can enable plugins.
-Rob
Martin Pool (mbp) wrote : | # |
2010/1/11 Ian Clatworthy <email address hidden>:
> Vincent Ladeuil wrote:
>
>> That's not in particular, windows is the only platform where we
>> have this problem.
>
> The issues I'm looking to solve impact all platforms IMO. Even on Linux,
> a user may wish to disable a plugin that's installed system-wide and
> they may not have permissions to touch the system paths where that
> plugin is installed.
This is definitely true. I commonly want to do it myself; obviously I
know how but moving the directory is a bit ugly. There are also bugs
where we want to ask people "can you reproduce this without bzr-svn"
and that is more complicated than it should be.
>> PATH is as magic as BZR_PLUGIN_PATH, I don't think it's relevant
>> here.
>
> I think you and I are trying to solve very different Use Cases. My
> drivers are:
>
> 1. More batteries should be included out-of-the-box in installers. Some
> users will want or need to disable some of those batteries and they'll
> most likely want to do it "forever". In some cases, plugins will be
> broken and they'll want to turn them off. Or they'll hit and bug and
> want to see whether having certain plugins installed fix the problem or
> otherwise. Others may simply prefer a smaller footprint, e.g. less
> entries in the list of commands when running qrun, less parts that might
> break or introduce errors, etc.
>
> 2. There should be a feature in qplugins for enabling/disabling plugins.
> That data ought to be permanently stored somewhere sensible like
> bazaar.conf. An environment variable just doesn't cut it.
>
> My focus is end-users, e.g. someone who clicks on a plugin in qplugins
> and is given the option to disable it or to select a particular instance
> of it found on the plugins path. Your focus seems to be test runners and
> plugin developers where the needs are far more short term.
>
>> You haven't even reply to the other conses....
>
> Fair enough:
>
> * "adds complexity" is a motherhood statement. Of course it does.
> So do 99% of other new features.
>
> * "Developers can't give an explicit path". Agreed. I could
> fix that. OTOH, current mechanisms (like symlinks) works fine
> right now so it didn't feel worth it.
I suspect if you point to the parent directory, people will commonly
get it wrong and be confused. Well that will probably happen whatever
you do, but I think perhaps more so this way.
> * "Restriction to a single run". I like your idea of environment
> variables for that case. You could just as nicely solve it by
> using an environment variable pointing to a custom bazaar.conf, yes?
> In that case, you could more easily test any custom settings in
> bazaar.conf, not just custom plugin paths.
>
>> And you're already bringing back a feature which should clearly
>> be addressed by using BZR_PLUGIN_PATH.
>
> I'm sorry but that statement is simply not true. For your Use Cases,
> environment variables sound fine. For mine, they are the wrong choice.
>
> Having multiple mechanisms may indeed be the right answer here, given
> the different problems we're trying to address. Regardless, having zero
> mechanisms isn't the right number. :-)
It's reasonable to have this be per...
- 4931. By Ian Clatworthy
-
Simplify to just on vs off configuration
- 4932. By Ian Clatworthy
-
just check disabled vs otherwise
Ian Clatworthy (ian-clatworthy) wrote : | # |
I've simplified this to just support disabling. Please re-review.
Martin Pool (mbp) wrote : | # |
I think finding these based on the section name is a bit limiting, because it will make it harder to put them into other places, if we add a say -O option or something. What do you think of making it something like "plugin:gtk=off"?
Ian Clatworthy (ian-clatworthy) wrote : | # |
Martin Pool wrote:
> I think finding these based on the section name is a bit limiting, because it will make it harder to put them into other places, if we add a say -O option or something. What do you think of making it something like "plugin:gtk=off"?
Sounds fine to me.
Ian C.
John A Meinel (jameinel) wrote : | # |
161 + try:
162 + enabled = load_rules[f]
163 + if not enabled:
164 + trace.mutter(
165 + continue
166 + except KeyError:
167 + pass
I think this could be simplified to:
if not load_rules.get(f, True):
trace.mutter(...)
continue
Also, I think this:
22 + def get_plugin_
23 + """Return the plugins section."""
24 + if 'PLUGINS' in self._get_parser():
25 + values = self._get_
26 + return dict([(k, not(v in ['off', 'disable', 'false']))
27 + for k, v in values.items()])
28 + else:
29 + return {}
30 +
1) Should probably use 'v.lower()'
2) Maybe should use 'ui.bool_
I don't really like allowing garbage settings to have 'default' results, rather than failing and telling the user that there is a problem with their configuration.
Unmerged revisions
- 4932. By Ian Clatworthy
-
just check disabled vs otherwise
- 4931. By Ian Clatworthy
-
Simplify to just on vs off configuration
- 4930. By Ian Clatworthy
-
add documentation
- 4929. By Ian Clatworthy
-
support plugin disabling and explicit locations
- 4928. By Ian Clatworthy
-
Add PLUGINS section to bazaar.conf
Preview Diff
1 | === modified file 'NEWS' |
2 | --- NEWS 2010-01-11 13:15:01 +0000 |
3 | +++ NEWS 2010-01-12 06:28:14 +0000 |
4 | @@ -36,6 +36,9 @@ |
5 | (Ted Gould, Matthew Fuller, Vincent Ladeuil) |
6 | |
7 | |
8 | +* ``bazaar.conf`` now supports a PLUGINS section where plugins |
9 | + can be disabled. (Ian Clatworthy, #411413) |
10 | + |
11 | Bug Fixes |
12 | ********* |
13 | |
14 | |
15 | === modified file 'bzrlib/config.py' |
16 | --- bzrlib/config.py 2009-12-17 10:01:25 +0000 |
17 | +++ bzrlib/config.py 2010-01-12 06:28:14 +0000 |
18 | @@ -514,6 +514,15 @@ |
19 | self._get_parser().write(f) |
20 | f.close() |
21 | |
22 | + def get_plugin_load_rules(self): |
23 | + """Return the plugins section.""" |
24 | + if 'PLUGINS' in self._get_parser(): |
25 | + values = self._get_parser()['PLUGINS'] |
26 | + return dict([(k, not(v in ['off', 'disable', 'false'])) |
27 | + for k, v in values.items()]) |
28 | + else: |
29 | + return {} |
30 | + |
31 | |
32 | class LocationConfig(IniBasedConfig): |
33 | """A configuration object that gives the policy for a location.""" |
34 | |
35 | === modified file 'bzrlib/help_topics/en/configuration.txt' |
36 | --- bzrlib/help_topics/en/configuration.txt 2010-01-03 03:33:10 +0000 |
37 | +++ bzrlib/help_topics/en/configuration.txt 2010-01-12 06:28:14 +0000 |
38 | @@ -172,9 +172,10 @@ |
39 | |
40 | [DEFAULT] |
41 | |
42 | -The only valid section headers for bazaar.conf currently are [DEFAULT] and |
43 | -[ALIASES]. Section headers are case sensitive. The default section provides for |
44 | -setting variables which can be overridden with the branch config file. |
45 | +The only valid section headers for bazaar.conf currently are [DEFAULT], |
46 | +[ALIASES] and [PLUGINS]. Section headers are case sensitive. The DEFAULT |
47 | +section provides for setting variables which can be overridden with the |
48 | +branch config file. |
49 | |
50 | For ``locations.conf``, the variables from the section with the |
51 | longest matching section header are used to the exclusion of other |
52 | @@ -228,8 +229,8 @@ |
53 | The main configuration file, bazaar.conf |
54 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
55 | |
56 | -``bazaar.conf`` allows two sections: ``[DEFAULT]`` and ``[ALIASES]``. |
57 | -The default section contains the default |
58 | +``bazaar.conf`` supports ``[DEFAULT]``, ``[ALIASES]`` and ``[PLUGINS]`` |
59 | +sections. The default section contains the default |
60 | configuration options for all branches. The default section can be |
61 | overriden by providing a branch-specific section in ``locations.conf``. |
62 | |
63 | @@ -241,6 +242,17 @@ |
64 | check_signatures = check-available |
65 | create_signatures = when-required |
66 | |
67 | +The PLUGINS section lets you disable plugins found on the path. |
68 | +Keys are plugin names. A value of ``off``, ``disable`` or ``false`` |
69 | +will disable a plugin. Otherwise, the plugin will be enabled. |
70 | +For example:: |
71 | + |
72 | + [PLUGINS] |
73 | + foo = off |
74 | + bar = on |
75 | + |
76 | +To debug plugin load problems, check the trace messages in .bzr.log. |
77 | + |
78 | |
79 | The branch location configuration file, locations.conf |
80 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
81 | |
82 | === modified file 'bzrlib/plugin.py' |
83 | --- bzrlib/plugin.py 2009-09-04 15:36:48 +0000 |
84 | +++ bzrlib/plugin.py 2010-01-12 06:28:14 +0000 |
85 | @@ -195,7 +195,7 @@ |
86 | return paths |
87 | |
88 | |
89 | -def load_plugins(path=None): |
90 | +def load_plugins(path=None, load_rules=None): |
91 | """Load bzrlib plugins. |
92 | |
93 | The environment variable BZR_PLUGIN_PATH is considered a delimited |
94 | @@ -203,12 +203,16 @@ |
95 | files (and whatever other extensions are used in the platform, |
96 | such as *.pyd). |
97 | |
98 | - load_from_dirs() provides the underlying mechanism and is called with |
99 | + load_from_path() provides the underlying mechanism and is called with |
100 | the default directory list to provide the normal behaviour. |
101 | |
102 | :param path: The list of paths to search for plugins. By default, |
103 | path will be determined using get_standard_plugins_path. |
104 | if path is [], no plugins can be loaded. |
105 | + :param load_rules: If a plugin name is found in this map, only load |
106 | + it if the corresponding value is True. |
107 | + If this map is None, config.GlobalConfig().get_plugin_load_rules() |
108 | + is used. |
109 | """ |
110 | global _loaded |
111 | if _loaded: |
112 | @@ -216,11 +220,14 @@ |
113 | return |
114 | _loaded = True |
115 | |
116 | + if load_rules is None: |
117 | + load_rules = config.GlobalConfig().get_plugin_load_rules() |
118 | + |
119 | # scan for all plugins in the path. |
120 | - load_from_path(set_plugins_path(path)) |
121 | - |
122 | - |
123 | -def load_from_path(dirs): |
124 | + load_from_path(set_plugins_path(path), load_rules) |
125 | + |
126 | + |
127 | +def load_from_path(dirs, load_rules=None): |
128 | """Load bzrlib plugins found in each dir in dirs. |
129 | |
130 | Loading a plugin means importing it into the python interpreter. |
131 | @@ -243,7 +250,7 @@ |
132 | continue |
133 | trace.mutter('looking for plugins in %s', d) |
134 | if os.path.isdir(d): |
135 | - load_from_dir(d) |
136 | + load_from_dir(d, load_rules) |
137 | |
138 | |
139 | # backwards compatability: load_from_dirs was the old name |
140 | @@ -251,7 +258,7 @@ |
141 | load_from_dirs = load_from_path |
142 | |
143 | |
144 | -def load_from_dir(d): |
145 | +def load_from_dir(d, load_rules=None): |
146 | """Load the plugins in directory d. |
147 | |
148 | d must be in the plugins module path already. |
149 | @@ -262,6 +269,7 @@ |
150 | valid_suffixes = [suffix for suffix, mod_type, flags in imp.get_suffixes() |
151 | if flags in (imp.PY_SOURCE, imp.PY_COMPILED)] |
152 | package_entries = ['__init__'+suffix for suffix in valid_suffixes] |
153 | + load_rules = load_rules or {} |
154 | plugin_names = set() |
155 | for f in os.listdir(d): |
156 | path = osutils.pathjoin(d, f) |
157 | @@ -287,6 +295,13 @@ |
158 | elif getattr(_mod_plugins, f, None): |
159 | trace.mutter('Plugin name %s already loaded', f) |
160 | else: |
161 | + try: |
162 | + enabled = load_rules[f] |
163 | + if not enabled: |
164 | + trace.mutter('Plugin name %s disabled', f) |
165 | + continue |
166 | + except KeyError: |
167 | + pass |
168 | # trace.mutter('add plugin name %s', f) |
169 | plugin_names.add(f) |
170 | |
171 | |
172 | === modified file 'bzrlib/tests/test_config.py' |
173 | --- bzrlib/tests/test_config.py 2009-12-22 23:09:50 +0000 |
174 | +++ bzrlib/tests/test_config.py 2010-01-12 06:28:14 +0000 |
175 | @@ -52,6 +52,17 @@ |
176 | ll=""" + sample_long_alias + "\n" |
177 | |
178 | |
179 | +sample_plugin_load_rules = """ |
180 | +[PLUGINS] |
181 | +p1=on |
182 | +p2=off |
183 | +p3=enable |
184 | +p4=disable |
185 | +p5=true |
186 | +p6=false |
187 | +""" |
188 | + |
189 | + |
190 | sample_always_signatures = """ |
191 | [DEFAULT] |
192 | check_signatures=ignore |
193 | @@ -692,6 +703,24 @@ |
194 | change_editor = my_config.get_change_editor('old', 'new') |
195 | self.assertIs(None, change_editor) |
196 | |
197 | + def test_get_plugin_load_rules(self): |
198 | + config_file = StringIO(sample_plugin_load_rules) |
199 | + my_config = config.GlobalConfig() |
200 | + my_config._parser = my_config._get_parser(file=config_file) |
201 | + load_rules = my_config.get_plugin_load_rules() |
202 | + self.assertEqual(6, len(load_rules)) |
203 | + self.assertEqual(True, load_rules['p1']) |
204 | + self.assertEqual(False, load_rules['p2']) |
205 | + self.assertEqual(True, load_rules['p3']) |
206 | + self.assertEqual(False, load_rules['p4']) |
207 | + self.assertEqual(True, load_rules['p5']) |
208 | + self.assertEqual(False, load_rules['p6']) |
209 | + |
210 | + def test_get_no_plugin_locations(self): |
211 | + my_config = self._get_sample_config() |
212 | + locations = my_config.get_plugin_locations() |
213 | + self.assertEqual(0, len(locations)) |
214 | + |
215 | |
216 | class TestGlobalConfigSavingOptions(tests.TestCaseInTempDir): |
217 | |
218 | |
219 | === modified file 'bzrlib/tests/test_plugins.py' |
220 | --- bzrlib/tests/test_plugins.py 2009-09-18 14:53:37 +0000 |
221 | +++ bzrlib/tests/test_plugins.py 2010-01-12 06:28:14 +0000 |
222 | @@ -592,7 +592,7 @@ |
223 | plugin._loaded = False |
224 | |
225 | # Monkey-patch load_from_path to stop it from actually loading anything. |
226 | - def load_from_path(dirs): |
227 | + def load_from_path(dirs, load_rules=None): |
228 | pass |
229 | plugin.load_from_path = load_from_path |
230 |
This branch lets users disable selected plugins by adding settings to bazaar.conf. This can be helpful while tracking down problems and has been requested numerous times on the mailing list.
To generalise the feature, the setting for a given plugin can be an explicit (parent) directory to load a given plugin from. This lets developers/users run/test the default installation of a plugin say, rather than the first one found on the plugin search path.
Another test or two is required before this can land. I had a look at bzrib/tests/ test_plugin. py and couldn't decide the best way to test this. TestLoadFromPath looks like the right class to extend but the way it monkey-patches the real code suggests otherwise? Input/advice/code welcome.
In terms of the big picture, my primary driver for this is better packaging. I'd like to see many more plugins bundled in the Windows and Mac installers but there's a risk in doing that. Being able to easily disable a suspect plugin reduces that risk a lot IMO.