/tortoisehg/hgqt/hginit.py

https://bitbucket.org/tortoisehg/hgtk/ · Python · 226 lines · 173 code · 29 blank · 24 comment · 28 complexity · 6f8f69c03ea8142190882351502b4110 MD5 · raw file

  1. # hginit.py - TortoiseHg dialog to initialize a repo
  2. #
  3. # Copyright 2008 Steve Borho <steve@borho.org>
  4. # Copyright 2010 Johan Samyn <johan.samyn@gmail.com>
  5. #
  6. # This software may be used and distributed according to the terms of the
  7. # GNU General Public License version 2, incorporated herein by reference.
  8. import os
  9. from mercurial import hg, ui, error, util
  10. from tortoisehg.hgqt.i18n import _
  11. from tortoisehg.hgqt import qtlib
  12. from tortoisehg.util import hglib, shlib
  13. from PyQt4.QtCore import *
  14. from PyQt4.QtGui import *
  15. class InitDialog(QDialog):
  16. """TortoiseHg init dialog"""
  17. def __init__(self, destdir=[], opts={}, parent=None):
  18. super(InitDialog, self).__init__(parent)
  19. # main layout
  20. self.vbox = QVBoxLayout()
  21. self.vbox.setSpacing(6)
  22. self.grid = QGridLayout()
  23. self.grid.setSpacing(6)
  24. self.vbox.addLayout(self.grid)
  25. # dest widgets
  26. self.dest_lbl = QLabel(_('Destination path:'))
  27. self.dest_edit = QLineEdit()
  28. self.dest_edit.setMinimumWidth(300)
  29. self.dest_btn = QPushButton(_('Browse...'))
  30. self.dest_btn.setAutoDefault(False)
  31. self.grid.addWidget(self.dest_lbl, 0, 0)
  32. self.grid.addWidget(self.dest_edit, 0, 1)
  33. self.grid.addWidget(self.dest_btn, 0, 2)
  34. # options checkboxes
  35. self.add_files_chk = QCheckBox(
  36. _('Add special files (.hgignore, ...)'))
  37. self.make_pre_1_7_chk = QCheckBox(
  38. _('Make repo compatible with Mercurial <1.7'))
  39. self.run_wb_chk = QCheckBox(
  40. _('Show in Workbench after init'))
  41. self.grid.addWidget(self.add_files_chk, 1, 1)
  42. self.grid.addWidget(self.make_pre_1_7_chk, 2, 1)
  43. if not self.parent():
  44. self.grid.addWidget(self.run_wb_chk, 3, 1)
  45. # buttons
  46. self.init_btn = QPushButton(_('Create'))
  47. self.init_btn.setDefault(True)
  48. self.close_btn = QPushButton(_('&Close'))
  49. self.close_btn.setAutoDefault(False)
  50. self.hbox = QHBoxLayout()
  51. self.hbox.addStretch(0)
  52. self.hbox.addWidget(self.init_btn)
  53. self.hbox.addWidget(self.close_btn)
  54. self.vbox.addLayout(self.hbox)
  55. # some extras
  56. self.hgcmd_lbl = QLabel(_('Hg command:'))
  57. self.hgcmd_lbl.setAlignment(Qt.AlignRight)
  58. self.hgcmd_txt = QLineEdit()
  59. self.hgcmd_txt.setReadOnly(True)
  60. self.grid.addWidget(self.hgcmd_lbl, 4, 0)
  61. self.grid.addWidget(self.hgcmd_txt, 4, 1)
  62. # init defaults
  63. self.cwd = os.getcwd()
  64. path = os.path.abspath(destdir and destdir[0] or self.cwd)
  65. if os.path.isfile(path):
  66. path = os.path.dirname(path)
  67. self.dest_edit.setText(hglib.tounicode(path))
  68. self.add_files_chk.setChecked(True)
  69. self.make_pre_1_7_chk.setChecked(False)
  70. self.compose_command()
  71. # dialog settings
  72. self.setWindowTitle(_('Init'))
  73. self.setWindowIcon(qtlib.geticon('init'))
  74. self.setWindowFlags(
  75. self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
  76. self.setLayout(self.vbox)
  77. self.layout().setSizeConstraint(QLayout.SetFixedSize)
  78. self.dest_edit.setFocus()
  79. # connecting slots
  80. self.dest_edit.textChanged.connect(self.compose_command)
  81. self.dest_btn.clicked.connect(self.browse_clicked)
  82. self.init_btn.clicked.connect(self.init)
  83. self.close_btn.clicked.connect(self.close)
  84. self.make_pre_1_7_chk.toggled.connect(self.compose_command)
  85. def browse_clicked(self):
  86. """Select the destination directory"""
  87. dest = hglib.fromunicode(self.dest_edit.text())
  88. if not os.path.exists(dest):
  89. dest = os.path.dirname(dest)
  90. FD = QFileDialog
  91. caption = _('Select Destination Folder')
  92. path = FD.getExistingDirectory(parent=self, caption=caption,
  93. options=FD.ShowDirsOnly | FD.ReadOnly)
  94. response = str(path)
  95. if response:
  96. self.dest_edit.setText(response)
  97. def compose_command(self):
  98. # just a stub for extension with extra options (--mq, --ssh, ...)
  99. cmd = ['hg', 'init']
  100. if self.make_pre_1_7_chk.isChecked():
  101. cmd.append('--config format.dotencode=False')
  102. cmd.append(self.getPath())
  103. self.hgcmd_txt.setText(hglib.tounicode(' '.join(cmd)))
  104. def getPath(self):
  105. return hglib.fromunicode(self.dest_edit.text()).strip()
  106. def init(self):
  107. dest = self.getPath()
  108. if dest == '':
  109. qtlib.ErrorMsgBox(_('Error executing init'),
  110. _('Destination path is empty'),
  111. _('Please enter the directory path'))
  112. self.dest_edit.setFocus()
  113. return False
  114. dest = os.path.normpath(dest)
  115. self.dest_edit.setText(hglib.tounicode(dest))
  116. udest = self.dest_edit.text()
  117. if not os.path.exists(dest):
  118. p = dest
  119. l = 0
  120. while not os.path.exists(p):
  121. l += 1
  122. p, t = os.path.split(p)
  123. if not t:
  124. break # already root path
  125. if l > 1:
  126. res = qtlib.QuestionMsgBox(_('Init'),
  127. _('Are you sure about adding the new repository'
  128. ' %d extra levels deep?') % l,
  129. _('Path exists up to:\n%s\nand you asked for:\n%s')
  130. % (p, udest),
  131. defaultbutton=QMessageBox.No)
  132. if not res:
  133. self.dest_edit.setFocus()
  134. return
  135. try:
  136. # create the folder, just like Hg would
  137. os.makedirs(dest)
  138. except:
  139. qtlib.ErrorMsgBox(_('Error executing init'),
  140. _('Cannot create folder %s' % udest))
  141. return False
  142. _ui = ui.ui()
  143. # dotencode is the new default repo format in Mercurial 1.7
  144. if self.make_pre_1_7_chk.isChecked():
  145. _ui.setconfig('format', 'dotencode', 'False')
  146. try:
  147. # create the new repo
  148. hg.repository(_ui, dest, create=1)
  149. except error.RepoError, inst:
  150. qtlib.ErrorMsgBox(_('Error executing init'),
  151. _('Unable to create new repository'),
  152. hglib.tounicode(str(inst)))
  153. return False
  154. except util.Abort, inst:
  155. if e.hint:
  156. err = _('%s (hint: %s)') % (hglib.tounicode(str(e)),
  157. hglib.tounicode(e.hint))
  158. else:
  159. err = hglib.tounicode(str(e))
  160. qtlib.ErrorMsgBox(_('Error executing init'),
  161. _('Error when creating repository'), err)
  162. return False
  163. except:
  164. import traceback
  165. qtlib.ErrorMsgBox(_('Error executing init'),
  166. _('Error when creating repository'),
  167. traceback.format_exc())
  168. return False
  169. # Create the .hg* file, mainly to workaround
  170. # Explorer's problem in creating files with a name
  171. # beginning with a dot.
  172. if (self.add_files_chk.isChecked() and
  173. os.path.exists(os.path.sep.join([dest, '.hg']))):
  174. hgignore = os.path.join(dest, '.hgignore')
  175. if not os.path.exists(hgignore):
  176. try:
  177. open(hgignore, 'wb')
  178. except:
  179. pass
  180. if self.run_wb_chk.isChecked():
  181. from tortoisehg.hgqt import run
  182. try:
  183. run.log(ui.ui(), root=dest)
  184. except Exception, e:
  185. qtlib.WarningMsgBox(_('Init'),
  186. _('<p>Repository successfully created at</p><p>%s</p>') % dest,
  187. _('<p>But could not run Workbench for it.</p><p>%s</p>')
  188. % hglib.tounicode(str(e)))
  189. else:
  190. if not self.parent():
  191. qtlib.InfoMsgBox(_('Init'),
  192. _('<p>Repository successfully created at</p><p>%s</p>') % udest)
  193. self.accept()
  194. def reject(self):
  195. super(InitDialog, self).reject()
  196. def run(ui, *pats, **opts):
  197. return InitDialog(pats, opts)