eric7/Plugins/WizardPlugins/SetupWizard/SetupWizardDialog.py

branch
eric7
changeset 9201
2f1ccadee231
parent 9188
d137adc02a0f
child 9202
81388c6065e8
equal deleted inserted replaced
9199:831e08e94960 9201:2f1ccadee231
5 5
6 """ 6 """
7 Module implementing the setup.py wizard dialog. 7 Module implementing the setup.py wizard dialog.
8 """ 8 """
9 9
10 import configparser
11 import datetime
12 import io
10 import os 13 import os
11 import datetime 14 import pathlib
15
16 import tomlkit
12 17
13 import trove_classifiers 18 import trove_classifiers
14 19
15 from PyQt6.QtCore import pyqtSlot, Qt 20 from PyQt6.QtCore import pyqtSlot, Qt
16 from PyQt6.QtWidgets import ( 21 from PyQt6.QtWidgets import (
19 24
20 from EricWidgets.EricApplication import ericApp 25 from EricWidgets.EricApplication import ericApp
21 from EricWidgets import EricFileDialog 26 from EricWidgets import EricFileDialog
22 from EricWidgets.EricPathPicker import EricPathPickerModes 27 from EricWidgets.EricPathPicker import EricPathPickerModes
23 28
29 from .AddEntryPointDialog import AddEntryPointDialog
30 from .AddProjectUrlDialog import AddProjectUrlDialog
24 from .Ui_SetupWizardDialog import Ui_SetupWizardDialog 31 from .Ui_SetupWizardDialog import Ui_SetupWizardDialog
25 32
26 import Utilities 33 import Utilities
27 import Preferences 34 import Preferences
28 35
32 Class implementing the setup.py wizard dialog. 39 Class implementing the setup.py wizard dialog.
33 40
34 It displays a dialog for entering the parameters for the setup.py code 41 It displays a dialog for entering the parameters for the setup.py code
35 generator. 42 generator.
36 """ 43 """
37 def __init__(self, parent=None): 44 def __init__(self, category, parent=None):
38 """ 45 """
39 Constructor 46 Constructor
40 47
41 @param parent reference to the parent widget 48 @param category category of setup file to create
42 @type QWidget 49 @type str
43 """ 50 @param parent reference to the parent widget (defaults to None)
51 @type QWidget (optional)
52 @exception ValueError raised for an illegal setup file category
53 """
54 if category not in ("setup.py", "setup.cfg", "pyproject.toml"):
55 raise ValueError("illegal setup file category given")
56
44 super().__init__(parent) 57 super().__init__(parent)
45 self.setupUi(self) 58 self.setupUi(self)
46 59
47 self.__replies = [] 60 self.__replies = []
61 self.__category = category
62
63 if category != "setup.py":
64 self.introCheckBox.setVisible(False)
65 self.importCheckBox.setVisible(False)
66 self.metaDataCheckBox.setVisible(False)
48 67
49 self.dataTabWidget.setCurrentIndex(0) 68 self.dataTabWidget.setCurrentIndex(0)
50 69
51 self.packageRootPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) 70 self.packageRootPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
52 self.sourceDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) 71 self.sourceDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
68 QDialogButtonBox.StandardButton.Ok) 87 QDialogButtonBox.StandardButton.Ok)
69 self.__okButton.setEnabled(False) 88 self.__okButton.setEnabled(False)
70 89
71 projectOpen = ericApp().getObject("Project").isOpen() 90 projectOpen = ericApp().getObject("Project").isOpen()
72 self.projectButton.setEnabled(projectOpen) 91 self.projectButton.setEnabled(projectOpen)
92
93 self.projectUrlsList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder)
94 self.entryPointsList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder)
95
96 self.descriptionContentTypeComboBox.addItem("", "")
97 for contentType, mimetype in sorted([
98 (self.tr("Plain Text"), "text/plain"),
99 (self.tr("Markdown"), "text/markdown"),
100 (self.tr("reStructuredText"), "text/x-rst")
101
102 ]):
103 self.descriptionContentTypeComboBox.addItem(contentType, mimetype)
73 104
74 self.homePageUrlEdit.textChanged.connect(self.__enableOkButton) 105 self.homePageUrlEdit.textChanged.connect(self.__enableOkButton)
75 self.nameEdit.textChanged.connect(self.__enableOkButton) 106 self.nameEdit.textChanged.connect(self.__enableOkButton)
76 self.versionEdit.textChanged.connect(self.__enableOkButton) 107 self.versionEdit.textChanged.connect(self.__enableOkButton)
77 self.authorEdit.textChanged.connect(self.__enableOkButton) 108 self.authorEdit.textChanged.connect(self.__enableOkButton)
166 lic = self.licenseClassifierComboBox.currentText() 197 lic = self.licenseClassifierComboBox.currentText()
167 if "(" in lic: 198 if "(" in lic:
168 lic = lic.rsplit("(", 1)[1].split(")", 1)[0] 199 lic = lic.rsplit("(", 1)[1].split(")", 1)[0]
169 return lic 200 return lic
170 201
171 def getCode(self, indLevel, indString): 202 def __getSetupPyCode(self, indLevel, indString):
172 """ 203 """
173 Public method to get the source code. 204 Private method to get the source code for a 'setup.py' file.
174 205
175 @param indLevel indentation level 206 @param indLevel indentation level
176 @type int 207 @type int
177 @param indString string used for indentation (space or tab) 208 @param indString string used for indentation (space or tab)
178 @type str 209 @type str
227 sourceCode += "{0}{0}".format(os.linesep) 258 sourceCode += "{0}{0}".format(os.linesep)
228 259
229 if self.descriptionFromFilesCheckBox.isChecked(): 260 if self.descriptionFromFilesCheckBox.isChecked():
230 sourceCode += 'def get_long_description():{0}'.format(os.linesep) 261 sourceCode += 'def get_long_description():{0}'.format(os.linesep)
231 sourceCode += '{0}descr = []{1}'.format(istring, os.linesep) 262 sourceCode += '{0}descr = []{1}'.format(istring, os.linesep)
232 sourceCode += '{0}for fname in "{1}":{2}'.format( 263 sourceCode += '{0}for fname in ("{1})":{2}'.format(
233 istring, 264 istring,
234 '", "'.join(self.descriptionEdit.toPlainText().splitlines()), 265 '", "'.join(self.descriptionEdit.toPlainText().splitlines()),
235 os.linesep) 266 os.linesep)
236 sourceCode += '{0}{0}with open(fname) as f:{1}'.format( 267 sourceCode += (
237 istring, os.linesep) 268 '{0}with open(fname, "r", encoding="utf-8") as f:{1}'
238 sourceCode += '{0}{0}{0}descr.append(f.read()){1}'.format( 269 ).format(i1string, os.linesep)
239 istring, os.linesep) 270 sourceCode += '{0}descr.append(f.read()){1}'.format(
271 i2string, os.linesep)
240 sourceCode += '{0}return "\\n\\n".join(descr){1}'.format( 272 sourceCode += '{0}return "\\n\\n".join(descr){1}'.format(
241 istring, os.linesep) 273 istring, os.linesep)
242 sourceCode += "{0}{0}".format(os.linesep) 274 sourceCode += "{0}{0}".format(os.linesep)
243 275
244 sourceCode += 'setup({0}'.format(os.linesep) 276 sourceCode += 'setup({0}'.format(os.linesep)
256 istring, os.linesep) 288 istring, os.linesep)
257 elif self.descriptionEdit.toPlainText(): 289 elif self.descriptionEdit.toPlainText():
258 sourceCode += '{0}long_description="""{1}""",{2}'.format( 290 sourceCode += '{0}long_description="""{1}""",{2}'.format(
259 istring, self.descriptionEdit.toPlainText(), os.linesep) 291 istring, self.descriptionEdit.toPlainText(), os.linesep)
260 292
293 if self.descriptionContentTypeComboBox.currentData():
294 sourceCode += '{0}long_description_content_type="{1}",{2}'.format(
295 istring, self.descriptionContentTypeComboBox.currentData(), os.linesep)
296
261 if self.authorEdit.text(): 297 if self.authorEdit.text():
262 sourceCode += '{0}author="{1}",{2}'.format( 298 sourceCode += '{0}author="{1}",{2}'.format(
263 istring, self.authorEdit.text(), os.linesep) 299 istring, self.authorEdit.text(), os.linesep)
264 sourceCode += '{0}author_email="{1}",{2}'.format( 300 sourceCode += '{0}author_email="{1}",{2}'.format(
265 istring, self.authorEmailEdit.text(), os.linesep) 301 istring, self.authorEmailEdit.text(), os.linesep)
270 sourceCode += '{0}maintainer_email="{1}",{2}'.format( 306 sourceCode += '{0}maintainer_email="{1}",{2}'.format(
271 istring, self.maintainerEmailEdit.text(), os.linesep) 307 istring, self.maintainerEmailEdit.text(), os.linesep)
272 308
273 sourceCode += '{0}url="{1}",{2}'.format( 309 sourceCode += '{0}url="{1}",{2}'.format(
274 istring, self.homePageUrlEdit.text(), os.linesep) 310 istring, self.homePageUrlEdit.text(), os.linesep)
311 if self.downloadUrlEdit.text():
312 sourceCode += '{0}download_url="{1}",{2}'.format(
313 istring, self.downloadUrlEdit.text(), os.linesep)
314
315 if self.projectUrlsList.topLevelItemCount():
316 sourceCode += '{0}project_urls={{{1}'.format(istring, os.linesep)
317 for row in range(self.projectUrlsList.topLevelItemCount()):
318 urlItem = self.projectUrlsList.topLevelItem(row)
319 sourceCode += '{0}"{1}": "{2}",{3}'.format(
320 i1string, urlItem.text(0), urlItem.text(1), os.linesep)
321 sourceCode += '{0}}},{1}'.format(istring, os.linesep)
275 322
276 classifiers = [] 323 classifiers = []
277 if not self.licenseClassifierCheckBox.isChecked(): 324 if not self.licenseClassifierCheckBox.isChecked():
278 sourceCode += '{0}license="{1}",{2}'.format( 325 sourceCode += '{0}license="{1}",{2}'.format(
279 istring, self.licenseEdit.text(), os.linesep) 326 istring, self.licenseEdit.text(), os.linesep)
290 '",{0}{1}"'.format(os.linesep, i1string).join(platforms), 337 '",{0}{1}"'.format(os.linesep, i1string).join(platforms),
291 os.linesep) 338 os.linesep)
292 sourceCode += '{0}],{1}'.format(istring, os.linesep) 339 sourceCode += '{0}],{1}'.format(istring, os.linesep)
293 340
294 if self.developmentStatusComboBox.currentIndex() != 0: 341 if self.developmentStatusComboBox.currentIndex() != 0:
295 classifiers.append( 342 classifiers.append(self.developmentStatusComboBox.currentData())
296 self.developmentStatusComboBox.itemData(
297 self.developmentStatusComboBox.currentIndex()))
298 343
299 itm = self.classifiersList.topLevelItem(0) 344 itm = self.classifiersList.topLevelItem(0)
300 while itm: 345 while itm:
301 itm.setExpanded(True) 346 itm.setExpanded(True)
302 if itm.checkState(0) == Qt.CheckState.Checked: 347 if itm.checkState(0) == Qt.CheckState.Checked:
315 del classifiers 360 del classifiers
316 361
317 if self.keywordsEdit.text(): 362 if self.keywordsEdit.text():
318 sourceCode += '{0}keywords="{1}",{2}'.format( 363 sourceCode += '{0}keywords="{1}",{2}'.format(
319 istring, self.keywordsEdit.text(), os.linesep) 364 istring, self.keywordsEdit.text(), os.linesep)
365
366 if self.pyVersionEdit.text():
367 sourceCode += '{0}python_requires="{1}",{2}'.format(
368 istring, self.pyVersionEdit.text(), os.linesep)
320 369
321 sourceCode += '{0}packages=find_packages('.format(istring) 370 sourceCode += '{0}packages=find_packages('.format(istring)
322 src = Utilities.fromNativeSeparators( 371 src = Utilities.fromNativeSeparators(
323 self.sourceDirectoryPicker.text()) 372 self.sourceDirectoryPicker.text())
324 excludePatterns = [] 373 excludePatterns = []
355 '",{0}{1}"'.format(os.linesep, i1string).join(modules), 404 '",{0}{1}"'.format(os.linesep, i1string).join(modules),
356 os.linesep) 405 os.linesep)
357 sourceCode += '{0}],{1}'.format(istring, os.linesep) 406 sourceCode += '{0}],{1}'.format(istring, os.linesep)
358 del modules 407 del modules
359 408
360 scripts = [] 409 if self.entryPointsList.topLevelItemCount():
361 for row in range(self.scriptsList.count()): 410 entryPoints = {
362 scripts.append(self.scriptsList.item(row).text()) 411 "console_scripts": [],
363 if scripts: 412 "gui_scripts": [],
364 sourceCode += '{0}scripts=[{1}'.format(istring, os.linesep) 413 }
365 sourceCode += '{0}"{1}"{2}'.format( 414 for row in range(self.entryPointsList.topLevelItemCount()):
366 i1string, 415 itm = self.entryPointsList.topLevelItem(row)
367 '",{0}{1}"'.format(os.linesep, i1string).join(scripts), 416 entryPoints[itm.data(0, Qt.ItemDataRole.UserRole)].append(
368 os.linesep) 417 "{0} = {1}".format(itm.text(1), itm.text(2))
369 sourceCode += '{0}],{1}'.format(istring, os.linesep) 418 )
370 del scripts 419 sourceCode += '{0}entry_points={{{1}'.format(istring, os.linesep)
420 for epCategory in entryPoints:
421 if entryPoints[epCategory]:
422 sourceCode += '{0}"{1}": [{2}'.format(
423 i1string, epCategory, os.linesep)
424 for entryPoint in entryPoints[epCategory]:
425 sourceCode += '{0}"{1}",{2}'.format(
426 i2string, entryPoint, os.linesep)
427 sourceCode += '{0}],{1}'.format(i1string, os.linesep)
428 sourceCode += '{0}}},{1}'.format(istring, os.linesep)
371 429
372 sourceCode += "){0}".format(estring) 430 sourceCode += "){0}".format(estring)
373 return sourceCode 431 return sourceCode
432
433 def __getSetupCfgCode(self):
434 """
435 Private method to get the source code for a 'setup.cfg' file.
436
437 @return generated code
438 @rtype str
439 """
440 from . import SetupCfgUtilities
441 metadata = {
442 "name": self.nameEdit.text(),
443 "version": self.versionEdit.text(),
444 }
445
446 if self.summaryEdit.text():
447 metadata["description"] = self.summaryEdit.text()
448
449 if self.descriptionEdit.toPlainText():
450 metadata["long_description"] = (
451 "file: {0}".format(
452 ", ".join(self.descriptionEdit.toPlainText().splitlines())
453 )
454 if self.descriptionFromFilesCheckBox.isChecked() else
455 self.descriptionEdit.toPlainText()
456 )
457
458 if self.descriptionContentTypeComboBox.currentData():
459 metadata["long_description_content_type"] = (
460 self.descriptionContentTypeComboBox.currentData()
461 )
462
463 if self.authorEdit.text():
464 metadata["author"] = self.authorEdit.text()
465 metadata["author_email"] = self.authorEmailEdit.text()
466
467 if self.maintainerEdit.text():
468 metadata["maintainer"] = self.maintainerEdit.text()
469 metadata["maintainer_email"] = self.maintainerEmailEdit.text()
470
471 metadata["url"] = self.homePageUrlEdit.text()
472 if self.downloadUrlEdit.text():
473 metadata["download_url"] = self.downloadUrlEdit.text()
474
475 if self.projectUrlsList.topLevelItemCount():
476 projectURLs = {}
477 for row in range(self.projectUrlsList.topLevelItemCount()):
478 urlItem = self.projectUrlsList.topLevelItem(row)
479 projectURLs[urlItem.text(0)] = urlItem.text(1)
480 metadata["project_urls"] = SetupCfgUtilities.toString(projectURLs)
481
482 classifiers = []
483 if not self.licenseClassifierCheckBox.isChecked():
484 metadata["license"] = self.licenseEdit.text()
485 else:
486 classifiers.append(
487 self.licenseClassifierComboBox.itemData(
488 self.licenseClassifierComboBox.currentIndex()))
489
490 platforms = self.platformsEdit.toPlainText().splitlines()
491 if platforms:
492 metadata["platforms"] = SetupCfgUtilities.toString(platforms)
493
494 if self.developmentStatusComboBox.currentIndex() != 0:
495 classifiers.append(self.developmentStatusComboBox.currentData())
496
497 itm = self.classifiersList.topLevelItem(0)
498 while itm:
499 itm.setExpanded(True)
500 if itm.checkState(0) == Qt.CheckState.Checked:
501 classifiers.append(itm.data(0, Qt.ItemDataRole.UserRole))
502 itm = self.classifiersList.itemBelow(itm)
503
504 # cleanup classifiers list - remove all invalid entries
505 classifiers = [c for c in classifiers if bool(c)]
506 if classifiers:
507 metadata["classifiers"] = SetupCfgUtilities.toString(classifiers)
508
509 if self.keywordsEdit.text():
510 metadata["keywords"] = SetupCfgUtilities.toString(
511 self.keywordsEdit.text().split())
512
513 options = {
514 "packages": "find:"
515 }
516
517 if self.pyVersionEdit.text():
518 options["python_requires"] = self.pyVersionEdit.text()
519
520 findOptions = {}
521 src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text())
522 excludePatterns = []
523 for row in range(self.excludePatternList.count()):
524 excludePatterns.append(
525 self.excludePatternList.item(row).text())
526 if src:
527 options["package_dir"] = SetupCfgUtilities.toString({"": src})
528 findOptions["where"] = src
529 if excludePatterns:
530 findOptions["exclude"] = SetupCfgUtilities.toString(excludePatterns)
531
532 if self.includePackageDataCheckBox.isChecked():
533 options["include_package_data"] = SetupCfgUtilities.toString(True)
534 packageData = {} # placeholder section
535 else:
536 packageData = None
537
538 modules = []
539 for row in range(self.modulesList.count()):
540 modules.append(self.modulesList.item(row).text())
541 if modules:
542 options["py_modules"] = SetupCfgUtilities.toString(modules)
543
544 if self.entryPointsList.topLevelItemCount():
545 entryPoints = {
546 "console_scripts": {},
547 "gui_scripts": {},
548 }
549 for row in range(self.entryPointsList.topLevelItemCount()):
550 itm = self.entryPointsList.topLevelItem(row)
551 entryPoints[itm.data(0, Qt.ItemDataRole.UserRole)][
552 itm.text(1)] = itm.text(2)
553 for epType in list(entryPoints.keys()):
554 if entryPoints[epType]:
555 entryPoints[epType] = SetupCfgUtilities.toString(
556 entryPoints[epType])
557 else:
558 del entryPoints[epType]
559 else:
560 entryPoints = {}
561
562 configDict = {
563 "metadata": metadata,
564 "options": options,
565 "options.packages.find": findOptions,
566 }
567 if packageData is not None:
568 configDict["options.package_data"] = packageData
569 if entryPoints:
570 configDict["options.entry_points"] = entryPoints
571
572 cparser = configparser.ConfigParser()
573 cparser.read_dict(configDict)
574 sio = io.StringIO()
575 cparser.write(sio)
576 sourceCode = sio.getvalue()
577 return sourceCode
578
579 def __getPyprojectCode(self):
580 """
581 Private method to get the source code for a 'pyproject.toml' file.
582
583 @return generated code
584 @rtype str
585 """
586 doc = tomlkit.document()
587
588 buildSystem = tomlkit.table()
589 buildSystem["requires"] = ["setuptools>=61.0.0", "wheel"]
590 buildSystem["build-backend"] = "setuptools.build_meta"
591 doc["build-system"] = buildSystem
592
593 project = tomlkit.table()
594 project["name"] = self.nameEdit.text()
595 project["version"] = self.versionEdit.text()
596
597 if self.summaryEdit.text():
598 project["description"] = self.summaryEdit.text()
599
600 if self.descriptionEdit.toPlainText():
601 if self.descriptionFromFilesCheckBox.isChecked():
602 project["readme"] = self.descriptionEdit.toPlainText().splitlines()[0]
603 else:
604 readme = tomlkit.table()
605 readme["text"] = self.descriptionEdit.toPlainText()
606 readme["content-type"] = (
607 self.descriptionContentTypeComboBox.currentData()
608 )
609 project["readme"] = readme
610
611 if self.authorEdit.text():
612 authors = tomlkit.array()
613 author = tomlkit.inline_table()
614 author["name"] = self.authorEdit.text()
615 author["email"] = self.authorEmailEdit.text()
616 authors.append(author)
617 project["authors"] = authors
618
619 if self.maintainerEdit.text():
620 maintainers = tomlkit.array()
621 maintainer = tomlkit.inline_table()
622 maintainer["name"] = self.maintainerEdit.text()
623 maintainer["email"] = self.maintainerEmailEdit.text()
624 maintainers.append(maintainer)
625 project["maintainers"] = maintainers
626
627 urls = tomlkit.table()
628 urls["Homepage"] = self.homePageUrlEdit.text()
629 if self.downloadUrlEdit.text():
630 urls["Download"] = self.downloadUrlEdit.text()
631
632 if self.projectUrlsList.topLevelItemCount():
633 for row in range(self.projectUrlsList.topLevelItemCount()):
634 urlItem = self.projectUrlsList.topLevelItem(row)
635 urls[urlItem.text(0)] = urlItem.text(1)
636 project["urls"] = urls
637
638 classifiers = []
639 if not self.licenseClassifierCheckBox.isChecked():
640 license = tomlkit.table()
641 license["text"] = self.licenseEdit.text()
642 project["license"] = license
643 else:
644 classifiers.append(
645 self.licenseClassifierComboBox.itemData(
646 self.licenseClassifierComboBox.currentIndex()))
647
648 if self.developmentStatusComboBox.currentIndex() != 0:
649 classifiers.append(self.developmentStatusComboBox.currentData())
650
651 itm = self.classifiersList.topLevelItem(0)
652 while itm:
653 itm.setExpanded(True)
654 if itm.checkState(0) == Qt.CheckState.Checked:
655 classifiers.append(itm.data(0, Qt.ItemDataRole.UserRole))
656 itm = self.classifiersList.itemBelow(itm)
657
658 # cleanup classifiers list - remove all invalid entries
659 classifiers = [c for c in classifiers if bool(c)]
660 if classifiers:
661 classifiersArray = tomlkit.array()
662 for classifier in classifiers:
663 classifiersArray.add_line(classifier)
664 classifiersArray.append(tomlkit.nl())
665 project["classifiers"] = classifiersArray
666
667 if self.keywordsEdit.text():
668 keywords = tomlkit.array()
669 for kw in self.keywordsEdit.text().split():
670 keywords.add_line(kw)
671 keywords.append(tomlkit.nl())
672 project["keywords"] = keywords
673
674 if self.pyVersionEdit.text():
675 project["requires-python"] = self.pyVersionEdit.text()
676
677 if self.entryPointsList.topLevelItemCount():
678 entryPoints = {
679 "console_scripts": {},
680 "gui_scripts": {},
681 }
682 for row in range(self.entryPointsList.topLevelItemCount()):
683 itm = self.entryPointsList.topLevelItem(row)
684 entryPoints[itm.data(0, Qt.ItemDataRole.UserRole)][
685 itm.text(1)] = itm.text(2)
686
687 if entryPoints["console_scripts"]:
688 scripts = tomlkit.table()
689 for name, function in entryPoints["console_scripts"].items():
690 scripts[name] = function
691 project["scripts"] = scripts
692
693 if entryPoints["gui_scripts"]:
694 guiScripts = tomlkit.table()
695 for name, function in entryPoints["gui_scripts"].items():
696 guiScripts[name] = function
697 project["gui-scripts"] = guiScripts
698
699 # placeholder
700 dependencies = tomlkit.array()
701 dependencies.append(tomlkit.comment(
702 "TODO: enter project dependencies " # __NO-TASK__
703 ))
704 project["dependencies"] = dependencies
705
706 doc["project"] = project
707
708 setuptools = tomlkit.table()
709
710 platforms = self.platformsEdit.toPlainText().splitlines()
711 if platforms:
712 platformsArray = tomlkit.array()
713 for plt in platforms:
714 platformsArray.add_line(plt)
715 platformsArray.append(tomlkit.nl())
716 setuptools["platforms"] = platformsArray
717
718 setuptools["include-package-data"] = self.includePackageDataCheckBox.isChecked()
719 if self.includePackageDataCheckBox.isChecked():
720 # placeholder
721 setuptools["package-data"] = tomlkit.table()
722 setuptools["package-data"].add(tomlkit.comment(
723 "TODO: enter package data patterns" # __NO-TASK__
724 ))
725
726 if self.modulesList.count():
727 modulesArray = tomlkit.array()
728 for row in range(self.modulesList.count()):
729 modulesArray.add_line(self.modulesList.item(row).text())
730 modulesArray.append(tomlkit.nl())
731 setuptools["py-modules"] = modulesArray
732
733 findspec = tomlkit.table()
734 src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text())
735 excludePatterns = []
736 for row in range(self.excludePatternList.count()):
737 excludePatterns.append(
738 self.excludePatternList.item(row).text())
739 if src:
740 findspec["where"] = [ericApp().getObject("Project").getRelativePath(src)]
741 if excludePatterns:
742 excludePatternsArray = tomlkit.array()
743 for pattern in excludePatterns:
744 excludePatternsArray.add_line(pattern)
745 excludePatternsArray.append(tomlkit.nl())
746 findspec["exclude"] = excludePatternsArray
747
748 if bool(findspec):
749 setuptools["packages"] = tomlkit.table(is_super_table=True)
750 setuptools["packages"]["find"] = findspec
751
752 doc["tool"] = tomlkit.table(is_super_table=True)
753 doc["tool"]["setuptools"] = setuptools
754
755 sourceCode = tomlkit.dumps(doc)
756 return sourceCode
757
758 def getCode(self, indLevel, indString):
759 """
760 Public method to get the source code.
761
762 @param indLevel indentation level
763 @type int
764 @param indString string used for indentation (space or tab)
765 @type str
766 @return generated code
767 @rtype str
768 """
769 if self.__category == "setup.py":
770 return self.__getSetupPyCode(indLevel, indString)
771 elif self.__category == "setup.cfg":
772 return self.__getSetupCfgCode()
773 elif self.__category == "pyproject.toml":
774 return self.__getPyprojectCode()
775 else:
776 # should not happen, but play it safe
777 return ""
374 778
375 @pyqtSlot() 779 @pyqtSlot()
376 def on_projectButton_clicked(self): 780 def on_projectButton_clicked(self):
377 """ 781 """
378 Private slot to populate some fields with data retrieved from the 782 Private slot to populate some fields with data retrieved from the
413 """ 817 """
414 return (Preferences.getMultiProject("Workspace") or 818 return (Preferences.getMultiProject("Workspace") or
415 Utilities.getHomeDir()) 819 Utilities.getHomeDir())
416 820
417 @pyqtSlot() 821 @pyqtSlot()
418 def on_scriptsList_itemSelectionChanged(self): 822 def on_entryPointsList_itemSelectionChanged(self):
419 """ 823 """
420 Private slot to handle a change of selected items of the 824 Private slot to handle a change of selected items of the
421 scripts list. 825 entry points list.
422 """ 826 """
423 self.deleteScriptButton.setEnabled( 827 self.deleteEntryPointButton.setEnabled(
424 len(self.scriptsList.selectedItems()) > 0) 828 bool(self.entryPointsList.selectedItems()))
425 829 self.editEntryPointButton.setEnabled(
426 @pyqtSlot() 830 len(self.entryPointsList.selectedItems()) == 1)
427 def on_deleteScriptButton_clicked(self): 831
428 """ 832 @pyqtSlot()
429 Private slot to delete the selected script items. 833 def on_deleteEntryPointButton_clicked(self):
430 """ 834 """
431 for itm in self.scriptsList.selectedItems(): 835 Private slot to delete the selected entry point items.
432 self.scriptsList.takeItem( 836 """
433 self.scriptsList.row(itm)) 837 for itm in self.entryPointsList.selectedItems():
838 self.entryPointsList.takeTopLevelItem(self.entryPointsList.row(itm))
434 del itm 839 del itm
435 840
436 @pyqtSlot() 841 @pyqtSlot()
437 def on_addScriptButton_clicked(self): 842 def on_addEntryPointButton_clicked(self):
438 """ 843 """
439 Private slot to add scripts to the list. 844 Private slot to add an entry point to the list.
440 """ 845 """
441 startDir = self.packageRootPicker.text() or self.__getStartDir() 846 project = ericApp().getObject("Project")
442 scriptsList = EricFileDialog.getOpenFileNames( 847 rootDir = (
443 self, 848 project.getProjectPath()
444 self.tr("Add Scripts"), 849 if project.isOpen() else
445 startDir, 850 ""
446 self.tr("Python Files (*.py);;All Files(*)")) 851 )
447 for script in scriptsList: 852 dlg = AddEntryPointDialog(rootDir, parent=self)
448 script = script.replace( 853 if dlg.exec() == QDialog.DialogCode.Accepted:
449 Utilities.toNativeSeparators(startDir), "") 854 epType, epCategory, name, script = dlg.getEntryPoint()
450 if script.startswith(("\\", "/")): 855 itm = QTreeWidgetItem(self.entryPointsList, [epType, name, script])
451 script = script[1:] 856 itm.setData(0, Qt.ItemDataRole.UserRole, epCategory)
452 if script: 857
453 QListWidgetItem(Utilities.fromNativeSeparators(script), 858 @pyqtSlot()
454 self.scriptsList) 859 def on_editEntryPointButton_clicked(self):
860 """
861 Private slot to edit the selected entry point.
862 """
863 project = ericApp().getObject("Project")
864 rootDir = (
865 project.getProjectPath()
866 if project.isOpen() else
867 ""
868 )
869 itm = self.entryPointsList.selectedItems()[0]
870 dlg = AddEntryPointDialog(rootDir, epType=itm.text(0), name=itm.text(1),
871 script=itm.text(2), parent=self)
872 if dlg.exec() == QDialog.DialogCode.Accepted:
873 epType, epCategory, name, script = dlg.getEntryPoint()
874 itm.setText(0, epType)
875 itm.setText(1, name)
876 itm.setText(2, script)
877 itm.setData(0, Qt.ItemDataRole.UserRole, epCategory)
455 878
456 @pyqtSlot() 879 @pyqtSlot()
457 def on_modulesList_itemSelectionChanged(self): 880 def on_modulesList_itemSelectionChanged(self):
458 """ 881 """
459 Private slot to handle a change of selected items of the 882 Private slot to handle a change of selected items of the
460 modules list. 883 modules list.
461 """ 884 """
462 self.deleteModuleButton.setEnabled( 885 self.deleteModuleButton.setEnabled(
463 len(self.modulesList.selectedItems()) > 0) 886 bool(self.modulesList.selectedItems()))
464 887
465 @pyqtSlot() 888 @pyqtSlot()
466 def on_deleteModuleButton_clicked(self): 889 def on_deleteModuleButton_clicked(self):
467 """ 890 """
468 Private slot to delete the selected script items. 891 Private slot to delete the selected module items.
469 """ 892 """
470 for itm in self.modulesList.selectedItems(): 893 for itm in self.modulesList.selectedItems():
471 self.modulesList.takeItem( 894 self.modulesList.takeItem(self.modulesList.row(itm))
472 self.modulesList.row(itm))
473 del itm 895 del itm
474 896
475 @pyqtSlot() 897 @pyqtSlot()
476 def on_addModuleButton_clicked(self): 898 def on_addModuleButton_clicked(self):
477 """ 899 """
487 module = module.replace( 909 module = module.replace(
488 Utilities.toNativeSeparators(startDir), "") 910 Utilities.toNativeSeparators(startDir), "")
489 if module.startswith(("\\", "/")): 911 if module.startswith(("\\", "/")):
490 module = module[1:] 912 module = module[1:]
491 if module: 913 if module:
492 QListWidgetItem(os.path.splitext(module)[0] 914 QListWidgetItem(
493 .replace("\\", ".").replace("/", "."), 915 str(pathlib.Path(module).with_suffix(""))
494 self.modulesList) 916 .replace("\\", ".")
917 .replace("/", "."),
918 self.modulesList
919 )
495 920
496 @pyqtSlot() 921 @pyqtSlot()
497 def on_excludePatternList_itemSelectionChanged(self): 922 def on_excludePatternList_itemSelectionChanged(self):
498 """ 923 """
499 Private slot to handle a change of selected items of the 924 Private slot to handle a change of selected items of the
500 exclude pattern list. 925 exclude pattern list.
501 """ 926 """
502 self.deleteExcludePatternButton.setEnabled( 927 self.deleteExcludePatternButton.setEnabled(
503 len(self.excludePatternList.selectedItems()) > 0) 928 bool(self.excludePatternList.selectedItems()))
504 929
505 @pyqtSlot() 930 @pyqtSlot()
506 def on_deleteExcludePatternButton_clicked(self): 931 def on_deleteExcludePatternButton_clicked(self):
507 """ 932 """
508 Private slot to delete the selected exclude pattern items. 933 Private slot to delete the selected exclude pattern items.
541 """ 966 """
542 Private slot handling a press of the return button of the 967 Private slot handling a press of the return button of the
543 exclude pattern edit. 968 exclude pattern edit.
544 """ 969 """
545 self.on_addExludePatternButton_clicked() 970 self.on_addExludePatternButton_clicked()
971
972 @pyqtSlot()
973 def on_urlDeleteButton_clicked(self):
974 """
975 Private slot to delete the selected URL items.
976 """
977 for itm in self.projectUrlsList.selectedItems():
978 self.projectUrlsList.takeTopLevelItem(self.projectUrlsList.row(itm))
979 del itm
980
981 @pyqtSlot()
982 def on_urlAddButton_clicked(self):
983 """
984 Private slot to add a project URL to the list.
985 """
986 dlg = AddProjectUrlDialog(parent=self)
987 if dlg.exec() == QDialog.DialogCode.Accepted:
988 name, url = dlg.getUrl()
989 QTreeWidgetItem(self.projectUrlsList, [name, url])
990
991 @pyqtSlot()
992 def on_urlEditButton_clicked(self):
993 """
994 Private slot to edit the selected project URL.
995 """
996 itm = self.projectUrlsList.selectedItems()[0]
997 dlg = AddProjectUrlDialog(name=itm.text(0), url=itm.text(1), parent=self)
998 if dlg.exec() == QDialog.DialogCode.Accepted:
999 name, url = dlg.getUrl()
1000 itm.setText(0, name)
1001 itm.setText(1, url)
1002
1003 @pyqtSlot()
1004 def on_projectUrlsList_itemSelectionChanged(self):
1005 """
1006 Private slot to handle a change of selected items of the
1007 project URLs list.
1008 """
1009 self.urlDeleteButton.setEnabled(bool(self.projectUrlsList.selectedItems()))
1010 self.urlEditButton.setEnabled(len(self.projectUrlsList.selectedItems()) == 1)

eric ide

mercurial