|
6 | 6 | import glob |
7 | 7 | import multiprocessing |
8 | 8 | import os |
| 9 | +import platform |
9 | 10 | import re |
10 | 11 | import subprocess |
11 | 12 | from subprocess import check_output |
@@ -412,6 +413,14 @@ class CheckFailed(Exception): |
412 | 413 |
|
413 | 414 | class SetupPackage(object): |
414 | 415 | optional = False |
| 416 | + pkg_names = { |
| 417 | + "apt-get": None, |
| 418 | + "yum": None, |
| 419 | + "dnf": None, |
| 420 | + "brew": None, |
| 421 | + "port": None, |
| 422 | + "windows_url": None |
| 423 | + } |
415 | 424 |
|
416 | 425 | def check(self): |
417 | 426 | """ |
@@ -531,6 +540,56 @@ def do_custom_build(self): |
531 | 540 | """ |
532 | 541 | pass |
533 | 542 |
|
| 543 | + def install_help_msg(self): |
| 544 | + """ |
| 545 | + Do not override this method ! |
| 546 | +
|
| 547 | + Generate the help message to show if the package is not installed. |
| 548 | + To use this in subclasses, simply add the dictionary `pkg_names` as |
| 549 | + a class variable: |
| 550 | +
|
| 551 | + pkg_names = { |
| 552 | + "apt-get": <Name of the apt-get package>, |
| 553 | + "yum": <Name of the yum package>, |
| 554 | + "dnf": <Name of the dnf package>, |
| 555 | + "brew": <Name of the brew package>, |
| 556 | + "port": <Name of the port package>, |
| 557 | + "windows_url": <The url which has installation instructions> |
| 558 | + } |
| 559 | +
|
| 560 | + All the dictionary keys are optional. If a key is not present or has |
| 561 | + the value `None` no message is provided for that platform. |
| 562 | + """ |
| 563 | + def _try_managers(*managers): |
| 564 | + for manager in managers: |
| 565 | + pkg_name = self.pkg_names.get(manager, None) |
| 566 | + if pkg_name: |
| 567 | + try: |
| 568 | + # `shutil.which()` can be used when Python 2.7 support |
| 569 | + # is dropped. It is available in Python 3.3+ |
| 570 | + _ = check_output(["which", manager], |
| 571 | + stderr=subprocess.STDOUT) |
| 572 | + return ('Try installing {0} with `{1} install {2}`' |
| 573 | + .format(self.name, manager, pkg_name)) |
| 574 | + except subprocess.CalledProcessError: |
| 575 | + pass |
| 576 | + |
| 577 | + message = None |
| 578 | + if sys.platform == "win32": |
| 579 | + url = self.pkg_names.get("windows_url", None) |
| 580 | + if url: |
| 581 | + message = ('Please check {0} for instructions to install {1}' |
| 582 | + .format(url, self.name)) |
| 583 | + elif sys.platform == "darwin": |
| 584 | + message = _try_managers("brew", "port") |
| 585 | + elif sys.platform.startswith("linux"): |
| 586 | + release = platform.linux_distribution()[0].lower() |
| 587 | + if release in ('debian', 'ubuntu'): |
| 588 | + message = _try_managers('apt-get') |
| 589 | + elif release in ('centos', 'redhat', 'fedora'): |
| 590 | + message = _try_managers('dnf', 'yum') |
| 591 | + return message |
| 592 | + |
534 | 593 |
|
535 | 594 | class OptionalPackage(SetupPackage): |
536 | 595 | optional = True |
@@ -953,6 +1012,14 @@ def add_flags(self, ext, add_sources=True): |
953 | 1012 |
|
954 | 1013 | class FreeType(SetupPackage): |
955 | 1014 | name = "freetype" |
| 1015 | + pkg_names = { |
| 1016 | + "apt-get": "libfreetype6-dev", |
| 1017 | + "yum": "freetype-devel", |
| 1018 | + "dnf": "freetype-devel", |
| 1019 | + "brew": "freetype", |
| 1020 | + "port": "freetype", |
| 1021 | + "windows_url": "http://gnuwin32.sourceforge.net/packages/freetype.htm" |
| 1022 | + } |
956 | 1023 |
|
957 | 1024 | def check(self): |
958 | 1025 | if options.get('local_freetype'): |
@@ -1167,6 +1234,14 @@ def get_extension(self): |
1167 | 1234 |
|
1168 | 1235 | class Png(SetupPackage): |
1169 | 1236 | name = "png" |
| 1237 | + pkg_names = { |
| 1238 | + "apt-get": "libpng12-dev", |
| 1239 | + "yum": "libpng-devel", |
| 1240 | + "dnf": "libpng-devel", |
| 1241 | + "brew": "libpng", |
| 1242 | + "port": "libpng", |
| 1243 | + "windows_url": "http://gnuwin32.sourceforge.net/packages/libpng.htm" |
| 1244 | + } |
1170 | 1245 |
|
1171 | 1246 | def check(self): |
1172 | 1247 | if sys.platform == 'win32': |
|
0 commit comments