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
1=== modified file 'NEWS.txt'
2--- NEWS.txt 2011-08-04 04:58:32 +0000
3+++ NEWS.txt 2011-08-08 10:11:37 +0000
4@@ -73,7 +73,13 @@
5 (Bug #490377, A. S. Budden)
6 * qgetnew:
7 * The target location no longer gets overwritten
8+<<<<<<< TREE
9 when the source location changes. (Andrテゥ Bachmann)
10+=======
11+ when the source location changes. (André Bachmann)
12+ * Base directories for the source branch and the destination checkout folder
13+ can now be configured in qconfig, tab 'User Interface'. (André Bachmann)
14+>>>>>>> MERGE-SOURCE
15 * qlog:
16 * File list context menu: added support to save content of a file
17 of specific revision as a new file. (Andrテゥ Bachmann)
18
19=== modified file 'lib/commands.py'
20--- lib/commands.py 2011-06-30 16:28:58 +0000
21+++ lib/commands.py 2011-08-08 10:11:37 +0000
22@@ -851,7 +851,7 @@
23 takes_options = [ui_mode_option]
24 aliases = ['qgetn']
25
26- def _qbzr_run(self, location=CUR_DIR, ui_mode=False):
27+ def _qbzr_run(self, location=None, ui_mode=False):
28 from bzrlib.plugins.qbzr.lib.getnew import GetNewWorkingTreeWindow
29 self.main_window = GetNewWorkingTreeWindow(location, ui_mode=ui_mode)
30 self.main_window.show()
31
32=== modified file 'lib/config.py'
33--- lib/config.py 2011-08-05 01:07:34 +0000
34+++ lib/config.py 2011-08-08 10:11:37 +0000
35@@ -274,6 +274,34 @@
36 grid.addWidget(label, 0, 0)
37 grid.addWidget(self.spellcheck_language_combo, 0, 1)
38
39+ self.branchsourceBasedirEdit = QtGui.QLineEdit()
40+ self.branchsourceBasedirEdit.setToolTip(gettext("This directory will be automatically filled in your branch source input field"))
41+ btnBranchsourceBasedirBrowse = QtGui.QPushButton(gettext('Browse...'))
42+ self.connect(btnBranchsourceBasedirBrowse,
43+ QtCore.SIGNAL("clicked()"),
44+ self.browseBranchsourceBasedir)
45+ branchsourceBasedirHBox = QtGui.QHBoxLayout()
46+ branchsourceBasedirHBox.addWidget(self.branchsourceBasedirEdit)
47+ branchsourceBasedirHBox.addWidget(btnBranchsourceBasedirBrowse)
48+ label = QtGui.QLabel(gettext("Base directory\nfor &branch sources:"))
49+ label.setBuddy(self.branchsourceBasedirEdit)
50+ grid.addWidget(label, 1, 0)
51+ grid.addLayout(branchsourceBasedirHBox, 1, 1)
52+
53+ self.checkoutBasedirEdit = QtGui.QLineEdit()
54+ self.checkoutBasedirEdit.setToolTip(gettext("This directory will be automatically filled in your checkout destination input field"))
55+ btnCheckoutBasedirBrowse = QtGui.QPushButton(gettext('Browse...'))
56+ self.connect(btnCheckoutBasedirBrowse,
57+ QtCore.SIGNAL("clicked()"),
58+ self.browseCheckoutBasedir)
59+ checkoutBasedirHBox = QtGui.QHBoxLayout()
60+ checkoutBasedirHBox.addWidget(self.checkoutBasedirEdit)
61+ checkoutBasedirHBox.addWidget(btnCheckoutBasedirBrowse)
62+ label = QtGui.QLabel(gettext("Base directory\nfor &checkouts:"))
63+ label.setBuddy(self.checkoutBasedirEdit)
64+ grid.addWidget(label, 2, 0)
65+ grid.addLayout(checkoutBasedirHBox, 2, 1)
66+
67 return tabwidget
68
69 def load(self):
70@@ -325,6 +353,16 @@
71 if index >= 0:
72 self.spellcheck_language_combo.setCurrentIndex(index)
73
74+ # Branch source basedir
75+ branchsourceBasedir = qconfig.get_option('branchsource_basedir')
76+ if branchsourceBasedir:
77+ self.branchsourceBasedirEdit.setText(branchsourceBasedir)
78+
79+ # Checkout basedir
80+ checkoutBasedir = qconfig.get_option('checkout_basedir')
81+ if checkoutBasedir:
82+ self.checkoutBasedirEdit.setText(checkoutBasedir)
83+
84 # Aliases
85 aliases = parser.get('ALIASES', {})
86 for alias, command in aliases.items():
87@@ -471,6 +509,14 @@
88 spellcheck_language = unicode(self.spellcheck_language_combo.itemData(index).toString())
89 set_or_delete_option(parser, 'spellcheck_language', spellcheck_language)
90
91+ # Branch source basedir
92+ branchsource_basedir = unicode(self.branchsourceBasedirEdit.text())
93+ qconfig.set_option('branchsource_basedir', branchsource_basedir)
94+
95+ # Checkout basedir
96+ checkout_basedir = unicode(self.checkoutBasedirEdit.text())
97+ qconfig.set_option('checkout_basedir', checkout_basedir)
98+
99 # Aliases
100 parser['ALIASES'] = {}
101 for index in range(self.aliasesList.topLevelItemCount()):
102@@ -674,6 +720,20 @@
103 '/')
104 if filename:
105 self.editorEdit.setText(filename)
106+
107+ def browseCheckoutBasedir(self):
108+ filename = QtGui.QFileDialog.getExistingDirectory(self,
109+ gettext('Select base directory for checkouts'),
110+ '/')
111+ if filename:
112+ self.checkoutBasedirEdit.setText(filename)
113+
114+ def browseBranchsourceBasedir(self):
115+ filename = QtGui.QFileDialog.getExistingDirectory(self,
116+ gettext('Select default directory for branch sources'),
117+ '/')
118+ if filename:
119+ self.branchsourceBasedirEdit.setText(filename)
120
121
122 def get_user_id_from_os():
123
124=== modified file 'lib/getnew.py'
125--- lib/getnew.py 2011-07-15 12:54:36 +0000
126+++ lib/getnew.py 2011-08-08 10:11:37 +0000
127@@ -32,14 +32,23 @@
128 hookup_directory_picker,
129 DIRECTORYPICKER_SOURCE,
130 DIRECTORYPICKER_TARGET,
131+ get_qbzr_config,
132 )
133-
134+#from bzrlib.trace import mutter
135
136 class GetNewWorkingTreeWindow(SubProcessDialog):
137
138 NAME = "new_tree"
139
140 def __init__(self, to_location, ui_mode=True, parent=None):
141+ config = get_qbzr_config()
142+ checkout_basedir = config.get_option("checkout_basedir")
143+ branchsource_basedir = config.get_option("branchsource_basedir")
144+ #mutter("*** co: %s", checkout_basedir)
145+ #mutter("*** bs: %s", branchsource_basedir)
146+ #mutter("*** to_l: %s", to_location)
147+ if not to_location:
148+ to_location = checkout_basedir or u'.'
149 self.to_location = os.path.abspath(to_location)
150 super(GetNewWorkingTreeWindow, self).__init__(
151 name = self.NAME,
152@@ -73,6 +82,9 @@
153 self.ui.but_checkout.setChecked(True)
154 self.ui.but_rev_tip.setChecked(True)
155 self.ui.to_location.setText(self.to_location)
156+ if branchsource_basedir is not None:
157+ self.from_location = branchsource_basedir
158+ self.ui.from_location.setEditText(self.from_location)
159
160 def to_location_changed(self):
161 self.disconnect(self.ui.from_location, QtCore.SIGNAL("editTextChanged(const QString &)"),
162@@ -83,8 +95,15 @@
163 def from_location_changed(self, new_text):
164 new_val = self.to_location
165 tail = re.split("[:$#\\\\/]", unicode(new_text))[-1]
166+ try:
167+ projectname = re.split("[:$#\\\\/]", unicode(new_text))[-2]
168+ except:
169+ projectname = ""
170 if tail:
171- new_val = os.path.join(new_val, tail)
172+ if self.checkout_basedir is not None:
173+ new_val = os.path.join(self.checkout_basedir, projectname)
174+ else:
175+ new_val = os.path.join(new_val, tail)
176 self.ui.to_location.setText(new_val)
177
178 def do_start(self):

Subscribers

People subscribed via source and target branches