Merge lp:~andrebachmann-dd/qbzr/checkout_basedir into lp:qbzr

Proposed by André Bachmann
Status: Merged
Merged at revision: 1430
Proposed branch: lp:~andrebachmann-dd/qbzr/checkout_basedir
Merge into: lp:qbzr
Diff against target: 178 lines (+88/-3) (has conflicts)
4 files modified
NEWS.txt (+6/-0)
lib/commands.py (+1/-1)
lib/config.py (+60/-0)
lib/getnew.py (+21/-2)
Text conflict in NEWS.txt
To merge this branch: bzr merge lp:~andrebachmann-dd/qbzr/checkout_basedir
Reviewer Review Type Date Requested Status
Jonathan Riddell (community) Approve
Alexander Belchenko Needs Fixing
Review via email: mp+68705@code.launchpad.net

Description of the change

As discussed in qbzr newsgroup, we can now specify base directories for qgetnew.

To post a comment you must log in.
1422. By PKO

added tooltips to these new options

Revision history for this message
IWATA Hidetaka (hid-iwata) wrote :

Hi.

`bzr qgetnew LOCATION` does not work. Command line arguments should be prior to global configuration.
Just focusing on GetNewWorkingTreeWindow class, `to_location` is parameter passed from outer code.
I think GetNewWorkingTreeWindow should respect it.

I want to specify url or string like "lp:~hid-iwata/" to branchsource_basedir.
But now, os.path.abspath breaks it. Is os.path.abspath realy needed?

1423. By PKO

to_location is honored when qgetnew is started without GUI,
from_location entry is completed without further checks

Revision history for this message
André Bachmann (andrebachmann-dd) wrote :

Ok, now to_location only gets the text from checkout_basedir if ui_mode is true. 'bzr qgetnew location' does work now.
But I disagree that this window should only respect the to_location from its outer code. If someone configures a base directory for checkouts, then this user wants it to be in the field 'to_location' - because if he/she doesn't wants it, he/she would have never configured this.

Concerning branchsource_basedir: My idea was to put at least a little bit of safety precaution that this field couldn't contain an invalid path. But I forgot that you can also put in a non-local path in it.
So I deleted os.path.abspath.

Revision history for this message
IWATA Hidetaka (hid-iwata) wrote :

Hi, thank you for reply.

> Ok, now to_location only gets the text from checkout_basedir if ui_mode is true. 'bzr qgetnew location' does work now.

Why ui_mode? I don't think ui_mode is good thing to switch this
behaivior. Now, 'bzr qgetnew' probably does not work as you expected.

I'd like to suggest you this fix. How about it?

1. cmd_qgetnew._qbzr_run
    Change default value of location to None, instead of CUR_DIR

2. GetNewWorkingTreeWindow.__init__
    Apply configuration if to_location is None.

=== modified file 'lib/commands.py'
--- lib/commands.py 2011-06-30 16:28:58 +0000
+++ lib/commands.py 2011-07-26 15:04:12 +0000
@@ -851,7 +851,7 @@
     takes_options = [ui_mode_option]
     aliases = ['qgetn']

- def _qbzr_run(self, location=CUR_DIR, ui_mode=False):
+ def _qbzr_run(self, location=None, ui_mode=False):
         from bzrlib.plugins.qbzr.lib.getnew import GetNewWorkingTreeWindow
         self.main_window = GetNewWorkingTreeWindow(location, ui_mode=ui_mode)
         self.main_window.show()

=== modified file 'lib/getnew.py'
--- lib/getnew.py 2011-07-25 13:23:12 +0000
+++ lib/getnew.py 2011-07-26 15:03:55 +0000
@@ -44,10 +44,9 @@
     branchsource_basedir = config.get_option("branchsource_basedir")

     def __init__(self, to_location, ui_mode=True, parent=None):
- if ui_mode and self.checkout_basedir is not None:
- self.to_location = os.path.abspath(self.checkout_basedir)
- else:
- self.to_location = os.path.abspath(to_location)
+ if not to_location:
+ to_location = self.checkout_basedir or u'.'
+ self.to_location = os.path.abspath(to_location)

         super(GetNewWorkingTreeWindow, self).__init__(
                                   name = self.NAME,

Revision history for this message
André Bachmann (andrebachmann-dd) wrote :

Hm... could you give me an example when my version would show a wrong behaviour? I'm asking because I observed that ui_mode is false if qgetnew is started from the command line and it is true if started from within Bazaar Explorer.

Revision history for this message
IWATA Hidetaka (hid-iwata) wrote :

Hi. Sorry for the delay.

> Hm... could you give me an example when my version would show a wrong
behaviour?

I expected, configured path is used when started from command line without
LOCATION argument.
I think it is natural that getnew window uses configured
path when no LOCATION specified.

> ui_mode is false if qgetnew is started from the command line

ui_mode is one of command line arguments, you can't know getnew is launched
from cui or gui by ui_mode value.

> it is true if started from within Bazaar Explorer.

qbzr is common library used by bzr-explorer, TortoiseBzr, IDE integrations,
and so on.
"How bzr-explorer use qbzr" is not enough. And ui_mode is just a option to
determine auto-closing behavior, no more and no less.

For example, by TortoiseBzr, users select a folder, and then, launch
Checkout command. so it is natural that getnew window use selected folder
path rather than configured path.
Your fix will prevent this operation.

BTW, I think we need Alexander's opinion.

Thanks.

2011/7/28 André Bachmann <email address hidden>:
> Hm... could you give me an example when my version would show a wrong
behaviour? I'm asking because I observed that ui_mode is false if qgetnew is
started from the command line and it is true if started from within Bazaar
Explorer.
> --
>
https://code.launchpad.net/~andrebachmann-dd/qbzr/checkout_basedir/+merge/68705
> Your team QBzr Developers is requested to review the proposed merge of
lp:~andrebachmann-dd/qbzr/checkout_basedir into lp:qbzr.
>

Revision history for this message
André Bachmann (andrebachmann-dd) wrote :

Ok, now I got your point. :)

I will look at this tomorrow. Thanks for your feedback!

1424. By PKO

Should now better work with external tools like TortoiseBZR

Revision history for this message
André Bachmann (andrebachmann-dd) wrote :

I have used your suggestion. I think it is indeed a better solution than mine. :)

Revision history for this message
Alexander Belchenko (bialix) wrote :

You should move your news item to latest unreleased section in trunk.

Revision history for this message
Alexander Belchenko (bialix) wrote :

Hidetaka's suggestions is quite right.

Re your code. I'm strongly against doing that at the class level:

+ config = get_qbzr_config()
+ checkout_basedir = config.get_option("checkout_basedir")
+ branchsource_basedir = config.get_option("branchsource_basedir")

in class GetNewWorkingTreeWindow.

Your code will be executed at the python module import time, and this is could be bad for Bazaar Explorer case. You should re-read values from config inside __init__ method on each qgetnew invocation. This is not obvious problem right now because we're used to launching q-commands as subprocesses. But for future compatibility we shouldn't use code like that. Put it to __init__.

review: Needs Fixing
Revision history for this message
André Bachmann (andrebachmann-dd) wrote :

Ok, I moved them to __init__.
But there is a problem which I don't understand: to_location begins with a ".", so my config option is never used (you can check this by uncommenting the lines with mutter in getnew.py). I thought we changed the default value of to_location in commands.py to None to prevent this? I could really need a hint...

1425. By PKO

moved to reading of values to __init__

Revision history for this message
Alexander Belchenko (bialix) wrote :

You need to add mutter to _qbzr_run and check what value location variable has.

Have you tested qgetnew from command-line or from Explorer? In the latter case it's Explorer who may pass '.' as argument.

Revision history for this message
André Bachmann (andrebachmann-dd) wrote :

Ok, 'bzr qgetnew' from command line gives the desired result, but Bazaar Explorer passes the '.'.

I just found the reason for that: It's in checkout_dialog.py from Explorer in QCheckoutExplorerStyleDialog::__init__. But why is this checkout dialog reimplemented? Why are there two implementations for one dialog?

I will have to modify this as well to get my new option working as intended, I think. Would this be ok, because Explorer and qbzr are two different projects?

Revision history for this message
Alexander Belchenko (bialix) wrote :

André Bachmann пишет:
> Ok, 'bzr qgetnew' from command line gives the desired result, but Bazaar Explorer passes the '.'.
>
> I just found the reason for that: It's in checkout_dialog.py from Explorer in QCheckoutExplorerStyleDialog::__init__. But why is this checkout dialog reimplemented? Why are there two implementations for one dialog?

Because Ian wanted to have better support for bzr-colo workflow.

> I will have to modify this as well to get my new option working as intended, I think. Would this be ok, because Explorer and qbzr are two different projects?

Explorer depends on QBzr, so they are related. We need to find the safe
way to extend Explorer giving in mind compatibility with old version of
qbzr.

--
All the dude wanted was his rug back

Revision history for this message
André Bachmann (andrebachmann-dd) wrote :

Ok, now I have also modified checkout_dialog.py from Bazaar Explorer (please see https://code.launchpad.net/~andrebachmann-dd/bzr-explorer/basedir/+merge/70828). I tried to make this change as soft as possible.

Revision history for this message
André Bachmann (andrebachmann-dd) wrote :

Any other comments on this?

Revision history for this message
Alexander Belchenko (bialix) wrote :

André Bachmann пишет:
> Any other comments on this?

Sorry for the delay.

But last weeks my health status don't allow me to work on QBzr and
Bazaar Explorer. Maybe somebody else can review it.

Revision history for this message
Jonathan Riddell (jr) wrote :

working well here, I'll merge it in, thanks

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'NEWS.txt'
--- NEWS.txt 2011-08-04 04:58:32 +0000
+++ NEWS.txt 2011-08-08 10:11:37 +0000
@@ -73,7 +73,13 @@
73 (Bug #490377, A. S. Budden)73 (Bug #490377, A. S. Budden)
74 * qgetnew:74 * qgetnew:
75 * The target location no longer gets overwritten 75 * The target location no longer gets overwritten
76<<<<<<< TREE
76 when the source location changes. (Andrテゥ Bachmann)77 when the source location changes. (Andrテゥ Bachmann)
78=======
79 when the source location changes. (André Bachmann)
80 * Base directories for the source branch and the destination checkout folder
81 can now be configured in qconfig, tab 'User Interface'. (André Bachmann)
82>>>>>>> MERGE-SOURCE
77 * qlog:83 * qlog:
78 * File list context menu: added support to save content of a file 84 * File list context menu: added support to save content of a file
79 of specific revision as a new file. (Andrテゥ Bachmann)85 of specific revision as a new file. (Andrテゥ Bachmann)
8086
=== modified file 'lib/commands.py'
--- lib/commands.py 2011-06-30 16:28:58 +0000
+++ lib/commands.py 2011-08-08 10:11:37 +0000
@@ -851,7 +851,7 @@
851 takes_options = [ui_mode_option]851 takes_options = [ui_mode_option]
852 aliases = ['qgetn']852 aliases = ['qgetn']
853853
854 def _qbzr_run(self, location=CUR_DIR, ui_mode=False):854 def _qbzr_run(self, location=None, ui_mode=False):
855 from bzrlib.plugins.qbzr.lib.getnew import GetNewWorkingTreeWindow855 from bzrlib.plugins.qbzr.lib.getnew import GetNewWorkingTreeWindow
856 self.main_window = GetNewWorkingTreeWindow(location, ui_mode=ui_mode)856 self.main_window = GetNewWorkingTreeWindow(location, ui_mode=ui_mode)
857 self.main_window.show()857 self.main_window.show()
858858
=== modified file 'lib/config.py'
--- lib/config.py 2011-08-05 01:07:34 +0000
+++ lib/config.py 2011-08-08 10:11:37 +0000
@@ -274,6 +274,34 @@
274 grid.addWidget(label, 0, 0)274 grid.addWidget(label, 0, 0)
275 grid.addWidget(self.spellcheck_language_combo, 0, 1)275 grid.addWidget(self.spellcheck_language_combo, 0, 1)
276276
277 self.branchsourceBasedirEdit = QtGui.QLineEdit()
278 self.branchsourceBasedirEdit.setToolTip(gettext("This directory will be automatically filled in your branch source input field"))
279 btnBranchsourceBasedirBrowse = QtGui.QPushButton(gettext('Browse...'))
280 self.connect(btnBranchsourceBasedirBrowse,
281 QtCore.SIGNAL("clicked()"),
282 self.browseBranchsourceBasedir)
283 branchsourceBasedirHBox = QtGui.QHBoxLayout()
284 branchsourceBasedirHBox.addWidget(self.branchsourceBasedirEdit)
285 branchsourceBasedirHBox.addWidget(btnBranchsourceBasedirBrowse)
286 label = QtGui.QLabel(gettext("Base directory\nfor &branch sources:"))
287 label.setBuddy(self.branchsourceBasedirEdit)
288 grid.addWidget(label, 1, 0)
289 grid.addLayout(branchsourceBasedirHBox, 1, 1)
290
291 self.checkoutBasedirEdit = QtGui.QLineEdit()
292 self.checkoutBasedirEdit.setToolTip(gettext("This directory will be automatically filled in your checkout destination input field"))
293 btnCheckoutBasedirBrowse = QtGui.QPushButton(gettext('Browse...'))
294 self.connect(btnCheckoutBasedirBrowse,
295 QtCore.SIGNAL("clicked()"),
296 self.browseCheckoutBasedir)
297 checkoutBasedirHBox = QtGui.QHBoxLayout()
298 checkoutBasedirHBox.addWidget(self.checkoutBasedirEdit)
299 checkoutBasedirHBox.addWidget(btnCheckoutBasedirBrowse)
300 label = QtGui.QLabel(gettext("Base directory\nfor &checkouts:"))
301 label.setBuddy(self.checkoutBasedirEdit)
302 grid.addWidget(label, 2, 0)
303 grid.addLayout(checkoutBasedirHBox, 2, 1)
304
277 return tabwidget305 return tabwidget
278306
279 def load(self):307 def load(self):
@@ -325,6 +353,16 @@
325 if index >= 0:353 if index >= 0:
326 self.spellcheck_language_combo.setCurrentIndex(index)354 self.spellcheck_language_combo.setCurrentIndex(index)
327355
356 # Branch source basedir
357 branchsourceBasedir = qconfig.get_option('branchsource_basedir')
358 if branchsourceBasedir:
359 self.branchsourceBasedirEdit.setText(branchsourceBasedir)
360
361 # Checkout basedir
362 checkoutBasedir = qconfig.get_option('checkout_basedir')
363 if checkoutBasedir:
364 self.checkoutBasedirEdit.setText(checkoutBasedir)
365
328 # Aliases366 # Aliases
329 aliases = parser.get('ALIASES', {})367 aliases = parser.get('ALIASES', {})
330 for alias, command in aliases.items():368 for alias, command in aliases.items():
@@ -471,6 +509,14 @@
471 spellcheck_language = unicode(self.spellcheck_language_combo.itemData(index).toString())509 spellcheck_language = unicode(self.spellcheck_language_combo.itemData(index).toString())
472 set_or_delete_option(parser, 'spellcheck_language', spellcheck_language)510 set_or_delete_option(parser, 'spellcheck_language', spellcheck_language)
473511
512 # Branch source basedir
513 branchsource_basedir = unicode(self.branchsourceBasedirEdit.text())
514 qconfig.set_option('branchsource_basedir', branchsource_basedir)
515
516 # Checkout basedir
517 checkout_basedir = unicode(self.checkoutBasedirEdit.text())
518 qconfig.set_option('checkout_basedir', checkout_basedir)
519
474 # Aliases520 # Aliases
475 parser['ALIASES'] = {}521 parser['ALIASES'] = {}
476 for index in range(self.aliasesList.topLevelItemCount()):522 for index in range(self.aliasesList.topLevelItemCount()):
@@ -674,6 +720,20 @@
674 '/')720 '/')
675 if filename:721 if filename:
676 self.editorEdit.setText(filename)722 self.editorEdit.setText(filename)
723
724 def browseCheckoutBasedir(self):
725 filename = QtGui.QFileDialog.getExistingDirectory(self,
726 gettext('Select base directory for checkouts'),
727 '/')
728 if filename:
729 self.checkoutBasedirEdit.setText(filename)
730
731 def browseBranchsourceBasedir(self):
732 filename = QtGui.QFileDialog.getExistingDirectory(self,
733 gettext('Select default directory for branch sources'),
734 '/')
735 if filename:
736 self.branchsourceBasedirEdit.setText(filename)
677737
678738
679def get_user_id_from_os():739def get_user_id_from_os():
680740
=== modified file 'lib/getnew.py'
--- lib/getnew.py 2011-07-15 12:54:36 +0000
+++ lib/getnew.py 2011-08-08 10:11:37 +0000
@@ -32,14 +32,23 @@
32 hookup_directory_picker,32 hookup_directory_picker,
33 DIRECTORYPICKER_SOURCE,33 DIRECTORYPICKER_SOURCE,
34 DIRECTORYPICKER_TARGET,34 DIRECTORYPICKER_TARGET,
35 get_qbzr_config,
35 )36 )
3637#from bzrlib.trace import mutter
3738
38class GetNewWorkingTreeWindow(SubProcessDialog):39class GetNewWorkingTreeWindow(SubProcessDialog):
3940
40 NAME = "new_tree"41 NAME = "new_tree"
4142
42 def __init__(self, to_location, ui_mode=True, parent=None):43 def __init__(self, to_location, ui_mode=True, parent=None):
44 config = get_qbzr_config()
45 checkout_basedir = config.get_option("checkout_basedir")
46 branchsource_basedir = config.get_option("branchsource_basedir")
47 #mutter("*** co: %s", checkout_basedir)
48 #mutter("*** bs: %s", branchsource_basedir)
49 #mutter("*** to_l: %s", to_location)
50 if not to_location:
51 to_location = checkout_basedir or u'.'
43 self.to_location = os.path.abspath(to_location)52 self.to_location = os.path.abspath(to_location)
44 super(GetNewWorkingTreeWindow, self).__init__(53 super(GetNewWorkingTreeWindow, self).__init__(
45 name = self.NAME,54 name = self.NAME,
@@ -73,6 +82,9 @@
73 self.ui.but_checkout.setChecked(True)82 self.ui.but_checkout.setChecked(True)
74 self.ui.but_rev_tip.setChecked(True)83 self.ui.but_rev_tip.setChecked(True)
75 self.ui.to_location.setText(self.to_location)84 self.ui.to_location.setText(self.to_location)
85 if branchsource_basedir is not None:
86 self.from_location = branchsource_basedir
87 self.ui.from_location.setEditText(self.from_location)
7688
77 def to_location_changed(self):89 def to_location_changed(self):
78 self.disconnect(self.ui.from_location, QtCore.SIGNAL("editTextChanged(const QString &)"),90 self.disconnect(self.ui.from_location, QtCore.SIGNAL("editTextChanged(const QString &)"),
@@ -83,8 +95,15 @@
83 def from_location_changed(self, new_text):95 def from_location_changed(self, new_text):
84 new_val = self.to_location96 new_val = self.to_location
85 tail = re.split("[:$#\\\\/]", unicode(new_text))[-1]97 tail = re.split("[:$#\\\\/]", unicode(new_text))[-1]
98 try:
99 projectname = re.split("[:$#\\\\/]", unicode(new_text))[-2]
100 except:
101 projectname = ""
86 if tail:102 if tail:
87 new_val = os.path.join(new_val, tail)103 if self.checkout_basedir is not None:
104 new_val = os.path.join(self.checkout_basedir, projectname)
105 else:
106 new_val = os.path.join(new_val, tail)
88 self.ui.to_location.setText(new_val)107 self.ui.to_location.setText(new_val)
89108
90 def do_start(self):109 def do_start(self):

Subscribers

People subscribed via source and target branches