diff options
author | bill-auger <mr.j.spam.me@gmail.com> | 2020-01-18 20:06:11 -0500 |
---|---|---|
committer | bill-auger <mr.j.spam.me@gmail.com> | 2020-01-19 08:53:38 -0500 |
commit | 72851d5f27f4fafefc20922de319e133caa53449 (patch) | |
tree | 1ff8686ca22b2a2be98cba361c611adf3052cd9f /libre/iceweasel/firefox-70.0-add-distro.patch | |
parent | 16b80f1f2bbecf98375b588f62a9bab77bc2e315 (diff) | |
download | abslibre-72851d5f27f4fafefc20922de319e133caa53449.tar.gz abslibre-72851d5f27f4fafefc20922de319e133caa53449.tar.bz2 abslibre-72851d5f27f4fafefc20922de319e133caa53449.zip |
[iceweasel]: rework patches for v72.0.1
Diffstat (limited to 'libre/iceweasel/firefox-70.0-add-distro.patch')
-rw-r--r-- | libre/iceweasel/firefox-70.0-add-distro.patch | 6965 |
1 files changed, 0 insertions, 6965 deletions
diff --git a/libre/iceweasel/firefox-70.0-add-distro.patch b/libre/iceweasel/firefox-70.0-add-distro.patch deleted file mode 100644 index 8db8ce5dc..000000000 --- a/libre/iceweasel/firefox-70.0-add-distro.patch +++ /dev/null @@ -1,6965 +0,0 @@ - -# HG changeset patch -# User Edwin Takahashi <egao@mozilla.com> -# Date 1572468170 0 -# Node ID d2d9fe01fc33af4538940e833a6696d973ebea74 -# Parent eddb9fcaaa4bd4fdb4e32024f92f969abfe92f58 -Bug 1212502 - Switch mozinfo to using the 'distro' package to get linux distribution info r=ahal,KWierso - -Differential Revision: https://phabricator.services.mozilla.com/D49366 - -diff --git a/build/virtualenv_packages.txt b/build/virtualenv_packages.txt ---- a/build/virtualenv_packages.txt -+++ b/build/virtualenv_packages.txt -@@ -10,16 +10,17 @@ mozilla.pth:third_party/python/atomicwri - mozilla.pth:third_party/python/attrs/src - python2:mozilla.pth:third_party/python/backports - mozilla.pth:third_party/python/biplist - mozilla.pth:third_party/python/blessings - mozilla.pth:third_party/python/Click - mozilla.pth:third_party/python/compare-locales - mozilla.pth:third_party/python/configobj - mozilla.pth:third_party/python/cram -+mozilla.pth:third_party/python/distro - mozilla.pth:third_party/python/dlmanager - mozilla.pth:third_party/python/enum34 - mozilla.pth:third_party/python/fluent - mozilla.pth:third_party/python/funcsigs - python2:mozilla.pth:third_party/python/futures - mozilla.pth:third_party/python/mohawk - mozilla.pth:third_party/python/more-itertools - mozilla.pth:third_party/python/mozilla-version -diff --git a/python/mozbuild/mozbuild/action/test_archive.py b/python/mozbuild/mozbuild/action/test_archive.py ---- a/python/mozbuild/mozbuild/action/test_archive.py -+++ b/python/mozbuild/mozbuild/action/test_archive.py -@@ -245,16 +245,22 @@ ARCHIVE_FILES = { - }, - { - 'source': buildconfig.topsrcdir, - 'base': 'third_party/python/six', - 'pattern': '**', - 'dest': 'tools/six', - }, - { -+ 'source': buildconfig.topsrcdir, -+ 'base': 'third_party/python/distro', -+ 'pattern': '**', -+ 'dest': 'tools/distro', -+ }, -+ { - 'source': buildconfig.topobjdir, - 'base': '', - 'pattern': 'mozinfo.json', - }, - { - 'source': buildconfig.topobjdir, - 'base': 'dist/bin', - 'patterns': [ -@@ -431,16 +437,22 @@ ARCHIVE_FILES = { - 'dest': 'mozharness', - }, - { - 'source': buildconfig.topsrcdir, - 'base': 'third_party/python/six', - 'pattern': 'six.py', - 'dest': 'mozharness', - }, -+ { -+ 'source': buildconfig.topsrcdir, -+ 'base': 'third_party/python/distro', -+ 'pattern': 'distro.py', -+ 'dest': 'mozharness', -+ }, - ], - 'reftest': [ - { - 'source': buildconfig.topobjdir, - 'base': '_tests', - 'pattern': 'reftest/**', - }, - { -diff --git a/testing/mozbase/mozinfo/mozinfo/mozinfo.py b/testing/mozbase/mozinfo/mozinfo/mozinfo.py ---- a/testing/mozbase/mozinfo/mozinfo/mozinfo.py -+++ b/testing/mozbase/mozinfo/mozinfo/mozinfo.py -@@ -9,16 +9,17 @@ - # information and having behaviour depend on it - - from __future__ import absolute_import, print_function - - import os - import platform - import re - import sys -+ - from .string_version import StringVersion - from ctypes.util import find_library - - # keep a copy of the os module since updating globals overrides this - _os = os - - - class unknown(object): -@@ -93,35 +94,45 @@ if system in ["Microsoft", "Windows"]: - version = "%d.%d.%d" % (major, minor, build_number) - - os_version = "%d.%d" % (major, minor) - elif system.startswith(('MINGW', 'MSYS_NT')): - # windows/mingw python build (msys) - info['os'] = 'win' - os_version = version = unknown - elif system == "Linux": -- if hasattr(platform, "linux_distribution"): -- (distro, os_version, codename) = platform.linux_distribution() -+ # Only attempt to import distro for Linux. -+ # https://github.com/nir0s/distro/issues/177 -+ try: -+ import distro -+ except ImportError: -+ pass -+ # First use distro package, then fall back to platform. -+ # This will only until Mozilla upgrades python to 3.8. -+ if hasattr(distro, "linux_distribution"): -+ (distribution, os_version, codename) = distro.linux_distribution() -+ elif hasattr(platform, "linux_distribution"): -+ (distribution, os_version, codename) = platform.linux_distribution() - else: -- (distro, os_version, codename) = platform.dist() -+ (distribution, os_version, codename) = platform.dist() - if not processor: - processor = machine -- version = "%s %s" % (distro, os_version) -+ version = "%s %s" % (distribution, os_version) - - # Bug in Python 2's `platform` library: - # It will return a triple of empty strings if the distribution is not supported. - # It works on Python 3. If we don't have an OS version, - # the unit tests fail to run. -- if not distro and not os_version and not codename: -- distro = 'lfs' -+ if not distribution and not os_version and not codename: -+ distribution = 'lfs' - version = release - os_version = release - - info['os'] = 'linux' -- info['linux_distro'] = distro -+ info['linux_distro'] = distribution - elif system in ['DragonFly', 'FreeBSD', 'NetBSD', 'OpenBSD']: - info['os'] = 'bsd' - version = os_version = sys.platform - elif system == "Darwin": - (release, versioninfo, machine) = platform.mac_ver() - version = "OS X %s" % release - versionNums = release.split('.')[:2] - os_version = "%s.%s" % (versionNums[0], versionNums[1]) -diff --git a/testing/mozbase/mozinfo/setup.py b/testing/mozbase/mozinfo/setup.py ---- a/testing/mozbase/mozinfo/setup.py -+++ b/testing/mozbase/mozinfo/setup.py -@@ -4,17 +4,20 @@ - - from __future__ import absolute_import - - from setuptools import setup - - PACKAGE_VERSION = "1.1.0" - - # dependencies --deps = ["mozfile >= 0.12"] -+deps = [ -+ "distro == 1.4.0", -+ "mozfile >= 0.12", -+] - - setup( - name="mozinfo", - version=PACKAGE_VERSION, - description="Library to get system information for use in Mozilla testing", - long_description="see https://firefox-source-docs.mozilla.org/mozbase/index.html", - classifiers=[ - "Programming Language :: Python :: 2.7", -diff --git a/testing/mozharness/tox.ini b/testing/mozharness/tox.ini ---- a/testing/mozharness/tox.ini -+++ b/testing/mozharness/tox.ini -@@ -1,14 +1,15 @@ - [tox] - envlist = py27-hg4.3 - - [base] - deps = - coverage -+ distro - nose - rednose - {toxinidir}/../mozbase/mozlog - mozbase = {toxinidir}/../mozbase/ - - - [testenv] - basepython = python2.7 -diff --git a/third_party/python/distro/CHANGELOG.md b/third_party/python/distro/CHANGELOG.md -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/CHANGELOG.md -@@ -0,0 +1,147 @@ -+## 1.4.0 (2019.2.4) -+ -+BACKWARD COMPATIBILITY: -+* Prefer the VERSION_CODENAME field of os-release to parsing it from VERSION [[#230](https://github.com/nir0s/distro/pull/230)] -+ -+BUG FIXES: -+* Return _uname_info from the uname_info() method [[#233](https://github.com/nir0s/distro/pull/233)] -+* Fixed CloudLinux id discovery [[#234](https://github.com/nir0s/distro/pull/234)] -+* Update Oracle matching [[#224](https://github.com/nir0s/distro/pull/224)] -+ -+DOCS: -+* Update Fedora package link [[#225](https://github.com/nir0s/distro/pull/225)] -+* Distro is the recommended replacement for platform.linux_distribution [[#220](https://github.com/nir0s/distro/pull/220)] -+ -+RELEASE: -+* Use Markdown for long description in setup.py [[#219](https://github.com/nir0s/distro/pull/219)] -+ -+Additionally, The Python2.6 branch was fixed and rebased on top of master. It is now passing all tests. Thanks [abadger](https://github.com/abadger)! -+ -+## 1.3.0 (2018.05.09) -+ -+ENHANCEMENTS: -+* Added support for OpenBSD, FreeBSD, and NetBSD [[#207](https://github.com/nir0s/distro/issues/207)] -+ -+TESTS: -+* Add test for Kali Linux Rolling [[#214](https://github.com/nir0s/distro/issues/214)] -+ -+DOCS: -+* Update docs with regards to #207 [[#209](https://github.com/nir0s/distro/issues/209)] -+* Add Ansible reference implementation and fix arch-linux link [[#213](https://github.com/nir0s/distro/issues/213)] -+* Add facter reference implementation [[#213](https://github.com/nir0s/distro/issues/213)] -+ -+## 1.2.0 (2017.12.24) -+ -+BACKWARD COMPATIBILITY: -+* Don't raise ImportError on non-linux platforms [[#202](https://github.com/nir0s/distro/issues/202)] -+ -+ENHANCEMENTS: -+* Lazily load the LinuxDistribution data [[#201](https://github.com/nir0s/distro/issues/201)] -+ -+BUG FIXES: -+* Stdout of shell should be decoded with sys.getfilesystemencoding() [[#203](https://github.com/nir0s/distro/issues/203)] -+ -+TESTS: -+* Explicitly set Python versions on Travis for flake [[#204](https://github.com/nir0s/distro/issues/204)] -+ -+ -+## 1.1.0 (2017.11.28) -+ -+BACKWARD COMPATIBILITY: -+* Drop python3.3 support [[#199](https://github.com/nir0s/distro/issues/199)] -+* Remove Official Python26 support [[#195](https://github.com/nir0s/distro/issues/195)] -+ -+TESTS: -+* Add MandrivaLinux test case [[#181](https://github.com/nir0s/distro/issues/181)] -+* Add test cases for CloudLinux 5, 6, and 7 [[#180](https://github.com/nir0s/distro/issues/180)] -+ -+RELEASE: -+* Modify MANIFEST to include resources for tests and docs in source tarballs [[97c91a1](97c91a1)] -+ -+## 1.0.4 (2017.04.01) -+ -+BUG FIXES: -+* Guess common *-release files if /etc not readable [[#175](https://github.com/nir0s/distro/issues/175)] -+ -+## 1.0.3 (2017.03.19) -+ -+ENHANCEMENTS: -+* Show keys for empty values when running distro from the CLI [[#160](https://github.com/nir0s/distro/issues/160)] -+* Add manual mapping for `redhatenterpriseserver` (previously only redhatenterpriseworkstation was mapped) [[#148](https://github.com/nir0s/distro/issues/148)] -+* Race condition in `_parse_distro_release_file` [[#163](https://github.com/nir0s/distro/issues/163)] -+ -+TESTS: -+* Add RHEL5 test case [[#165](https://github.com/nir0s/distro/issues/165)] -+* Add OpenELEC test case [[#166](https://github.com/nir0s/distro/issues/166)] -+* Replace nose with pytest [[#158](https://github.com/nir0s/distro/issues/158)] -+ -+RELEASE: -+* Update classifiers -+* Update supported Python versions (with py36) -+ -+## 1.0.2 (2017.01.12) -+ -+TESTS: -+* Test on py33, py36 and py3 based flake8 -+ -+RELEASE: -+* Add MANIFEST file (which also includes the LICENSE as part of Issue [[#139](https://github.com/nir0s/distro/issues/139)]) -+* Default to releasing using Twine [[#121](https://github.com/nir0s/distro/issues/121)] -+* Add setup.cfg file [[#145](https://github.com/nir0s/distro/issues/145)] -+* Update license in setup.py -+ -+## 1.0.1 (2016-11-03) -+ -+ENHANCEMENTS: -+* Prettify distro -j's output and add more elaborate docs [[#147](https://github.com/nir0s/distro/issues/147)] -+* Decode output of `lsb_release` as utf-8 [[#144](https://github.com/nir0s/distro/issues/144)] -+* Logger now uses `message %s, string` form to not-evaulate log messages if unnecessary [[#145](https://github.com/nir0s/distro/issues/145)] -+ -+TESTS: -+* Increase code-coverage [[#146](https://github.com/nir0s/distro/issues/146)] -+* Fix landscape code-quality warnings [[#145](https://github.com/nir0s/distro/issues/145)] -+ -+RELEASE: -+* Add CONTRIBUTING.md -+ -+## 1.0.0 (2016-09-25) -+ -+BACKWARD COMPATIBILITY: -+* raise exception when importing on non-supported platforms [[#129](https://github.com/nir0s/distro/issues/129)] -+ -+ENHANCEMENTS: -+* Use `bytes` invariantly [[#135](https://github.com/nir0s/distro/issues/135)] -+* Some minor code adjustments plus a CLI [[#134](https://github.com/nir0s/distro/issues/134)] -+* Emit stderr if `lsb_release` fails -+ -+BUG FIXES: -+* Fix some encoding related issues -+ -+TESTS: -+* Add many test cases (e.g. Raspbian 8, CoreOS, Amazon Linux, Scientific Linux, Gentoo, Manjaro) -+* Completely redo the testing framework to make it easier to add tests -+* Test on pypy -+ -+RELEASE: -+* Remove six as a dependency -+ -+## 0.6.0 (2016-04-21) -+ -+This is the first release of `distro`. -+All previous work was done on `ld` and therefore unmentioned here. See the release log in GitHub if you want the entire log. -+ -+BACKWARD COMPATIBILITY: -+* No longer a package. constants.py has been removed and distro is now a single module -+ -+ENHANCEMENTS: -+* distro.info() now receives best and pretty flags -+* Removed get_ prefix from get_*_release_attr functions -+* Codename is now passed in distro.info() -+ -+TESTS: -+* Added Linux Mint test case -+* Now testing on Python 3.4 -+ -+DOCS: -+* Documentation fixes -+ -diff --git a/third_party/python/distro/CONTRIBUTING.md b/third_party/python/distro/CONTRIBUTING.md -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/CONTRIBUTING.md -@@ -0,0 +1,54 @@ -+# General -+ -+* Contributing to distro identification currently doesn't have any specific standards and rather depends on the specific implementation. -+* A 100% coverage is expected for each PR unless explicitly authorized by the reviewer. -+* Please try to maintain maximum code-health (via landscape.io). -+ -+# Contributing distro specific tests -+ -+Distro's tests are implemented via a standardized framework under `tests/test_distro.py` -+ -+For each distribution, tests should be added in the relevant class according to which distribution file(s) exists on it, so, for example, tests should be added under `TestOSRelease` where `/etc/os-release` is available. -+ -+The tests must be self-contained, meaning that the release files for the distribution should be maintained in the repository under `tests/resources/distros/distribution_name+distribution_version`. -+ -+A tests method would like somewhat like this: -+ -+```python -+def test_centos7_os_release(self): -+ desired_outcome = { -+ 'id': 'centos', -+ 'name': 'CentOS Linux', -+ 'pretty_name': 'CentOS Linux 7 (Core)', -+ 'version': '7', -+ 'pretty_version': '7 (Core)', -+ 'best_version': '7', -+ 'like': 'rhel fedora', -+ 'codename': 'Core' -+ } -+ self._test_outcome(desired_outcome) -+``` -+ -+The framework will automatically try to pick up the relevant file according to the method's name (`centos7` meaning the folder should be named `centos7` as well) and compare the `desired_outcome` with the parsed files found under the test dir. -+ -+The exception to the rule is under the `TestDistroRelease` test class which should look somewhat like this: -+ -+```python -+def test_centos5_dist_release(self): -+ desired_outcome = { -+ 'id': 'centos', -+ 'name': 'CentOS', -+ 'pretty_name': 'CentOS 5.11 (Final)', -+ 'version': '5.11', -+ 'pretty_version': '5.11 (Final)', -+ 'best_version': '5.11', -+ 'codename': 'Final', -+ 'major_version': '5', -+ 'minor_version': '11' -+ } -+ self._test_outcome(desired_outcome, 'centos', '5') -+``` -+ -+Where the name of the method is not indicative of the lookup folder but rather tha two last arguments in `_test_outcome`. -+ -+A test case is mandatory under `TestOverall` for a PR to be complete. -\ No newline at end of file -diff --git a/third_party/python/distro/CONTRIBUTORS.md b/third_party/python/distro/CONTRIBUTORS.md -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/CONTRIBUTORS.md -@@ -0,0 +1,13 @@ -+Thanks! -+ -+* https://github.com/andy-maier -+* https://github.com/SethMichaelLarson -+* https://github.com/asottile -+* https://github.com/MartijnBraam -+* https://github.com/funkyfuture -+* https://github.com/adamjstewart -+* https://github.com/xavfernandez -+* https://github.com/xsuchy -+* https://github.com/marcoceppi -+* https://github.com/tgamblin -+* https://github.com/sebix -diff --git a/third_party/python/distro/LICENSE b/third_party/python/distro/LICENSE -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/LICENSE -@@ -0,0 +1,202 @@ -+Apache License -+ Version 2.0, January 2004 -+ http://www.apache.org/licenses/ -+ -+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -+ -+ 1. Definitions. -+ -+ "License" shall mean the terms and conditions for use, reproduction, -+ and distribution as defined by Sections 1 through 9 of this document. -+ -+ "Licensor" shall mean the copyright owner or entity authorized by -+ the copyright owner that is granting the License. -+ -+ "Legal Entity" shall mean the union of the acting entity and all -+ other entities that control, are controlled by, or are under common -+ control with that entity. For the purposes of this definition, -+ "control" means (i) the power, direct or indirect, to cause the -+ direction or management of such entity, whether by contract or -+ otherwise, or (ii) ownership of fifty percent (50%) or more of the -+ outstanding shares, or (iii) beneficial ownership of such entity. -+ -+ "You" (or "Your") shall mean an individual or Legal Entity -+ exercising permissions granted by this License. -+ -+ "Source" form shall mean the preferred form for making modifications, -+ including but not limited to software source code, documentation -+ source, and configuration files. -+ -+ "Object" form shall mean any form resulting from mechanical -+ transformation or translation of a Source form, including but -+ not limited to compiled object code, generated documentation, -+ and conversions to other media types. -+ -+ "Work" shall mean the work of authorship, whether in Source or -+ Object form, made available under the License, as indicated by a -+ copyright notice that is included in or attached to the work -+ (an example is provided in the Appendix below). -+ -+ "Derivative Works" shall mean any work, whether in Source or Object -+ form, that is based on (or derived from) the Work and for which the -+ editorial revisions, annotations, elaborations, or other modifications -+ represent, as a whole, an original work of authorship. For the purposes -+ of this License, Derivative Works shall not include works that remain -+ separable from, or merely link (or bind by name) to the interfaces of, -+ the Work and Derivative Works thereof. -+ -+ "Contribution" shall mean any work of authorship, including -+ the original version of the Work and any modifications or additions -+ to that Work or Derivative Works thereof, that is intentionally -+ submitted to Licensor for inclusion in the Work by the copyright owner -+ or by an individual or Legal Entity authorized to submit on behalf of -+ the copyright owner. For the purposes of this definition, "submitted" -+ means any form of electronic, verbal, or written communication sent -+ to the Licensor or its representatives, including but not limited to -+ communication on electronic mailing lists, source code control systems, -+ and issue tracking systems that are managed by, or on behalf of, the -+ Licensor for the purpose of discussing and improving the Work, but -+ excluding communication that is conspicuously marked or otherwise -+ designated in writing by the copyright owner as "Not a Contribution." -+ -+ "Contributor" shall mean Licensor and any individual or Legal Entity -+ on behalf of whom a Contribution has been received by Licensor and -+ subsequently incorporated within the Work. -+ -+ 2. Grant of Copyright License. Subject to the terms and conditions of -+ this License, each Contributor hereby grants to You a perpetual, -+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable -+ copyright license to reproduce, prepare Derivative Works of, -+ publicly display, publicly perform, sublicense, and distribute the -+ Work and such Derivative Works in Source or Object form. -+ -+ 3. Grant of Patent License. Subject to the terms and conditions of -+ this License, each Contributor hereby grants to You a perpetual, -+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable -+ (except as stated in this section) patent license to make, have made, -+ use, offer to sell, sell, import, and otherwise transfer the Work, -+ where such license applies only to those patent claims licensable -+ by such Contributor that are necessarily infringed by their -+ Contribution(s) alone or by combination of their Contribution(s) -+ with the Work to which such Contribution(s) was submitted. If You -+ institute patent litigation against any entity (including a -+ cross-claim or counterclaim in a lawsuit) alleging that the Work -+ or a Contribution incorporated within the Work constitutes direct -+ or contributory patent infringement, then any patent licenses -+ granted to You under this License for that Work shall terminate -+ as of the date such litigation is filed. -+ -+ 4. Redistribution. You may reproduce and distribute copies of the -+ Work or Derivative Works thereof in any medium, with or without -+ modifications, and in Source or Object form, provided that You -+ meet the following conditions: -+ -+ (a) You must give any other recipients of the Work or -+ Derivative Works a copy of this License; and -+ -+ (b) You must cause any modified files to carry prominent notices -+ stating that You changed the files; and -+ -+ (c) You must retain, in the Source form of any Derivative Works -+ that You distribute, all copyright, patent, trademark, and -+ attribution notices from the Source form of the Work, -+ excluding those notices that do not pertain to any part of -+ the Derivative Works; and -+ -+ (d) If the Work includes a "NOTICE" text file as part of its -+ distribution, then any Derivative Works that You distribute must -+ include a readable copy of the attribution notices contained -+ within such NOTICE file, excluding those notices that do not -+ pertain to any part of the Derivative Works, in at least one -+ of the following places: within a NOTICE text file distributed -+ as part of the Derivative Works; within the Source form or -+ documentation, if provided along with the Derivative Works; or, -+ within a display generated by the Derivative Works, if and -+ wherever such third-party notices normally appear. The contents -+ of the NOTICE file are for informational purposes only and -+ do not modify the License. You may add Your own attribution -+ notices within Derivative Works that You distribute, alongside -+ or as an addendum to the NOTICE text from the Work, provided -+ that such additional attribution notices cannot be construed -+ as modifying the License. -+ -+ You may add Your own copyright statement to Your modifications and -+ may provide additional or different license terms and conditions -+ for use, reproduction, or distribution of Your modifications, or -+ for any such Derivative Works as a whole, provided Your use, -+ reproduction, and distribution of the Work otherwise complies with -+ the conditions stated in this License. -+ -+ 5. Submission of Contributions. Unless You explicitly state otherwise, -+ any Contribution intentionally submitted for inclusion in the Work -+ by You to the Licensor shall be under the terms and conditions of -+ this License, without any additional terms or conditions. -+ Notwithstanding the above, nothing herein shall supersede or modify -+ the terms of any separate license agreement you may have executed -+ with Licensor regarding such Contributions. -+ -+ 6. Trademarks. This License does not grant permission to use the trade -+ names, trademarks, service marks, or product names of the Licensor, -+ except as required for reasonable and customary use in describing the -+ origin of the Work and reproducing the content of the NOTICE file. -+ -+ 7. Disclaimer of Warranty. Unless required by applicable law or -+ agreed to in writing, Licensor provides the Work (and each -+ Contributor provides its Contributions) on an "AS IS" BASIS, -+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -+ implied, including, without limitation, any warranties or conditions -+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A -+ PARTICULAR PURPOSE. You are solely responsible for determining the -+ appropriateness of using or redistributing the Work and assume any -+ risks associated with Your exercise of permissions under this License. -+ -+ 8. Limitation of Liability. In no event and under no legal theory, -+ whether in tort (including negligence), contract, or otherwise, -+ unless required by applicable law (such as deliberate and grossly -+ negligent acts) or agreed to in writing, shall any Contributor be -+ liable to You for damages, including any direct, indirect, special, -+ incidental, or consequential damages of any character arising as a -+ result of this License or out of the use or inability to use the -+ Work (including but not limited to damages for loss of goodwill, -+ work stoppage, computer failure or malfunction, or any and all -+ other commercial damages or losses), even if such Contributor -+ has been advised of the possibility of such damages. -+ -+ 9. Accepting Warranty or Additional Liability. While redistributing -+ the Work or Derivative Works thereof, You may choose to offer, -+ and charge a fee for, acceptance of support, warranty, indemnity, -+ or other liability obligations and/or rights consistent with this -+ License. However, in accepting such obligations, You may act only -+ on Your own behalf and on Your sole responsibility, not on behalf -+ of any other Contributor, and only if You agree to indemnify, -+ defend, and hold each Contributor harmless for any liability -+ incurred by, or claims asserted against, such Contributor by reason -+ of your accepting any such warranty or additional liability. -+ -+ END OF TERMS AND CONDITIONS -+ -+ APPENDIX: How to apply the Apache License to your work. -+ -+ To apply the Apache License to your work, attach the following -+ boilerplate notice, with the fields enclosed by brackets "{}" -+ replaced with your own identifying information. (Don't include -+ the brackets!) The text should be enclosed in the appropriate -+ comment syntax for the file format. We also recommend that a -+ file or class name and description of purpose be included on the -+ same "printed page" as the copyright notice for easier -+ identification within third-party archives. -+ -+ Copyright {yyyy} {name of copyright owner} -+ -+ Licensed under the Apache License, Version 2.0 (the "License"); -+ you may not use this file except in compliance with the License. -+ You may obtain a copy of the License at -+ -+ http://www.apache.org/licenses/LICENSE-2.0 -+ -+ Unless required by applicable law or agreed to in writing, software -+ distributed under the License is distributed on an "AS IS" BASIS, -+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ See the License for the specific language governing permissions and -+ limitations under the License. -+ -diff --git a/third_party/python/distro/MANIFEST.in b/third_party/python/distro/MANIFEST.in -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/MANIFEST.in -@@ -0,0 +1,12 @@ -+include *.md -+include *.py -+include *.txt -+include LICENSE -+include CHANGES -+include Makefile -+ -+graft tests -+ -+include docs/* -+ -+global-exclude *.py[co] -diff --git a/third_party/python/distro/Makefile b/third_party/python/distro/Makefile -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/Makefile -@@ -0,0 +1,145 @@ -+# Copyright 2015,2016 Nir Cohen -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); -+# you may not use this file except in compliance with the License. -+# You may obtain a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, -+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+# See the License for the specific language governing permissions and -+# limitations under the License. -+ -+# Name of this package -+PACKAGENAME = distro -+ -+# Additional options for Sphinx -+SPHINXOPTS = -v -+ -+# Paper format for the Sphinx LaTex/PDF builder. -+# Valid values: a4, letter -+SPHINXPAPER = a4 -+ -+# Sphinx build subtree. -+SPHINXBUILDDIR = build_docs -+ -+# Directory where conf.py is located -+SPHINXCONFDIR = docs -+ -+# Directory where input files for Sphinx are located -+SPHINXSOURCEDIR = . -+ -+# Sphinx build command (Use 'pip install sphinx' to get it) -+SPHINXBUILD = sphinx-build -+ -+# Internal variables for Sphinx -+SPHINXPAPEROPT_a4 = -D latex_paper_size=a4 -+SPHINXPAPEROPT_letter = -D latex_paper_size=letter -+ALLSPHINXOPTS = -d $(SPHINXBUILDDIR)/doctrees -c $(SPHINXCONFDIR) \ -+ $(SPHINXPAPEROPT_$(SPHINXPAPER)) $(SPHINXOPTS) \ -+ $(SPHINXSOURCEDIR) -+ -+.PHONY: help -+help: -+ @echo 'Please use "make <target>" where <target> is one of' -+ @echo " release - build a release and publish it" -+ @echo " dev - prepare a development environment (includes tests)" -+ @echo " instdev - prepare a development environment (no tests)" -+ @echo " install - install into current Python environment" -+ @echo " html - generate docs as standalone HTML files in: $(SPHINXBUILDDIR)/html" -+ @echo " pdf - generate docs as PDF (via LaTeX) for paper format: $(SPHINXPAPER) in: $(SPHINXBUILDDIR)/pdf" -+ @echo " man - generate docs as manual pages in: $(SPHINXBUILDDIR)/man" -+ @echo " docchanges - generate an overview of all changed/added/deprecated items in docs" -+ @echo " doclinkcheck - check all external links in docs for integrity" -+ @echo " doccoverage - run coverage check of the documentation" -+ @echo " clobber - remove any build products" -+ @echo " build - build the package" -+ @echo " test - test from this directory using tox, including test coverage" -+ @echo " publish - upload to PyPI" -+ @echo " clean - remove any temporary build products" -+ @echo " dry-run - perform all action required for a release without actually releasing" -+ -+.PHONY: release -+release: test clean build publish -+ @echo "$@ done." -+ -+.PHONY: test -+test: -+ pip install 'tox>=1.7.2' -+ tox -+ @echo "$@ done." -+ -+.PHONY: clean -+clean: -+ rm -rf dist build $(PACKAGENAME).egg-info -+ @echo "$@ done." -+ -+.PHONY: build -+build: -+ python setup.py sdist bdist_wheel -+ -+.PHONY: publish -+publish: -+ twine upload -r pypi dist/$(PACKAGENAME)-* -+ @echo "$@ done." -+ -+.PHONY: dry-run -+dry-run: test clean build -+ @echo "$@ done." -+ -+.PHONY: dev -+dev: instdev test -+ @echo "$@ done." -+ -+.PHONY: instdev -+instdev: -+ pip install -r dev-requirements.txt -+ python setup.py develop -+ @echo "$@ done." -+ -+.PHONY: install -+install: -+ python setup.py install -+ @echo "$@ done." -+ -+.PHONY: html -+html: -+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(SPHINXBUILDDIR)/html -+ @echo "$@ done; the HTML pages are in $(SPHINXBUILDDIR)/html." -+ -+.PHONY: pdf -+pdf: -+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(SPHINXBUILDDIR)/pdf -+ @echo "Running LaTeX files through pdflatex..." -+ $(MAKE) -C $(SPHINXBUILDDIR)/pdf all-pdf -+ @echo "$@ done; the PDF files are in $(SPHINXBUILDDIR)/pdf." -+ -+.PHONY: man -+man: -+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(SPHINXBUILDDIR)/man -+ @echo "$@ done; the manual pages are in $(SPHINXBUILDDIR)/man." -+ -+.PHONY: docchanges -+docchanges: -+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(SPHINXBUILDDIR)/changes -+ @echo -+ @echo "$@ done; the doc changes overview file is in $(SPHINXBUILDDIR)/changes." -+ -+.PHONY: doclinkcheck -+doclinkcheck: -+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(SPHINXBUILDDIR)/linkcheck -+ @echo -+ @echo "$@ done; look for any errors in the above output " \ -+ "or in $(SPHINXBUILDDIR)/linkcheck/output.txt." -+ -+.PHONY: doccoverage -+doccoverage: -+ $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(SPHINXBUILDDIR)/coverage -+ @echo "$@ done; the doc coverage results are in $(SPHINXBUILDDIR)/coverage/python.txt." -+ -+.PHONY: clobber -+clobber: clean -+ rm -rf $(SPHINXBUILDDIR) -+ @echo "$@ done." -diff --git a/third_party/python/distro/PKG-INFO b/third_party/python/distro/PKG-INFO -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/PKG-INFO -@@ -0,0 +1,168 @@ -+Metadata-Version: 2.1 -+Name: distro -+Version: 1.4.0 -+Summary: Distro - an OS platform information API -+Home-page: https://github.com/nir0s/distro -+Author: Nir Cohen -+Author-email: nir36g@gmail.com -+License: Apache License, Version 2.0 -+Description: Distro - an OS platform information API -+ ======================================= -+ -+ [![Build Status](https://travis-ci.org/nir0s/distro.svg?branch=master)](https://travis-ci.org/nir0s/distro) -+ [![Build status](https://ci.appveyor.com/api/projects/status/e812qjk1gf0f74r5/branch/master?svg=true)](https://ci.appveyor.com/project/nir0s/distro/branch/master) -+ [![PyPI version](http://img.shields.io/pypi/v/distro.svg)](https://pypi.python.org/pypi/distro) -+ [![Supported Python Versions](https://img.shields.io/pypi/pyversions/distro.svg)](https://img.shields.io/pypi/pyversions/distro.svg) -+ [![Requirements Status](https://requires.io/github/nir0s/distro/requirements.svg?branch=master)](https://requires.io/github/nir0s/distro/requirements/?branch=master) -+ [![Code Coverage](https://codecov.io/github/nir0s/distro/coverage.svg?branch=master)](https://codecov.io/github/nir0s/distro?branch=master) -+ [![Code Quality](https://landscape.io/github/nir0s/distro/master/landscape.svg?style=flat)](https://landscape.io/github/nir0s/distro) -+ [![Is Wheel](https://img.shields.io/pypi/wheel/distro.svg?style=flat)](https://pypi.python.org/pypi/distro) -+ [![Latest Github Release](https://readthedocs.org/projects/distro/badge/?version=stable)](http://distro.readthedocs.io/en/latest/) -+ [![Join the chat at https://gitter.im/nir0s/distro](https://badges.gitter.im/nir0s/distro.svg)](https://gitter.im/nir0s/distro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -+ -+ `distro` provides information about the -+ OS distribution it runs on, such as a reliable machine-readable ID, or -+ version information. -+ -+ It is the recommended replacement for Python's original -+ [`platform.linux_distribution`](https://docs.python.org/3.7/library/platform.html#platform.linux_distribution) -+ function (which will be removed in Python 3.8). -+ It also provides much more functionality which isn't necessarily Python bound, -+ like a command-line interface. -+ -+ Distro currently supports Linux and BSD based systems but [Windows and OS X support](https://github.com/nir0s/distro/issues/177) is also planned. -+ -+ For Python 2.6 support, see https://github.com/nir0s/distro/tree/python2.6-support -+ -+ ## Installation -+ -+ Installation of the latest released version from PyPI: -+ -+ ```shell -+ pip install distro -+ ``` -+ -+ Installation of the latest development version: -+ -+ ```shell -+ pip install https://github.com/nir0s/distro/archive/master.tar.gz -+ ``` -+ -+ -+ ## Usage -+ -+ ```bash -+ $ distro -+ Name: Antergos Linux -+ Version: 2015.10 (ISO-Rolling) -+ Codename: ISO-Rolling -+ -+ $ distro -j -+ { -+ "codename": "ISO-Rolling", -+ "id": "antergos", -+ "like": "arch", -+ "version": "16.9", -+ "version_parts": { -+ "build_number": "", -+ "major": "16", -+ "minor": "9" -+ } -+ } -+ -+ -+ $ python -+ >>> import distro -+ >>> distro.linux_distribution(full_distribution_name=False) -+ ('centos', '7.1.1503', 'Core') -+ ``` -+ -+ -+ ## Documentation -+ -+ On top of the aforementioned API, several more functions are available. For a complete description of the -+ API, see the [latest API documentation](http://distro.readthedocs.org/en/latest/). -+ -+ ## Background -+ -+ An alternative implementation became necessary because Python 3.5 deprecated -+ this function, and Python 3.8 will remove it altogether. -+ Its predecessor function `platform.dist` was already deprecated since -+ Python 2.6 and will also be removed in Python 3.8. -+ Still, there are many cases in which access to that information is needed. -+ See [Python issue 1322](https://bugs.python.org/issue1322) for more -+ information. -+ -+ The `distro` package implements a robust and inclusive way of retrieving the -+ information about a distribution based on new standards and old methods, -+ namely from these data sources (from high to low precedence): -+ -+ * The os-release file `/etc/os-release`, if present. -+ * The output of the `lsb_release` command, if available. -+ * The distro release file (`/etc/*(-|_)(release|version)`), if present. -+ * The `uname` command for BSD based distrubtions. -+ -+ -+ ## Python and Distribution Support -+ -+ `distro` is supported and tested on Python 2.7, 3.4+ and PyPy and on -+ any distribution that provides one or more of the data sources -+ covered. -+ -+ This package is tested with test data that mimics the exact behavior of the data sources of [a number of Linux distributions](https://github.com/nir0s/distro/tree/master/tests/resources/distros). -+ -+ -+ ## Testing -+ -+ ```shell -+ git clone git@github.com:nir0s/distro.git -+ cd distro -+ pip install tox -+ tox -+ ``` -+ -+ -+ ## Contributions -+ -+ Pull requests are always welcome to deal with specific distributions or just -+ for general merriment. -+ -+ See [CONTRIBUTIONS](https://github.com/nir0s/distro/blob/master/CONTRIBUTING.md) for contribution info. -+ -+ Reference implementations for supporting additional distributions and file -+ formats can be found here: -+ -+ * https://github.com/saltstack/salt/blob/develop/salt/grains/core.py#L1172 -+ * https://github.com/chef/ohai/blob/master/lib/ohai/plugins/linux/platform.rb -+ * https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/facts/system/distribution.py -+ * https://github.com/puppetlabs/facter/blob/master/lib/src/facts/linux/os_linux.cc -+ -+ ## Package manager distributions -+ -+ * https://src.fedoraproject.org/rpms/python-distro -+ * https://www.archlinux.org/packages/community/any/python-distro/ -+ * https://launchpad.net/ubuntu/+source/python-distro -+ * https://packages.debian.org/sid/python-distro -+ * https://packages.gentoo.org/packages/dev-python/distro -+ * https://pkgs.org/download/python2-distro -+ * https://slackbuilds.org/repository/14.2/python/python-distro/ -+ -+Platform: All -+Classifier: Development Status :: 5 - Production/Stable -+Classifier: Intended Audience :: Developers -+Classifier: Intended Audience :: System Administrators -+Classifier: License :: OSI Approved :: Apache Software License -+Classifier: Operating System :: POSIX :: Linux -+Classifier: Operating System :: POSIX :: BSD -+Classifier: Operating System :: POSIX :: BSD :: FreeBSD -+Classifier: Operating System :: POSIX :: BSD :: NetBSD -+Classifier: Operating System :: POSIX :: BSD :: OpenBSD -+Classifier: Programming Language :: Python :: 2 -+Classifier: Programming Language :: Python :: 2.7 -+Classifier: Programming Language :: Python :: 3 -+Classifier: Programming Language :: Python :: 3.4 -+Classifier: Programming Language :: Python :: 3.5 -+Classifier: Programming Language :: Python :: 3.6 -+Classifier: Topic :: Software Development :: Libraries :: Python Modules -+Classifier: Topic :: System :: Operating System -+Description-Content-Type: text/markdown -diff --git a/third_party/python/distro/README.md b/third_party/python/distro/README.md -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/README.md -@@ -0,0 +1,140 @@ -+Distro - an OS platform information API -+======================================= -+ -+[![Build Status](https://travis-ci.org/nir0s/distro.svg?branch=master)](https://travis-ci.org/nir0s/distro) -+[![Build status](https://ci.appveyor.com/api/projects/status/e812qjk1gf0f74r5/branch/master?svg=true)](https://ci.appveyor.com/project/nir0s/distro/branch/master) -+[![PyPI version](http://img.shields.io/pypi/v/distro.svg)](https://pypi.python.org/pypi/distro) -+[![Supported Python Versions](https://img.shields.io/pypi/pyversions/distro.svg)](https://img.shields.io/pypi/pyversions/distro.svg) -+[![Requirements Status](https://requires.io/github/nir0s/distro/requirements.svg?branch=master)](https://requires.io/github/nir0s/distro/requirements/?branch=master) -+[![Code Coverage](https://codecov.io/github/nir0s/distro/coverage.svg?branch=master)](https://codecov.io/github/nir0s/distro?branch=master) -+[![Code Quality](https://landscape.io/github/nir0s/distro/master/landscape.svg?style=flat)](https://landscape.io/github/nir0s/distro) -+[![Is Wheel](https://img.shields.io/pypi/wheel/distro.svg?style=flat)](https://pypi.python.org/pypi/distro) -+[![Latest Github Release](https://readthedocs.org/projects/distro/badge/?version=stable)](http://distro.readthedocs.io/en/latest/) -+[![Join the chat at https://gitter.im/nir0s/distro](https://badges.gitter.im/nir0s/distro.svg)](https://gitter.im/nir0s/distro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -+ -+`distro` provides information about the -+OS distribution it runs on, such as a reliable machine-readable ID, or -+version information. -+ -+It is the recommended replacement for Python's original -+[`platform.linux_distribution`](https://docs.python.org/3.7/library/platform.html#platform.linux_distribution) -+function (which will be removed in Python 3.8). -+It also provides much more functionality which isn't necessarily Python bound, -+like a command-line interface. -+ -+Distro currently supports Linux and BSD based systems but [Windows and OS X support](https://github.com/nir0s/distro/issues/177) is also planned. -+ -+For Python 2.6 support, see https://github.com/nir0s/distro/tree/python2.6-support -+ -+## Installation -+ -+Installation of the latest released version from PyPI: -+ -+```shell -+pip install distro -+``` -+ -+Installation of the latest development version: -+ -+```shell -+pip install https://github.com/nir0s/distro/archive/master.tar.gz -+``` -+ -+ -+## Usage -+ -+```bash -+$ distro -+Name: Antergos Linux -+Version: 2015.10 (ISO-Rolling) -+Codename: ISO-Rolling -+ -+$ distro -j -+{ -+ "codename": "ISO-Rolling", -+ "id": "antergos", -+ "like": "arch", -+ "version": "16.9", -+ "version_parts": { -+ "build_number": "", -+ "major": "16", -+ "minor": "9" -+ } -+} -+ -+ -+$ python -+>>> import distro -+>>> distro.linux_distribution(full_distribution_name=False) -+('centos', '7.1.1503', 'Core') -+``` -+ -+ -+## Documentation -+ -+On top of the aforementioned API, several more functions are available. For a complete description of the -+API, see the [latest API documentation](http://distro.readthedocs.org/en/latest/). -+ -+## Background -+ -+An alternative implementation became necessary because Python 3.5 deprecated -+this function, and Python 3.8 will remove it altogether. -+Its predecessor function `platform.dist` was already deprecated since -+Python 2.6 and will also be removed in Python 3.8. -+Still, there are many cases in which access to that information is needed. -+See [Python issue 1322](https://bugs.python.org/issue1322) for more -+information. -+ -+The `distro` package implements a robust and inclusive way of retrieving the -+information about a distribution based on new standards and old methods, -+namely from these data sources (from high to low precedence): -+ -+* The os-release file `/etc/os-release`, if present. -+* The output of the `lsb_release` command, if available. -+* The distro release file (`/etc/*(-|_)(release|version)`), if present. -+* The `uname` command for BSD based distrubtions. -+ -+ -+## Python and Distribution Support -+ -+`distro` is supported and tested on Python 2.7, 3.4+ and PyPy and on -+any distribution that provides one or more of the data sources -+covered. -+ -+This package is tested with test data that mimics the exact behavior of the data sources of [a number of Linux distributions](https://github.com/nir0s/distro/tree/master/tests/resources/distros). -+ -+ -+## Testing -+ -+```shell -+git clone git@github.com:nir0s/distro.git -+cd distro -+pip install tox -+tox -+``` -+ -+ -+## Contributions -+ -+Pull requests are always welcome to deal with specific distributions or just -+for general merriment. -+ -+See [CONTRIBUTIONS](https://github.com/nir0s/distro/blob/master/CONTRIBUTING.md) for contribution info. -+ -+Reference implementations for supporting additional distributions and file -+formats can be found here: -+ -+* https://github.com/saltstack/salt/blob/develop/salt/grains/core.py#L1172 -+* https://github.com/chef/ohai/blob/master/lib/ohai/plugins/linux/platform.rb -+* https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/facts/system/distribution.py -+* https://github.com/puppetlabs/facter/blob/master/lib/src/facts/linux/os_linux.cc -+ -+## Package manager distributions -+ -+* https://src.fedoraproject.org/rpms/python-distro -+* https://www.archlinux.org/packages/community/any/python-distro/ -+* https://launchpad.net/ubuntu/+source/python-distro -+* https://packages.debian.org/sid/python-distro -+* https://packages.gentoo.org/packages/dev-python/distro -+* https://pkgs.org/download/python2-distro -+* https://slackbuilds.org/repository/14.2/python/python-distro/ -diff --git a/third_party/python/distro/dev-requirements.txt b/third_party/python/distro/dev-requirements.txt -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/dev-requirements.txt -@@ -0,0 +1,3 @@ -+pytest -+pytest-cov -+sphinx>=1.1 -\ No newline at end of file -diff --git a/third_party/python/distro/distro.py b/third_party/python/distro/distro.py -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/distro.py -@@ -0,0 +1,1216 @@ -+# Copyright 2015,2016,2017 Nir Cohen -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); -+# you may not use this file except in compliance with the License. -+# You may obtain a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, -+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+# See the License for the specific language governing permissions and -+# limitations under the License. -+ -+""" -+The ``distro`` package (``distro`` stands for Linux Distribution) provides -+information about the Linux distribution it runs on, such as a reliable -+machine-readable distro ID, or version information. -+ -+It is the recommended replacement for Python's original -+:py:func:`platform.linux_distribution` function, but it provides much more -+functionality. An alternative implementation became necessary because Python -+3.5 deprecated this function, and Python 3.8 will remove it altogether. -+Its predecessor function :py:func:`platform.dist` was already -+deprecated since Python 2.6 and will also be removed in Python 3.8. -+Still, there are many cases in which access to OS distribution information -+is needed. See `Python issue 1322 <https://bugs.python.org/issue1322>`_ for -+more information. -+""" -+ -+import os -+import re -+import sys -+import json -+import shlex -+import logging -+import argparse -+import subprocess -+ -+ -+_UNIXCONFDIR = os.environ.get('UNIXCONFDIR', '/etc') -+_OS_RELEASE_BASENAME = 'os-release' -+ -+#: Translation table for normalizing the "ID" attribute defined in os-release -+#: files, for use by the :func:`distro.id` method. -+#: -+#: * Key: Value as defined in the os-release file, translated to lower case, -+#: with blanks translated to underscores. -+#: -+#: * Value: Normalized value. -+NORMALIZED_OS_ID = { -+ 'ol': 'oracle', # Oracle Enterprise Linux -+} -+ -+#: Translation table for normalizing the "Distributor ID" attribute returned by -+#: the lsb_release command, for use by the :func:`distro.id` method. -+#: -+#: * Key: Value as returned by the lsb_release command, translated to lower -+#: case, with blanks translated to underscores. -+#: -+#: * Value: Normalized value. -+NORMALIZED_LSB_ID = { -+ 'enterpriseenterprise': 'oracle', # Oracle Enterprise Linux -+ 'redhatenterpriseworkstation': 'rhel', # RHEL 6, 7 Workstation -+ 'redhatenterpriseserver': 'rhel', # RHEL 6, 7 Server -+} -+ -+#: Translation table for normalizing the distro ID derived from the file name -+#: of distro release files, for use by the :func:`distro.id` method. -+#: -+#: * Key: Value as derived from the file name of a distro release file, -+#: translated to lower case, with blanks translated to underscores. -+#: -+#: * Value: Normalized value. -+NORMALIZED_DISTRO_ID = { -+ 'redhat': 'rhel', # RHEL 6.x, 7.x -+} -+ -+# Pattern for content of distro release file (reversed) -+_DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile( -+ r'(?:[^)]*\)(.*)\()? *(?:STL )?([\d.+\-a-z]*\d) *(?:esaeler *)?(.+)') -+ -+# Pattern for base file name of distro release file -+_DISTRO_RELEASE_BASENAME_PATTERN = re.compile( -+ r'(\w+)[-_](release|version)$') -+ -+# Base file names to be ignored when searching for distro release file -+_DISTRO_RELEASE_IGNORE_BASENAMES = ( -+ 'debian_version', -+ 'lsb-release', -+ 'oem-release', -+ _OS_RELEASE_BASENAME, -+ 'system-release' -+) -+ -+ -+def linux_distribution(full_distribution_name=True): -+ """ -+ Return information about the current OS distribution as a tuple -+ ``(id_name, version, codename)`` with items as follows: -+ -+ * ``id_name``: If *full_distribution_name* is false, the result of -+ :func:`distro.id`. Otherwise, the result of :func:`distro.name`. -+ -+ * ``version``: The result of :func:`distro.version`. -+ -+ * ``codename``: The result of :func:`distro.codename`. -+ -+ The interface of this function is compatible with the original -+ :py:func:`platform.linux_distribution` function, supporting a subset of -+ its parameters. -+ -+ The data it returns may not exactly be the same, because it uses more data -+ sources than the original function, and that may lead to different data if -+ the OS distribution is not consistent across multiple data sources it -+ provides (there are indeed such distributions ...). -+ -+ Another reason for differences is the fact that the :func:`distro.id` -+ method normalizes the distro ID string to a reliable machine-readable value -+ for a number of popular OS distributions. -+ """ -+ return _distro.linux_distribution(full_distribution_name) -+ -+ -+def id(): -+ """ -+ Return the distro ID of the current distribution, as a -+ machine-readable string. -+ -+ For a number of OS distributions, the returned distro ID value is -+ *reliable*, in the sense that it is documented and that it does not change -+ across releases of the distribution. -+ -+ This package maintains the following reliable distro ID values: -+ -+ ============== ========================================= -+ Distro ID Distribution -+ ============== ========================================= -+ "ubuntu" Ubuntu -+ "debian" Debian -+ "rhel" RedHat Enterprise Linux -+ "centos" CentOS -+ "fedora" Fedora -+ "sles" SUSE Linux Enterprise Server -+ "opensuse" openSUSE -+ "amazon" Amazon Linux -+ "arch" Arch Linux -+ "cloudlinux" CloudLinux OS -+ "exherbo" Exherbo Linux -+ "gentoo" GenToo Linux -+ "ibm_powerkvm" IBM PowerKVM -+ "kvmibm" KVM for IBM z Systems -+ "linuxmint" Linux Mint -+ "mageia" Mageia -+ "mandriva" Mandriva Linux -+ "parallels" Parallels -+ "pidora" Pidora -+ "raspbian" Raspbian -+ "oracle" Oracle Linux (and Oracle Enterprise Linux) -+ "scientific" Scientific Linux -+ "slackware" Slackware -+ "xenserver" XenServer -+ "openbsd" OpenBSD -+ "netbsd" NetBSD -+ "freebsd" FreeBSD -+ ============== ========================================= -+ -+ If you have a need to get distros for reliable IDs added into this set, -+ or if you find that the :func:`distro.id` function returns a different -+ distro ID for one of the listed distros, please create an issue in the -+ `distro issue tracker`_. -+ -+ **Lookup hierarchy and transformations:** -+ -+ First, the ID is obtained from the following sources, in the specified -+ order. The first available and non-empty value is used: -+ -+ * the value of the "ID" attribute of the os-release file, -+ -+ * the value of the "Distributor ID" attribute returned by the lsb_release -+ command, -+ -+ * the first part of the file name of the distro release file, -+ -+ The so determined ID value then passes the following transformations, -+ before it is returned by this method: -+ -+ * it is translated to lower case, -+ -+ * blanks (which should not be there anyway) are translated to underscores, -+ -+ * a normalization of the ID is performed, based upon -+ `normalization tables`_. The purpose of this normalization is to ensure -+ that the ID is as reliable as possible, even across incompatible changes -+ in the OS distributions. A common reason for an incompatible change is -+ the addition of an os-release file, or the addition of the lsb_release -+ command, with ID values that differ from what was previously determined -+ from the distro release file name. -+ """ -+ return _distro.id() -+ -+ -+def name(pretty=False): -+ """ -+ Return the name of the current OS distribution, as a human-readable -+ string. -+ -+ If *pretty* is false, the name is returned without version or codename. -+ (e.g. "CentOS Linux") -+ -+ If *pretty* is true, the version and codename are appended. -+ (e.g. "CentOS Linux 7.1.1503 (Core)") -+ -+ **Lookup hierarchy:** -+ -+ The name is obtained from the following sources, in the specified order. -+ The first available and non-empty value is used: -+ -+ * If *pretty* is false: -+ -+ - the value of the "NAME" attribute of the os-release file, -+ -+ - the value of the "Distributor ID" attribute returned by the lsb_release -+ command, -+ -+ - the value of the "<name>" field of the distro release file. -+ -+ * If *pretty* is true: -+ -+ - the value of the "PRETTY_NAME" attribute of the os-release file, -+ -+ - the value of the "Description" attribute returned by the lsb_release -+ command, -+ -+ - the value of the "<name>" field of the distro release file, appended -+ with the value of the pretty version ("<version_id>" and "<codename>" -+ fields) of the distro release file, if available. -+ """ -+ return _distro.name(pretty) -+ -+ -+def version(pretty=False, best=False): -+ """ -+ Return the version of the current OS distribution, as a human-readable -+ string. -+ -+ If *pretty* is false, the version is returned without codename (e.g. -+ "7.0"). -+ -+ If *pretty* is true, the codename in parenthesis is appended, if the -+ codename is non-empty (e.g. "7.0 (Maipo)"). -+ -+ Some distributions provide version numbers with different precisions in -+ the different sources of distribution information. Examining the different -+ sources in a fixed priority order does not always yield the most precise -+ version (e.g. for Debian 8.2, or CentOS 7.1). -+ -+ The *best* parameter can be used to control the approach for the returned -+ version: -+ -+ If *best* is false, the first non-empty version number in priority order of -+ the examined sources is returned. -+ -+ If *best* is true, the most precise version number out of all examined -+ sources is returned. -+ -+ **Lookup hierarchy:** -+ -+ In all cases, the version number is obtained from the following sources. -+ If *best* is false, this order represents the priority order: -+ -+ * the value of the "VERSION_ID" attribute of the os-release file, -+ * the value of the "Release" attribute returned by the lsb_release -+ command, -+ * the version number parsed from the "<version_id>" field of the first line -+ of the distro release file, -+ * the version number parsed from the "PRETTY_NAME" attribute of the -+ os-release file, if it follows the format of the distro release files. -+ * the version number parsed from the "Description" attribute returned by -+ the lsb_release command, if it follows the format of the distro release -+ files. -+ """ -+ return _distro.version(pretty, best) -+ -+ -+def version_parts(best=False): -+ """ -+ Return the version of the current OS distribution as a tuple -+ ``(major, minor, build_number)`` with items as follows: -+ -+ * ``major``: The result of :func:`distro.major_version`. -+ -+ * ``minor``: The result of :func:`distro.minor_version`. -+ -+ * ``build_number``: The result of :func:`distro.build_number`. -+ -+ For a description of the *best* parameter, see the :func:`distro.version` -+ method. -+ """ -+ return _distro.version_parts(best) -+ -+ -+def major_version(best=False): -+ """ -+ Return the major version of the current OS distribution, as a string, -+ if provided. -+ Otherwise, the empty string is returned. The major version is the first -+ part of the dot-separated version string. -+ -+ For a description of the *best* parameter, see the :func:`distro.version` -+ method. -+ """ -+ return _distro.major_version(best) -+ -+ -+def minor_version(best=False): -+ """ -+ Return the minor version of the current OS distribution, as a string, -+ if provided. -+ Otherwise, the empty string is returned. The minor version is the second -+ part of the dot-separated version string. -+ -+ For a description of the *best* parameter, see the :func:`distro.version` -+ method. -+ """ -+ return _distro.minor_version(best) -+ -+ -+def build_number(best=False): -+ """ -+ Return the build number of the current OS distribution, as a string, -+ if provided. -+ Otherwise, the empty string is returned. The build number is the third part -+ of the dot-separated version string. -+ -+ For a description of the *best* parameter, see the :func:`distro.version` -+ method. -+ """ -+ return _distro.build_number(best) -+ -+ -+def like(): -+ """ -+ Return a space-separated list of distro IDs of distributions that are -+ closely related to the current OS distribution in regards to packaging -+ and programming interfaces, for example distributions the current -+ distribution is a derivative from. -+ -+ **Lookup hierarchy:** -+ -+ This information item is only provided by the os-release file. -+ For details, see the description of the "ID_LIKE" attribute in the -+ `os-release man page -+ <http://www.freedesktop.org/software/systemd/man/os-release.html>`_. -+ """ -+ return _distro.like() -+ -+ -+def codename(): -+ """ -+ Return the codename for the release of the current OS distribution, -+ as a string. -+ -+ If the distribution does not have a codename, an empty string is returned. -+ -+ Note that the returned codename is not always really a codename. For -+ example, openSUSE returns "x86_64". This function does not handle such -+ cases in any special way and just returns the string it finds, if any. -+ -+ **Lookup hierarchy:** -+ -+ * the codename within the "VERSION" attribute of the os-release file, if -+ provided, -+ -+ * the value of the "Codename" attribute returned by the lsb_release -+ command, -+ -+ * the value of the "<codename>" field of the distro release file. -+ """ -+ return _distro.codename() -+ -+ -+def info(pretty=False, best=False): -+ """ -+ Return certain machine-readable information items about the current OS -+ distribution in a dictionary, as shown in the following example: -+ -+ .. sourcecode:: python -+ -+ { -+ 'id': 'rhel', -+ 'version': '7.0', -+ 'version_parts': { -+ 'major': '7', -+ 'minor': '0', -+ 'build_number': '' -+ }, -+ 'like': 'fedora', -+ 'codename': 'Maipo' -+ } -+ -+ The dictionary structure and keys are always the same, regardless of which -+ information items are available in the underlying data sources. The values -+ for the various keys are as follows: -+ -+ * ``id``: The result of :func:`distro.id`. -+ -+ * ``version``: The result of :func:`distro.version`. -+ -+ * ``version_parts -> major``: The result of :func:`distro.major_version`. -+ -+ * ``version_parts -> minor``: The result of :func:`distro.minor_version`. -+ -+ * ``version_parts -> build_number``: The result of -+ :func:`distro.build_number`. -+ -+ * ``like``: The result of :func:`distro.like`. -+ -+ * ``codename``: The result of :func:`distro.codename`. -+ -+ For a description of the *pretty* and *best* parameters, see the -+ :func:`distro.version` method. -+ """ -+ return _distro.info(pretty, best) -+ -+ -+def os_release_info(): -+ """ -+ Return a dictionary containing key-value pairs for the information items -+ from the os-release file data source of the current OS distribution. -+ -+ See `os-release file`_ for details about these information items. -+ """ -+ return _distro.os_release_info() -+ -+ -+def lsb_release_info(): -+ """ -+ Return a dictionary containing key-value pairs for the information items -+ from the lsb_release command data source of the current OS distribution. -+ -+ See `lsb_release command output`_ for details about these information -+ items. -+ """ -+ return _distro.lsb_release_info() -+ -+ -+def distro_release_info(): -+ """ -+ Return a dictionary containing key-value pairs for the information items -+ from the distro release file data source of the current OS distribution. -+ -+ See `distro release file`_ for details about these information items. -+ """ -+ return _distro.distro_release_info() -+ -+ -+def uname_info(): -+ """ -+ Return a dictionary containing key-value pairs for the information items -+ from the distro release file data source of the current OS distribution. -+ """ -+ return _distro.uname_info() -+ -+ -+def os_release_attr(attribute): -+ """ -+ Return a single named information item from the os-release file data source -+ of the current OS distribution. -+ -+ Parameters: -+ -+ * ``attribute`` (string): Key of the information item. -+ -+ Returns: -+ -+ * (string): Value of the information item, if the item exists. -+ The empty string, if the item does not exist. -+ -+ See `os-release file`_ for details about these information items. -+ """ -+ return _distro.os_release_attr(attribute) -+ -+ -+def lsb_release_attr(attribute): -+ """ -+ Return a single named information item from the lsb_release command output -+ data source of the current OS distribution. -+ -+ Parameters: -+ -+ * ``attribute`` (string): Key of the information item. -+ -+ Returns: -+ -+ * (string): Value of the information item, if the item exists. -+ The empty string, if the item does not exist. -+ -+ See `lsb_release command output`_ for details about these information -+ items. -+ """ -+ return _distro.lsb_release_attr(attribute) -+ -+ -+def distro_release_attr(attribute): -+ """ -+ Return a single named information item from the distro release file -+ data source of the current OS distribution. -+ -+ Parameters: -+ -+ * ``attribute`` (string): Key of the information item. -+ -+ Returns: -+ -+ * (string): Value of the information item, if the item exists. -+ The empty string, if the item does not exist. -+ -+ See `distro release file`_ for details about these information items. -+ """ -+ return _distro.distro_release_attr(attribute) -+ -+ -+def uname_attr(attribute): -+ """ -+ Return a single named information item from the distro release file -+ data source of the current OS distribution. -+ -+ Parameters: -+ -+ * ``attribute`` (string): Key of the information item. -+ -+ Returns: -+ -+ * (string): Value of the information item, if the item exists. -+ The empty string, if the item does not exist. -+ """ -+ return _distro.uname_attr(attribute) -+ -+ -+class cached_property(object): -+ """A version of @property which caches the value. On access, it calls the -+ underlying function and sets the value in `__dict__` so future accesses -+ will not re-call the property. -+ """ -+ def __init__(self, f): -+ self._fname = f.__name__ -+ self._f = f -+ -+ def __get__(self, obj, owner): -+ assert obj is not None, 'call {} on an instance'.format(self._fname) -+ ret = obj.__dict__[self._fname] = self._f(obj) -+ return ret -+ -+ -+class LinuxDistribution(object): -+ """ -+ Provides information about a OS distribution. -+ -+ This package creates a private module-global instance of this class with -+ default initialization arguments, that is used by the -+ `consolidated accessor functions`_ and `single source accessor functions`_. -+ By using default initialization arguments, that module-global instance -+ returns data about the current OS distribution (i.e. the distro this -+ package runs on). -+ -+ Normally, it is not necessary to create additional instances of this class. -+ However, in situations where control is needed over the exact data sources -+ that are used, instances of this class can be created with a specific -+ distro release file, or a specific os-release file, or without invoking the -+ lsb_release command. -+ """ -+ -+ def __init__(self, -+ include_lsb=True, -+ os_release_file='', -+ distro_release_file='', -+ include_uname=True): -+ """ -+ The initialization method of this class gathers information from the -+ available data sources, and stores that in private instance attributes. -+ Subsequent access to the information items uses these private instance -+ attributes, so that the data sources are read only once. -+ -+ Parameters: -+ -+ * ``include_lsb`` (bool): Controls whether the -+ `lsb_release command output`_ is included as a data source. -+ -+ If the lsb_release command is not available in the program execution -+ path, the data source for the lsb_release command will be empty. -+ -+ * ``os_release_file`` (string): The path name of the -+ `os-release file`_ that is to be used as a data source. -+ -+ An empty string (the default) will cause the default path name to -+ be used (see `os-release file`_ for details). -+ -+ If the specified or defaulted os-release file does not exist, the -+ data source for the os-release file will be empty. -+ -+ * ``distro_release_file`` (string): The path name of the -+ `distro release file`_ that is to be used as a data source. -+ -+ An empty string (the default) will cause a default search algorithm -+ to be used (see `distro release file`_ for details). -+ -+ If the specified distro release file does not exist, or if no default -+ distro release file can be found, the data source for the distro -+ release file will be empty. -+ -+ * ``include_name`` (bool): Controls whether uname command output is -+ included as a data source. If the uname command is not available in -+ the program execution path the data source for the uname command will -+ be empty. -+ -+ Public instance attributes: -+ -+ * ``os_release_file`` (string): The path name of the -+ `os-release file`_ that is actually used as a data source. The -+ empty string if no distro release file is used as a data source. -+ -+ * ``distro_release_file`` (string): The path name of the -+ `distro release file`_ that is actually used as a data source. The -+ empty string if no distro release file is used as a data source. -+ -+ * ``include_lsb`` (bool): The result of the ``include_lsb`` parameter. -+ This controls whether the lsb information will be loaded. -+ -+ * ``include_uname`` (bool): The result of the ``include_uname`` -+ parameter. This controls whether the uname information will -+ be loaded. -+ -+ Raises: -+ -+ * :py:exc:`IOError`: Some I/O issue with an os-release file or distro -+ release file. -+ -+ * :py:exc:`subprocess.CalledProcessError`: The lsb_release command had -+ some issue (other than not being available in the program execution -+ path). -+ -+ * :py:exc:`UnicodeError`: A data source has unexpected characters or -+ uses an unexpected encoding. -+ """ -+ self.os_release_file = os_release_file or \ -+ os.path.join(_UNIXCONFDIR, _OS_RELEASE_BASENAME) -+ self.distro_release_file = distro_release_file or '' # updated later -+ self.include_lsb = include_lsb -+ self.include_uname = include_uname -+ -+ def __repr__(self): -+ """Return repr of all info -+ """ -+ return \ -+ "LinuxDistribution(" \ -+ "os_release_file={self.os_release_file!r}, " \ -+ "distro_release_file={self.distro_release_file!r}, " \ -+ "include_lsb={self.include_lsb!r}, " \ -+ "include_uname={self.include_uname!r}, " \ -+ "_os_release_info={self._os_release_info!r}, " \ -+ "_lsb_release_info={self._lsb_release_info!r}, " \ -+ "_distro_release_info={self._distro_release_info!r}, " \ -+ "_uname_info={self._uname_info!r})".format( -+ self=self) -+ -+ def linux_distribution(self, full_distribution_name=True): -+ """ -+ Return information about the OS distribution that is compatible -+ with Python's :func:`platform.linux_distribution`, supporting a subset -+ of its parameters. -+ -+ For details, see :func:`distro.linux_distribution`. -+ """ -+ return ( -+ self.name() if full_distribution_name else self.id(), -+ self.version(), -+ self.codename() -+ ) -+ -+ def id(self): -+ """Return the distro ID of the OS distribution, as a string. -+ -+ For details, see :func:`distro.id`. -+ """ -+ def normalize(distro_id, table): -+ distro_id = distro_id.lower().replace(' ', '_') -+ return table.get(distro_id, distro_id) -+ -+ distro_id = self.os_release_attr('id') -+ if distro_id: -+ return normalize(distro_id, NORMALIZED_OS_ID) -+ -+ distro_id = self.lsb_release_attr('distributor_id') -+ if distro_id: -+ return normalize(distro_id, NORMALIZED_LSB_ID) -+ -+ distro_id = self.distro_release_attr('id') -+ if distro_id: -+ return normalize(distro_id, NORMALIZED_DISTRO_ID) -+ -+ distro_id = self.uname_attr('id') -+ if distro_id: -+ return normalize(distro_id, NORMALIZED_DISTRO_ID) -+ -+ return '' -+ -+ def name(self, pretty=False): -+ """ -+ Return the name of the OS distribution, as a string. -+ -+ For details, see :func:`distro.name`. -+ """ -+ name = self.os_release_attr('name') \ -+ or self.lsb_release_attr('distributor_id') \ -+ or self.distro_release_attr('name') \ -+ or self.uname_attr('name') -+ if pretty: -+ name = self.os_release_attr('pretty_name') \ -+ or self.lsb_release_attr('description') -+ if not name: -+ name = self.distro_release_attr('name') \ -+ or self.uname_attr('name') -+ version = self.version(pretty=True) -+ if version: -+ name = name + ' ' + version -+ return name or '' -+ -+ def version(self, pretty=False, best=False): -+ """ -+ Return the version of the OS distribution, as a string. -+ -+ For details, see :func:`distro.version`. -+ """ -+ versions = [ -+ self.os_release_attr('version_id'), -+ self.lsb_release_attr('release'), -+ self.distro_release_attr('version_id'), -+ self._parse_distro_release_content( -+ self.os_release_attr('pretty_name')).get('version_id', ''), -+ self._parse_distro_release_content( -+ self.lsb_release_attr('description')).get('version_id', ''), -+ self.uname_attr('release') -+ ] -+ version = '' -+ if best: -+ # This algorithm uses the last version in priority order that has -+ # the best precision. If the versions are not in conflict, that -+ # does not matter; otherwise, using the last one instead of the -+ # first one might be considered a surprise. -+ for v in versions: -+ if v.count(".") > version.count(".") or version == '': -+ version = v -+ else: -+ for v in versions: -+ if v != '': -+ version = v -+ break -+ if pretty and version and self.codename(): -+ version = u'{0} ({1})'.format(version, self.codename()) -+ return version -+ -+ def version_parts(self, best=False): -+ """ -+ Return the version of the OS distribution, as a tuple of version -+ numbers. -+ -+ For details, see :func:`distro.version_parts`. -+ """ -+ version_str = self.version(best=best) -+ if version_str: -+ version_regex = re.compile(r'(\d+)\.?(\d+)?\.?(\d+)?') -+ matches = version_regex.match(version_str) -+ if matches: -+ major, minor, build_number = matches.groups() -+ return major, minor or '', build_number or '' -+ return '', '', '' -+ -+ def major_version(self, best=False): -+ """ -+ Return the major version number of the current distribution. -+ -+ For details, see :func:`distro.major_version`. -+ """ -+ return self.version_parts(best)[0] -+ -+ def minor_version(self, best=False): -+ """ -+ Return the minor version number of the current distribution. -+ -+ For details, see :func:`distro.minor_version`. -+ """ -+ return self.version_parts(best)[1] -+ -+ def build_number(self, best=False): -+ """ -+ Return the build number of the current distribution. -+ -+ For details, see :func:`distro.build_number`. -+ """ -+ return self.version_parts(best)[2] -+ -+ def like(self): -+ """ -+ Return the IDs of distributions that are like the OS distribution. -+ -+ For details, see :func:`distro.like`. -+ """ -+ return self.os_release_attr('id_like') or '' -+ -+ def codename(self): -+ """ -+ Return the codename of the OS distribution. -+ -+ For details, see :func:`distro.codename`. -+ """ -+ try: -+ # Handle os_release specially since distros might purposefully set -+ # this to empty string to have no codename -+ return self._os_release_info['codename'] -+ except KeyError: -+ return self.lsb_release_attr('codename') \ -+ or self.distro_release_attr('codename') \ -+ or '' -+ -+ def info(self, pretty=False, best=False): -+ """ -+ Return certain machine-readable information about the OS -+ distribution. -+ -+ For details, see :func:`distro.info`. -+ """ -+ return dict( -+ id=self.id(), -+ version=self.version(pretty, best), -+ version_parts=dict( -+ major=self.major_version(best), -+ minor=self.minor_version(best), -+ build_number=self.build_number(best) -+ ), -+ like=self.like(), -+ codename=self.codename(), -+ ) -+ -+ def os_release_info(self): -+ """ -+ Return a dictionary containing key-value pairs for the information -+ items from the os-release file data source of the OS distribution. -+ -+ For details, see :func:`distro.os_release_info`. -+ """ -+ return self._os_release_info -+ -+ def lsb_release_info(self): -+ """ -+ Return a dictionary containing key-value pairs for the information -+ items from the lsb_release command data source of the OS -+ distribution. -+ -+ For details, see :func:`distro.lsb_release_info`. -+ """ -+ return self._lsb_release_info -+ -+ def distro_release_info(self): -+ """ -+ Return a dictionary containing key-value pairs for the information -+ items from the distro release file data source of the OS -+ distribution. -+ -+ For details, see :func:`distro.distro_release_info`. -+ """ -+ return self._distro_release_info -+ -+ def uname_info(self): -+ """ -+ Return a dictionary containing key-value pairs for the information -+ items from the uname command data source of the OS distribution. -+ -+ For details, see :func:`distro.uname_info`. -+ """ -+ return self._uname_info -+ -+ def os_release_attr(self, attribute): -+ """ -+ Return a single named information item from the os-release file data -+ source of the OS distribution. -+ -+ For details, see :func:`distro.os_release_attr`. -+ """ -+ return self._os_release_info.get(attribute, '') -+ -+ def lsb_release_attr(self, attribute): -+ """ -+ Return a single named information item from the lsb_release command -+ output data source of the OS distribution. -+ -+ For details, see :func:`distro.lsb_release_attr`. -+ """ -+ return self._lsb_release_info.get(attribute, '') -+ -+ def distro_release_attr(self, attribute): -+ """ -+ Return a single named information item from the distro release file -+ data source of the OS distribution. -+ -+ For details, see :func:`distro.distro_release_attr`. -+ """ -+ return self._distro_release_info.get(attribute, '') -+ -+ def uname_attr(self, attribute): -+ """ -+ Return a single named information item from the uname command -+ output data source of the OS distribution. -+ -+ For details, see :func:`distro.uname_release_attr`. -+ """ -+ return self._uname_info.get(attribute, '') -+ -+ @cached_property -+ def _os_release_info(self): -+ """ -+ Get the information items from the specified os-release file. -+ -+ Returns: -+ A dictionary containing all information items. -+ """ -+ if os.path.isfile(self.os_release_file): -+ with open(self.os_release_file) as release_file: -+ return self._parse_os_release_content(release_file) -+ return {} -+ -+ @staticmethod -+ def _parse_os_release_content(lines): -+ """ -+ Parse the lines of an os-release file. -+ -+ Parameters: -+ -+ * lines: Iterable through the lines in the os-release file. -+ Each line must be a unicode string or a UTF-8 encoded byte -+ string. -+ -+ Returns: -+ A dictionary containing all information items. -+ """ -+ props = {} -+ lexer = shlex.shlex(lines, posix=True) -+ lexer.whitespace_split = True -+ -+ # The shlex module defines its `wordchars` variable using literals, -+ # making it dependent on the encoding of the Python source file. -+ # In Python 2.6 and 2.7, the shlex source file is encoded in -+ # 'iso-8859-1', and the `wordchars` variable is defined as a byte -+ # string. This causes a UnicodeDecodeError to be raised when the -+ # parsed content is a unicode object. The following fix resolves that -+ # (... but it should be fixed in shlex...): -+ if sys.version_info[0] == 2 and isinstance(lexer.wordchars, bytes): -+ lexer.wordchars = lexer.wordchars.decode('iso-8859-1') -+ -+ tokens = list(lexer) -+ for token in tokens: -+ # At this point, all shell-like parsing has been done (i.e. -+ # comments processed, quotes and backslash escape sequences -+ # processed, multi-line values assembled, trailing newlines -+ # stripped, etc.), so the tokens are now either: -+ # * variable assignments: var=value -+ # * commands or their arguments (not allowed in os-release) -+ if '=' in token: -+ k, v = token.split('=', 1) -+ if isinstance(v, bytes): -+ v = v.decode('utf-8') -+ props[k.lower()] = v -+ else: -+ # Ignore any tokens that are not variable assignments -+ pass -+ -+ if 'version_codename' in props: -+ # os-release added a version_codename field. Use that in -+ # preference to anything else Note that some distros purposefully -+ # do not have code names. They should be setting -+ # version_codename="" -+ props['codename'] = props['version_codename'] -+ elif 'ubuntu_codename' in props: -+ # Same as above but a non-standard field name used on older Ubuntus -+ props['codename'] = props['ubuntu_codename'] -+ elif 'version' in props: -+ # If there is no version_codename, parse it from the version -+ codename = re.search(r'(\(\D+\))|,(\s+)?\D+', props['version']) -+ if codename: -+ codename = codename.group() -+ codename = codename.strip('()') -+ codename = codename.strip(',') -+ codename = codename.strip() -+ # codename appears within paranthese. -+ props['codename'] = codename -+ -+ return props -+ -+ @cached_property -+ def _lsb_release_info(self): -+ """ -+ Get the information items from the lsb_release command output. -+ -+ Returns: -+ A dictionary containing all information items. -+ """ -+ if not self.include_lsb: -+ return {} -+ with open(os.devnull, 'w') as devnull: -+ try: -+ cmd = ('lsb_release', '-a') -+ stdout = subprocess.check_output(cmd, stderr=devnull) -+ except OSError: # Command not found -+ return {} -+ content = stdout.decode(sys.getfilesystemencoding()).splitlines() -+ return self._parse_lsb_release_content(content) -+ -+ @staticmethod -+ def _parse_lsb_release_content(lines): -+ """ -+ Parse the output of the lsb_release command. -+ -+ Parameters: -+ -+ * lines: Iterable through the lines of the lsb_release output. -+ Each line must be a unicode string or a UTF-8 encoded byte -+ string. -+ -+ Returns: -+ A dictionary containing all information items. -+ """ -+ props = {} -+ for line in lines: -+ kv = line.strip('\n').split(':', 1) -+ if len(kv) != 2: -+ # Ignore lines without colon. -+ continue -+ k, v = kv -+ props.update({k.replace(' ', '_').lower(): v.strip()}) -+ return props -+ -+ @cached_property -+ def _uname_info(self): -+ with open(os.devnull, 'w') as devnull: -+ try: -+ cmd = ('uname', '-rs') -+ stdout = subprocess.check_output(cmd, stderr=devnull) -+ except OSError: -+ return {} -+ content = stdout.decode(sys.getfilesystemencoding()).splitlines() -+ return self._parse_uname_content(content) -+ -+ @staticmethod -+ def _parse_uname_content(lines): -+ props = {} -+ match = re.search(r'^([^\s]+)\s+([\d\.]+)', lines[0].strip()) -+ if match: -+ name, version = match.groups() -+ -+ # This is to prevent the Linux kernel version from -+ # appearing as the 'best' version on otherwise -+ # identifiable distributions. -+ if name == 'Linux': -+ return {} -+ props['id'] = name.lower() -+ props['name'] = name -+ props['release'] = version -+ return props -+ -+ @cached_property -+ def _distro_release_info(self): -+ """ -+ Get the information items from the specified distro release file. -+ -+ Returns: -+ A dictionary containing all information items. -+ """ -+ if self.distro_release_file: -+ # If it was specified, we use it and parse what we can, even if -+ # its file name or content does not match the expected pattern. -+ distro_info = self._parse_distro_release_file( -+ self.distro_release_file) -+ basename = os.path.basename(self.distro_release_file) -+ # The file name pattern for user-specified distro release files -+ # is somewhat more tolerant (compared to when searching for the -+ # file), because we want to use what was specified as best as -+ # possible. -+ match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) -+ if 'name' in distro_info \ -+ and 'cloudlinux' in distro_info['name'].lower(): -+ distro_info['id'] = 'cloudlinux' -+ elif match: -+ distro_info['id'] = match.group(1) -+ return distro_info -+ else: -+ try: -+ basenames = os.listdir(_UNIXCONFDIR) -+ # We sort for repeatability in cases where there are multiple -+ # distro specific files; e.g. CentOS, Oracle, Enterprise all -+ # containing `redhat-release` on top of their own. -+ basenames.sort() -+ except OSError: -+ # This may occur when /etc is not readable but we can't be -+ # sure about the *-release files. Check common entries of -+ # /etc for information. If they turn out to not be there the -+ # error is handled in `_parse_distro_release_file()`. -+ basenames = ['SuSE-release', -+ 'arch-release', -+ 'base-release', -+ 'centos-release', -+ 'fedora-release', -+ 'gentoo-release', -+ 'mageia-release', -+ 'mandrake-release', -+ 'mandriva-release', -+ 'mandrivalinux-release', -+ 'manjaro-release', -+ 'oracle-release', -+ 'redhat-release', -+ 'sl-release', -+ 'slackware-version'] -+ for basename in basenames: -+ if basename in _DISTRO_RELEASE_IGNORE_BASENAMES: -+ continue -+ match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) -+ if match: -+ filepath = os.path.join(_UNIXCONFDIR, basename) -+ distro_info = self._parse_distro_release_file(filepath) -+ if 'name' in distro_info: -+ # The name is always present if the pattern matches -+ self.distro_release_file = filepath -+ distro_info['id'] = match.group(1) -+ if 'cloudlinux' in distro_info['name'].lower(): -+ distro_info['id'] = 'cloudlinux' -+ return distro_info -+ return {} -+ -+ def _parse_distro_release_file(self, filepath): -+ """ -+ Parse a distro release file. -+ -+ Parameters: -+ -+ * filepath: Path name of the distro release file. -+ -+ Returns: -+ A dictionary containing all information items. -+ """ -+ try: -+ with open(filepath) as fp: -+ # Only parse the first line. For instance, on SLES there -+ # are multiple lines. We don't want them... -+ return self._parse_distro_release_content(fp.readline()) -+ except (OSError, IOError): -+ # Ignore not being able to read a specific, seemingly version -+ # related file. -+ # See https://github.com/nir0s/distro/issues/162 -+ return {} -+ -+ @staticmethod -+ def _parse_distro_release_content(line): -+ """ -+ Parse a line from a distro release file. -+ -+ Parameters: -+ * line: Line from the distro release file. Must be a unicode string -+ or a UTF-8 encoded byte string. -+ -+ Returns: -+ A dictionary containing all information items. -+ """ -+ if isinstance(line, bytes): -+ line = line.decode('utf-8') -+ matches = _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN.match( -+ line.strip()[::-1]) -+ distro_info = {} -+ if matches: -+ # regexp ensures non-None -+ distro_info['name'] = matches.group(3)[::-1] -+ if matches.group(2): -+ distro_info['version_id'] = matches.group(2)[::-1] -+ if matches.group(1): -+ distro_info['codename'] = matches.group(1)[::-1] -+ elif line: -+ distro_info['name'] = line.strip() -+ return distro_info -+ -+ -+_distro = LinuxDistribution() -+ -+ -+def main(): -+ logger = logging.getLogger(__name__) -+ logger.setLevel(logging.DEBUG) -+ logger.addHandler(logging.StreamHandler(sys.stdout)) -+ -+ parser = argparse.ArgumentParser(description="OS distro info tool") -+ parser.add_argument( -+ '--json', -+ '-j', -+ help="Output in machine readable format", -+ action="store_true") -+ args = parser.parse_args() -+ -+ if args.json: -+ logger.info(json.dumps(info(), indent=4, sort_keys=True)) -+ else: -+ logger.info('Name: %s', name(pretty=True)) -+ distribution_version = version(pretty=True) -+ logger.info('Version: %s', distribution_version) -+ distribution_codename = codename() -+ logger.info('Codename: %s', distribution_codename) -+ -+ -+if __name__ == '__main__': -+ main() -diff --git a/third_party/python/distro/docs/conf.py b/third_party/python/distro/docs/conf.py -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/docs/conf.py -@@ -0,0 +1,342 @@ -+# -*- coding: utf-8 -*- -+# -+# Configuration file for Sphinx builds, created by -+# sphinx-quickstart on Wed Mar 2 11:33:06 2016. -+# -+# This file is execfile()d with the current directory set to its -+# containing dir. -+# -+# Note that not all possible configuration values are present in this -+# autogenerated file. -+# -+# All configuration values have a default; values that are commented out -+# serve to show the default. -+ -+import sys -+import os -+import re -+ -+# If extensions (or modules to document with autodoc) are in another directory, -+# add these directories to sys.path here. If the directory is relative to the -+# documentation root, use os.path.abspath to make it absolute, like shown here. -+sys.path.insert(0, os.path.abspath('..')) -+ -+# -- General configuration ------------------------------------------------ -+ -+# If your documentation needs a minimal Sphinx version, state it here. -+needs_sphinx = '1.1' -+ -+# Add any Sphinx extension module names here, as strings. They can be -+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -+# ones. -+extensions = [ -+ 'sphinx.ext.autodoc', -+ 'sphinx.ext.intersphinx', -+ 'sphinx.ext.todo', -+ 'sphinx.ext.coverage', -+ 'sphinx.ext.viewcode', -+] -+ -+# Add any paths that contain templates here, relative to this directory. -+templates_path = ['_templates'] -+ -+# The suffix(es) of source filenames. -+# You can specify multiple suffix as a list of string: -+# source_suffix = ['.rst', '.md'] -+source_suffix = '.rst' -+ -+# The encoding of source files. -+source_encoding = 'utf-8' -+ -+# The master toctree document. -+on_rtd = os.environ.get('READTHEDOCS', None) == 'True' -+if on_rtd: -+ master_doc = 'index' -+else: -+ master_doc = 'docs/index' -+ -+# General information about the project. -+project = u'distro' -+copyright = u'2015,2016, Nir Cohen, Andreas Maier' -+author = u'Nir Cohen, Andreas Maier' -+ -+# The short description of the package. -+_short_description = u'Linux Distribution - a Linux OS platform information API' -+ -+# The version info for the project you're documenting, acts as replacement for -+# |version| and |release|, also used in various other places throughout the -+# built documents. -+ -+def parse_version(): -+ with open('../setup.py', 'r') as _fp: -+ _lines = _fp.readlines() -+ for _line in _lines: -+ m = re.match(r'^package_version *= *[\'"](.+)[\'"].*$', _line) -+ if m: -+ break -+ if m: -+ return m.group(1) -+ else: -+ return 'unknown' -+ -+# The short X.Y version. -+# Note: We use the full version in both cases. -+version = parse_version() -+ -+# The full version, including alpha/beta/rc tags. -+release = version -+ -+# The language for content autogenerated by Sphinx. Refer to documentation -+# for a list of supported languages. -+# -+# This is also used if you do content translation via gettext catalogs. -+# Usually you set "language" from the command line for these cases. -+language = None -+ -+# There are two options for replacing |today|: either, you set today to some -+# non-false value, then it is used: -+#today = '' -+# Else, today_fmt is used as the format for a strftime call. -+#today_fmt = '%B %d, %Y' -+ -+# List of patterns, relative to source directory, that match files and -+# directories to ignore when looking for source files. -+exclude_patterns = ["tests", ".tox", ".git", "build_docs", "ld.egg-info"] -+ -+# The reST default role (used for this markup: `text`) to use for all -+# documents. -+#default_role = None -+ -+# If true, '()' will be appended to :func: etc. cross-reference text. -+add_function_parentheses = True -+ -+# If true, the current module name will be prepended to all description -+# unit titles (such as .. function::). -+#add_module_names = True -+ -+# If true, sectionauthor and moduleauthor directives will be shown in the -+# output. They are ignored by default. -+#show_authors = False -+ -+# The name of the Pygments (syntax highlighting) style to use. -+pygments_style = 'sphinx' -+ -+# A list of ignored prefixes for module index sorting. -+#modindex_common_prefix = [] -+ -+# If true, keep warnings as "system message" paragraphs in the built documents. -+#keep_warnings = False -+ -+# If true, `todo` and `todoList` produce output, else they produce nothing. -+todo_include_todos = True -+ -+ -+# -- Options for HTML output ---------------------------------------------- -+ -+# The theme to use for HTML and HTML Help pages. -+# See http://www.sphinx-doc.org/en/stable/theming.html for built-in themes. -+html_theme = "classic" -+ -+# Theme options are theme-specific and customize the look and feel of a theme -+# further. -+# See http://www.sphinx-doc.org/en/stable/theming.html for the options -+# available for built-in themes. -+html_theme_options = { -+} -+ -+# Add any paths that contain custom themes here, relative to this directory. -+#html_theme_path = [] -+ -+# The name for this set of Sphinx documents. If not defined, it defaults to -+# "<project> v<release> documentation". -+#html_title = None -+ -+# A shorter title for the navigation bar. Default is the same as html_title. -+#html_short_title = 'distro' -+ -+# The name of an image file (relative to this directory) to place at the top -+# of the sidebar. -+#html_logo = None -+ -+# The name of an image file (relative to this directory) to use as a favicon of -+# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -+# pixels large. -+#html_favicon = None -+ -+# Add any paths that contain custom static files (such as style sheets) here, -+# relative to this directory. They are copied after the builtin static files, -+# so a file named "default.css" will overwrite the builtin "default.css". -+html_static_path = ['html_static'] -+ -+# Add any extra paths that contain custom files (such as robots.txt or -+# .htaccess) here, relative to this directory. These files are copied -+# directly to the root of the documentation. -+html_extra_path = ['html_extra'] -+ -+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -+# using the given strftime format. -+#html_last_updated_fmt = '%b %d, %Y' -+ -+# If true, SmartyPants will be used to convert quotes and dashes to -+# typographically correct entities. -+#html_use_smartypants = True -+ -+# Custom sidebar templates, maps document names to template names. -+#html_sidebars = {} -+ -+# Additional templates that should be rendered to pages, maps page names to -+# template names. -+#html_additional_pages = {} -+ -+# If false, no module index is generated. -+#html_domain_indices = True -+ -+# If false, no index is generated. -+#html_use_index = True -+ -+# If true, the index is split into individual pages for each letter. -+#html_split_index = False -+ -+# If true, links to the reST sources are added to the pages. -+#html_show_sourcelink = True -+ -+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -+#html_show_sphinx = True -+ -+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -+#html_show_copyright = True -+ -+# If true, an OpenSearch description file will be output, and all pages will -+# contain a <link> tag referring to it. The value of this option must be the -+# base URL from which the finished HTML is served. -+#html_use_opensearch = '' -+ -+# This is the file name suffix for HTML files (e.g. ".xhtml"). -+#html_file_suffix = None -+ -+# Language to be used for generating the HTML full-text search index. -+# Sphinx supports the following languages: -+# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -+# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -+#html_search_language = 'en' -+ -+# A dictionary with options for the search language support, empty by default. -+# Now only 'ja' uses this config value -+#html_search_options = {'type': 'default'} -+ -+# The name of a javascript file (relative to the configuration directory) that -+# implements a search results scorer. If empty, the default will be used. -+#html_search_scorer = 'scorer.js' -+ -+# Output file base name for HTML help builder. -+htmlhelp_basename = 'distro_doc' -+ -+# -- Options for LaTeX output --------------------------------------------- -+ -+latex_elements = { -+# The paper size ('letterpaper' or 'a4paper'). -+#'papersize': 'letterpaper', -+ -+# The font size ('10pt', '11pt' or '12pt'). -+#'pointsize': '10pt', -+ -+# Additional stuff for the LaTeX preamble. -+#'preamble': '', -+ -+# Latex figure (float) alignment -+#'figure_align': 'htbp', -+} -+ -+# Grouping the document tree into LaTeX files. List of tuples -+# (source start file, target name, title, -+# author, documentclass [howto, manual, or own class]). -+latex_documents = [ -+ (master_doc, 'ld.tex', _short_description, author, 'manual'), -+] -+ -+# The name of an image file (relative to this directory) to place at the top of -+# the title page. -+#latex_logo = None -+ -+# For "manual" documents, if this is true, then toplevel headings are parts, -+# not chapters. -+#latex_use_parts = False -+ -+# If true, show page references after internal links. -+#latex_show_pagerefs = False -+ -+# If true, show URL addresses after external links. -+#latex_show_urls = False -+ -+# Documents to append as an appendix to all manuals. -+#latex_appendices = [] -+ -+# If false, no module index is generated. -+#latex_domain_indices = True -+ -+ -+# -- Options for manual page output --------------------------------------- -+ -+# One entry per manual page. List of tuples -+# (source start file, name, description, authors, manual section). -+man_pages = [ -+ (master_doc, 'ld', _short_description, [author], 1) -+] -+ -+# If true, show URL addresses after external links. -+#man_show_urls = False -+ -+ -+# -- Options for Texinfo output ------------------------------------------- -+ -+# Grouping the document tree into Texinfo files. List of tuples -+# (source start file, target name, title, author, -+# dir menu entry, description, category) -+texinfo_documents = [ -+ (master_doc, 'LinuxDistribution', _short_description, -+ author, 'LinuxDistribution', _short_description, -+ 'Miscellaneous'), -+] -+ -+# Documents to append as an appendix to all manuals. -+#texinfo_appendices = [] -+ -+# If false, no module index is generated. -+#texinfo_domain_indices = True -+ -+# How to display URL addresses: 'footnote', 'no', or 'inline'. -+#texinfo_show_urls = 'footnote' -+ -+# If true, do not generate a @detailmenu in the "Top" node's menu. -+#texinfo_no_detailmenu = False -+ -+ -+# -- Options for autodoc extension ---------------------------------------- -+# For documentation, see -+# http://www.sphinx-doc.org/en/stable/ext/autodoc.html -+ -+# Selects what content will be inserted into a class description. -+# The possible values are: -+# "class" - Only the classβ docstring is inserted. This is the default. -+# "both" - Both the classβ and the __init__ methodβs docstring are -+# concatenated and inserted. -+# "init" - Only the __init__ methodβs docstring is inserted. -+autoclass_content = "both" -+ -+# Selects if automatically documented members are sorted alphabetically -+# (value 'alphabetical'), by member type (value 'groupwise') or by source -+# order (value 'bysource'). The default is alphabetical. -+autodoc_member_order = "bysource" -+ -+# -- Options for intersphinx extension ------------------------------------ -+# For documentation, see -+# http://www.sphinx-doc.org/en/stable/ext/intersphinx.html -+ -+# Defines the prefixes for intersphinx links, and the targets they resolve -+# to. Example RST source for 'py' prefix: -+# :py:func:`platform.dist` -+intersphinx_mapping = { -+ 'py': ('https://docs.python.org/3.5', None) -+} -+ -+intersphinx_cache_limit = 5 -diff --git a/third_party/python/distro/docs/index.rst b/third_party/python/distro/docs/index.rst -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/docs/index.rst -@@ -0,0 +1,476 @@ -+ -+.. _distro official repo: https://github.com/nir0s/distro -+.. _distro issue tracker: https://github.com/nir0s/distro/issues -+.. _open issues on missing test data: https://github.com/nir0s/distro/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22> -+ -+ -+**distro** package (Linux Distribution) version |version| -+********************************************************* -+ -+Official distro repository: `distro official repo`_ -+ -+Overview and motivation -+======================= -+ -+.. automodule:: distro -+ -+If you want to jump into the API description right away, read about the -+`consolidated accessor functions`_. -+ -+Compatibility -+============= -+ -+The ``distro`` package is supported on Python 2.7, 3.4+ and PyPy, and on -+any Linux or *BSD distribution that provides one or more of the `data sources`_ -+used by this package. -+ -+This package is tested on Python 2.7, 3.4+ and PyPy, with test data that -+mimics the exact behavior of the data sources of -+`a number of Linux distributions <https://github.com/nir0s/distro/tree/master/tests/resources/distros>`_. -+ -+If you want to add test data for more distributions, please -+create an issue in the `distro issue tracker`_ -+and provide the following information in the issue: -+ -+* The content of the `/etc/os-release` file, if any. -+* The file names and content of the `/etc/*release` and `/etc/*version` files, if any. -+* The output of the command: `lsb_release -a`, if available. -+* The file names and content of any other files you are aware of that provide -+ useful information about the distro. -+ -+There are already some `open issues on missing test data`_. -+ -+ -+Data sources -+============ -+ -+The ``distro`` package implements a robust and inclusive way of retrieving the -+information about a Linux distribution based on new standards and old methods, -+namely from these data sources: -+ -+* The `os-release file`_, if present. -+ -+* The `lsb_release command output`_, if the lsb_release command is available. -+ -+* The `distro release file`_, if present. -+ -+* The `uname command output`_, if present. -+ -+ -+Access to the information -+========================= -+ -+This package provides three ways to access the information about a Linux -+distribution: -+ -+* `Consolidated accessor functions`_ -+ -+ These are module-global functions that take into account all data sources in -+ a priority order, and that return information about the current Linux -+ distribution. -+ -+ These functions should be the normal way to access the information. -+ -+ The precedence of data sources is applied for each information item -+ separately. Therefore, it is possible that not all information items returned -+ by these functions come from the same data source. For example, on a -+ distribution that has an lsb_release command that returns the -+ "Distributor ID" field but not the "Codename" field, and that has a distro -+ release file that specifies a codename inside, the distro ID will come from -+ the lsb_release command (because it has higher precedence), and the codename -+ will come from the distro release file (because it is not provided by the -+ lsb_release command). -+ -+ Examples: :func:`distro.id` for retrieving -+ the distro ID, or :func:`ld.info` to get the machine-readable part of the -+ information in a more aggregated way, or :func:`distro.linux_distribution` with -+ an interface that is compatible to the original -+ :py:func:`platform.linux_distribution` function, supporting a subset of its -+ parameters. -+ -+* `Single source accessor functions`_ -+ -+ These are module-global functions that take into account a single data -+ source, and that return information about the current Linux distribution. -+ -+ They are useful for distributions that provide multiple inconsistent data -+ sources, or for retrieving information items that are not provided by the -+ consolidated accessor functions. -+ -+ Examples: :func:`distro.os_release_attr` for retrieving a single information -+ item from the os-release data source, or :func:`distro.lsb_release_info` for -+ retrieving all information items from the lsb_release command output data -+ source. -+ -+* `LinuxDistribution class`_ -+ -+ The :class:`distro.LinuxDistribution` class provides the main code of this -+ package. -+ -+ This package contains a private module-global :class:`distro.LinuxDistribution` -+ instance with default initialization arguments, that is used by the -+ consolidated and single source accessor functions. -+ -+ A user-defined instance of the :class:`distro.LinuxDistribution` class allows -+ specifying the path names of the os-release file and distro release file and -+ whether the lsb_release command should be used or not. That is useful for -+ example when the distribution information from a chrooted environment -+ is to be retrieved, or when a distro has multiple distro release files and -+ the default algorithm uses the wrong one. -+ -+ -+Consolidated accessor functions -+=============================== -+ -+This section describes the consolidated accessor functions. -+See `access to the information`_ for a discussion of the different kinds of -+accessor functions. -+ -+.. autofunction:: distro.linux_distribution -+.. autofunction:: distro.id -+.. autofunction:: distro.name -+.. autofunction:: distro.version -+.. autofunction:: distro.version_parts -+.. autofunction:: distro.major_version -+.. autofunction:: distro.minor_version -+.. autofunction:: distro.build_number -+.. autofunction:: distro.like -+.. autofunction:: distro.codename -+.. autofunction:: distro.info -+ -+Single source accessor functions -+================================ -+ -+This section describes the single source accessor functions. -+See `access to the information`_ for a discussion of the different kinds of -+accessor functions. -+ -+.. autofunction:: distro.os_release_info -+.. autofunction:: distro.lsb_release_info -+.. autofunction:: distro.distro_release_info -+.. autofunction:: distro.os_release_attr -+.. autofunction:: distro.lsb_release_attr -+.. autofunction:: distro.distro_release_attr -+ -+LinuxDistribution class -+======================= -+ -+This section describes the access via the :class:`distro.LinuxDistribution` class. -+See `access to the information`_ for a discussion of the different kinds of -+accessor functions. -+ -+.. autoclass:: distro.LinuxDistribution -+ :members: -+ :undoc-members: -+ -+Normalization tables -+==================== -+ -+These translation tables are used to normalize the parsed distro ID values -+into reliable IDs. See :func:`distro.id` for details. -+ -+They are documented in order to show for which distros a normalization is -+currently defined. -+ -+As a quick fix, these tables can also be extended by the user by appending new -+entries, should the need arise. If you have a need to get these tables -+extended, please make an according request in the `distro issue tracker`_. -+ -+.. autodata:: distro.NORMALIZED_OS_ID -+.. autodata:: distro.NORMALIZED_LSB_ID -+.. autodata:: distro.NORMALIZED_DISTRO_ID -+ -+Os-release file -+=============== -+ -+The os-release file is looked up using the path name ``/etc/os-release``. Its -+optional additional location ``/usr/lib/os-release`` is ignored. -+ -+The os-release file is expected to be encoded in UTF-8. -+ -+It is parsed using the standard Python :py:mod:`shlex` package, which treats it -+like a shell script. -+ -+The attribute names found in the file are translated to lower case and then -+become the keys of the information items from the os-release file data source. -+These keys can be used to retrieve single items with the -+:func:`distro.os_release_attr` function, and they are also used as keys in the -+dictionary returned by :func:`distro.os_release_info`. -+ -+The attribute values found in the file are processed using shell rules (e.g. -+for whitespace, escaping, and quoting) before they become the values of the -+information items from the os-release file data source. -+ -+If the attribute "VERSION" is found in the file, the distro codename is -+extracted from its value if it can be found there. If a codename is found, it -+becomes an additional information item with key "codename". -+ -+See the `os-release man page -+<http://www.freedesktop.org/software/systemd/man/os-release.html>`_ -+for a list of possible attributes in the file. -+ -+**Examples:** -+ -+1. The following os-release file content: -+ -+ .. sourcecode:: shell -+ -+ NAME='Ubuntu' -+ VERSION="14.04.3 LTS, Trusty Tahr" -+ ID=ubuntu -+ ID_LIKE=debian -+ PRETTY_NAME="Ubuntu 14.04.3 LTS" -+ VERSION_ID="14.04" -+ HOME_URL="http://www.ubuntu.com/" -+ SUPPORT_URL="http://help.ubuntu.com/" -+ BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" -+ -+ results in these information items: -+ -+ =============================== ========================================== -+ Key Value -+ =============================== ========================================== -+ name "Ubuntu" -+ version "14.04.3 LTS, Trusty Tahr" -+ id "ubuntu" -+ id_like "debian" -+ pretty_name "Ubuntu 14.04.3 LTS" -+ version_id "14.04" -+ home_url "http://www.ubuntu.com/" -+ support_url "http://help.ubuntu.com/" -+ bug_report_url "http://bugs.launchpad.net/ubuntu/" -+ codename "Trusty Tahr" -+ =============================== ========================================== -+ -+2. The following os-release file content: -+ -+ .. sourcecode:: shell -+ -+ NAME="Red Hat Enterprise Linux Server" -+ VERSION="7.0 (Maipo)" -+ ID="rhel" -+ ID_LIKE="fedora" -+ VERSION_ID="7.0" -+ PRETTY_NAME="Red Hat Enterprise Linux Server 7.0 (Maipo)" -+ ANSI_COLOR="0;31" -+ CPE_NAME="cpe:/o:redhat:enterprise_linux:7.0:GA:server" -+ HOME_URL="https://www.redhat.com/" -+ BUG_REPORT_URL="https://bugzilla.redhat.com/" -+ -+ REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7" -+ REDHAT_BUGZILLA_PRODUCT_VERSION=7.0 -+ REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" -+ REDHAT_SUPPORT_PRODUCT_VERSION=7.0 -+ -+ results in these information items: -+ -+ =============================== ========================================== -+ Key Value -+ =============================== ========================================== -+ name "Red Hat Enterprise Linux Server" -+ version "7.0 (Maipo)" -+ id "rhel" -+ id_like "fedora" -+ version_id "7.0" -+ pretty_name "Red Hat Enterprise Linux Server 7.0 (Maipo)" -+ ansi_color "0;31" -+ cpe_name "cpe:/o:redhat:enterprise_linux:7.0:GA:server" -+ home_url "https://www.redhat.com/" -+ bug_report_url "https://bugzilla.redhat.com/" -+ redhat_bugzilla_product "Red Hat Enterprise Linux 7" -+ redhat_bugzilla_product_version "7.0" -+ redhat_support_product "Red Hat Enterprise Linux" -+ redhat_support_product_version "7.0" -+ codename "Maipo" -+ =============================== ========================================== -+ -+Lsb_release command output -+========================== -+ -+The lsb_release command is expected to be in the PATH, and is invoked as -+follows: -+ -+.. sourcecode:: shell -+ -+ lsb_release -a -+ -+The command output is expected to be encoded in UTF-8. -+ -+Only lines in the command output with the following format will be used: -+ -+ ``<attr-name>: <attr-value>`` -+ -+Where: -+ -+* ``<attr-name>`` is the name of the attribute, and -+* ``<attr-value>`` is the attribute value. -+ -+The attribute names are stripped from surrounding blanks, any remaining blanks -+are translated to underscores, they are translated to lower case, and then -+become the keys of the information items from the lsb_release command output -+data source. -+ -+The attribute values are stripped from surrounding blanks, and then become the -+values of the information items from the lsb_release command output data -+source. -+ -+See the `lsb_release man page -+<http://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/ -+LSB-Core-generic/lsbrelease.html>`_ -+for a description of standard attributes returned by the lsb_release command. -+ -+**Examples:** -+ -+1. The following lsb_release command output: -+ -+ .. sourcecode:: text -+ -+ No LSB modules are available. -+ Distributor ID: Ubuntu -+ Description: Ubuntu 14.04.3 LTS -+ Release: 14.04 -+ Codename: trusty -+ -+ results in these information items: -+ -+ =============================== ========================================== -+ Key Value -+ =============================== ========================================== -+ distributor_id "Ubuntu" -+ description "Ubuntu 14.04.3 LTS" -+ release "14.04" -+ codename "trusty" -+ =============================== ========================================== -+ -+2. The following lsb_release command output: -+ -+ .. sourcecode:: text -+ -+ LSB Version: n/a -+ Distributor ID: SUSE LINUX -+ Description: SUSE Linux Enterprise Server 12 SP1 -+ Release: 12.1 -+ Codename: n/a -+ -+ results in these information items: -+ -+ =============================== ========================================== -+ Key Value -+ =============================== ========================================== -+ lsb_version "n/a" -+ distributor_id "SUSE LINUX" -+ description "SUSE Linux Enterprise Server 12 SP1" -+ release "12.1" -+ codename "n/a" -+ =============================== ========================================== -+ -+Distro release file -+=================== -+ -+Unless specified with a particular path name when using the -+:class:`distro.LinuxDistribution` class, the distro release file is found by using -+the first match in the alphabetically sorted list of the files matching the -+following path name patterns: -+ -+* ``/etc/*-release`` -+* ``/etc/*_release`` -+* ``/etc/*-version`` -+* ``/etc/*_version`` -+ -+where the following special path names are excluded: -+ -+* ``/etc/debian_version`` -+* ``/etc/system-release`` -+* ``/etc/os-release`` -+ -+and where the first line within the file has the expected format. -+ -+The algorithm to sort the files alphabetically is far from perfect, but the -+distro release file has the least priority as a data source, and it is expected -+that distributions provide one of the other data sources. -+ -+The distro release file is expected to be encoded in UTF-8. -+ -+Only its first line is used, and it is expected to have the following format: -+ -+ ``<name> [[[release] <version_id>] (<codename>)]`` -+ -+Where: -+ -+* square brackets indicate optionality, -+* ``<name>`` is the distro name, -+* ``<version_id>`` is the distro version, and -+* ``<codename>`` is the distro codename. -+ -+The following information items can be found in a distro release file -+(shown with their keys and data types): -+ -+* ``id`` (string): Distro ID, taken from the first part of the file name -+ before the hyphen (``-``) or underscore (``_``). -+ -+ Note that the distro ID is not normalized or translated to lower case at this -+ point; this happens only for the result of the :func:`distro.id` function. -+ -+* ``name`` (string): Distro name, as found in the first line of the file. -+ -+* ``version_id`` (string): Distro version, as found in the first line of the -+ file. If not found, this information item will not exist. -+ -+* ``codename`` (string): Distro codename, as found in the first line of the -+ file. If not found, this information item will not exist. -+ -+ Note that the string in the codename field is not always really a -+ codename. For example, openSUSE returns "x86_64". -+ -+**Examples:** -+ -+1. The following distro release file ``/etc/centos-release``: -+ -+ .. sourcecode:: text -+ -+ CentOS Linux release 7.1.1503 (Core) -+ -+ results in these information items: -+ -+ =============================== ========================================== -+ Key Value -+ =============================== ========================================== -+ id "centos" -+ name "CentOS Linux" -+ version_id "7.1.1503" -+ codename "Core" -+ =============================== ========================================== -+ -+2. The following distro release file ``/etc/oracle-release``: -+ -+ .. sourcecode:: text -+ -+ Oracle Linux Server release 7.1 -+ -+ results in these information items: -+ -+ =============================== ========================================== -+ Key Value -+ =============================== ========================================== -+ id "oracle" -+ name "Oracle Linux Server" -+ version_id "7.1" -+ =============================== ========================================== -+ -+3. The following distro release file ``/etc/SuSE-release``: -+ -+ .. sourcecode:: text -+ -+ openSUSE 42.1 (x86_64) -+ -+ results in these information items: -+ -+ =============================== ========================================== -+ Key Value -+ =============================== ========================================== -+ id "SuSE" -+ name "openSUSE" -+ version_id "42.1" -+ codename "x86_64" -+ =============================== ========================================== -+ -diff --git a/third_party/python/distro/query_local_distro.py b/third_party/python/distro/query_local_distro.py -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/query_local_distro.py -@@ -0,0 +1,45 @@ -+#!/usr/bin/env python -+# Copyright 2015,2016 Nir Cohen -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); -+# you may not use this file except in compliance with the License. -+# You may obtain a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, -+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+# See the License for the specific language governing permissions and -+# limitations under the License. -+ -+from __future__ import print_function -+ -+from pprint import pformat -+ -+import distro -+ -+ -+def pprint(obj): -+ for line in pformat(obj).split('\n'): -+ print(4 * ' ' + line) -+ -+ -+print('os_release_info:') -+pprint(distro.os_release_info()) -+print('lsb_release_info:') -+pprint(distro.lsb_release_info()) -+print('distro_release_info:') -+pprint(distro.distro_release_info()) -+print('id: {0}'.format(distro.id())) -+print('name: {0}'.format(distro.name())) -+print('name_pretty: {0}'.format(distro.name(True))) -+print('version: {0}'.format(distro.version())) -+print('version_pretty: {0}'.format(distro.version(True))) -+print('like: {0}'.format(distro.like())) -+print('codename: {0}'.format(distro.codename())) -+print('linux_distribution_full: {0}'.format(distro.linux_distribution())) -+print('linux_distribution: {0}'.format(distro.linux_distribution(False))) -+print('major_version: {0}'.format(distro.major_version())) -+print('minor_version: {0}'.format(distro.minor_version())) -+print('build_number: {0}'.format(distro.build_number())) -diff --git a/third_party/python/distro/setup.cfg b/third_party/python/distro/setup.cfg -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/setup.cfg -@@ -0,0 +1,10 @@ -+[bdist_wheel] -+universal = 1 -+ -+[metadata] -+license_file = LICENSE -+ -+[egg_info] -+tag_build = -+tag_date = 0 -+ -diff --git a/third_party/python/distro/setup.py b/third_party/python/distro/setup.py -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/setup.py -@@ -0,0 +1,67 @@ -+# Copyright 2015,2016 Nir Cohen -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); -+# you may not use this file except in compliance with the License. -+# You may obtain a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, -+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+# See the License for the specific language governing permissions and -+# limitations under the License. -+ -+import os -+import codecs -+from setuptools import setup -+ -+# The following version is parsed by other parts of this package. -+# Don't change the format of the line, or the variable name. -+package_version = "1.4.0" -+ -+here = os.path.abspath(os.path.dirname(__file__)) -+ -+ -+def read(*parts): -+ # intentionally *not* adding an encoding option to open -+ return codecs.open(os.path.join(here, *parts), 'r').read() -+ -+ -+setup( -+ name='distro', -+ version=package_version, -+ url='https://github.com/nir0s/distro', -+ author='Nir Cohen', -+ author_email='nir36g@gmail.com', -+ license='Apache License, Version 2.0', -+ platforms='All', -+ description='Distro - an OS platform information API', -+ long_description=read('README.md'), -+ long_description_content_type='text/markdown', -+ py_modules=['distro'], -+ entry_points={ -+ 'console_scripts': [ -+ 'distro = distro:main', -+ ] -+ }, -+ classifiers=[ -+ 'Development Status :: 5 - Production/Stable', -+ 'Intended Audience :: Developers', -+ 'Intended Audience :: System Administrators', -+ 'License :: OSI Approved :: Apache Software License', -+ 'Operating System :: POSIX :: Linux', -+ 'Operating System :: POSIX :: BSD', -+ 'Operating System :: POSIX :: BSD :: FreeBSD', -+ 'Operating System :: POSIX :: BSD :: NetBSD', -+ 'Operating System :: POSIX :: BSD :: OpenBSD', -+ 'Programming Language :: Python :: 2', -+ 'Programming Language :: Python :: 2.7', -+ 'Programming Language :: Python :: 3', -+ 'Programming Language :: Python :: 3.4', -+ 'Programming Language :: Python :: 3.5', -+ 'Programming Language :: Python :: 3.6', -+ 'Topic :: Software Development :: Libraries :: Python Modules', -+ 'Topic :: System :: Operating System', -+ ] -+) -diff --git a/third_party/python/distro/tests/__init__.py b/third_party/python/distro/tests/__init__.py -new file mode 100644 -diff --git a/third_party/python/distro/tests/resources/distros/__shared__/bin/lsb_release b/third_party/python/distro/tests/resources/distros/__shared__/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/__shared__/bin/lsb_release -@@ -0,0 +1,43 @@ -+#!/bin/bash -+# -+# lsb_release command for testing the ld module. -+# Only the -a option is supported. -+# -+# This version of the lsb_release command reads an lsb-release file. -+# -+# The lsb-release file has the usual format, e.g.: -+# DISTRIB_ID=Ubuntu -+# DISTRIB_RELEASE=14.04 -+# DISTRIB_CODENAME=trusty -+# DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS" -+# Where each line is optional. If a line is missing, the default value -+# will be the empty string. -+# -+ -+if [[ "$@" != "-a" ]]; then -+ echo "Usage: lsb_release -a" -+ exit 2 -+fi -+ -+# Because the PATH is set to just this directory, we cannot use 'dirname' -+# or other external programs, but need to use built-in abilities of bash. -+LSB_FILE="${0%/*}/../etc/lsb-release" -+ -+if [[ ! -f $LSB_FILE ]]; then -+ echo "Error: LSB release file does not exist: $LSB_FILE" -+ exit 1 -+fi -+ -+source $LSB_FILE -+ -+if [[ -n $LSB_VERSION ]]; then -+ echo "LSB Version: $LSB_VERSION" -+else -+ echo "No LSB modules are available." -+fi -+echo "Distributor ID: ${DISTRIB_ID:-}" -+echo "Description: ${DISTRIB_DESCRIPTION:-}" -+echo "Release: ${DISTRIB_RELEASE:-}" -+echo "Codename: ${DISTRIB_CODENAME:-}" -+ -+exit 0 -diff --git a/third_party/python/distro/tests/resources/distros/amazon2014/etc/system-release b/third_party/python/distro/tests/resources/distros/amazon2014/etc/system-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/amazon2014/etc/system-release -@@ -0,0 +1,1 @@ -+Amazon Linux AMI release 2014.03 -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/amazon2016/etc/os-release b/third_party/python/distro/tests/resources/distros/amazon2016/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/amazon2016/etc/os-release -@@ -0,0 +1,9 @@ -+NAME="Amazon Linux AMI" -+VERSION="2016.03" -+ID="amzn" -+ID_LIKE="rhel fedora" -+VERSION_ID="2016.03" -+PRETTY_NAME="Amazon Linux AMI 2016.03" -+ANSI_COLOR="0;33" -+CPE_NAME="cpe:/o:amazon:linux:2016.03:ga" -+HOME_URL="http://aws.amazon.com/amazon-linux-ami/" -diff --git a/third_party/python/distro/tests/resources/distros/amazon2016/etc/system-release b/third_party/python/distro/tests/resources/distros/amazon2016/etc/system-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/amazon2016/etc/system-release -@@ -0,0 +1,1 @@ -+Amazon Linux AMI release 2016.03 -diff --git a/third_party/python/distro/tests/resources/distros/arch/etc/arch-release b/third_party/python/distro/tests/resources/distros/arch/etc/arch-release -new file mode 100644 -diff --git a/third_party/python/distro/tests/resources/distros/arch/etc/os-release b/third_party/python/distro/tests/resources/distros/arch/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/arch/etc/os-release -@@ -0,0 +1,7 @@ -+NAME="Arch Linux" -+ID=arch -+PRETTY_NAME="Arch Linux" -+ANSI_COLOR="0;36" -+HOME_URL="https://www.archlinux.org/" -+SUPPORT_URL="https://bbs.archlinux.org/" -+BUG_REPORT_URL="https://bugs.archlinux.org/" -diff --git a/third_party/python/distro/tests/resources/distros/arch/usr/lib/os-release b/third_party/python/distro/tests/resources/distros/arch/usr/lib/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/arch/usr/lib/os-release -@@ -0,0 +1,7 @@ -+NAME="Arch Linux" -+ID=arch -+PRETTY_NAME="Arch Linux" -+ANSI_COLOR="0;36" -+HOME_URL="https://www.archlinux.org/" -+SUPPORT_URL="https://bbs.archlinux.org/" -+BUG_REPORT_URL="https://bugs.archlinux.org/" -diff --git a/third_party/python/distro/tests/resources/distros/centos5/etc/centos-release b/third_party/python/distro/tests/resources/distros/centos5/etc/centos-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/centos5/etc/centos-release -@@ -0,0 +1,1 @@ -+CentOS release 5.11 (Final) -diff --git a/third_party/python/distro/tests/resources/distros/centos5/etc/redhat-release b/third_party/python/distro/tests/resources/distros/centos5/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/centos5/etc/redhat-release -@@ -0,0 +1,1 @@ -+CentOS release 5.11 (Final) -diff --git a/third_party/python/distro/tests/resources/distros/centos5/etc/system-release b/third_party/python/distro/tests/resources/distros/centos5/etc/system-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/centos5/etc/system-release -@@ -0,0 +1,1 @@ -+CentOS release 5.11 (Final) -diff --git a/third_party/python/distro/tests/resources/distros/centos7/etc/centos-release b/third_party/python/distro/tests/resources/distros/centos7/etc/centos-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/centos7/etc/centos-release -@@ -0,0 +1,1 @@ -+CentOS Linux release 7.1.1503 (Core) -diff --git a/third_party/python/distro/tests/resources/distros/centos7/etc/os-release b/third_party/python/distro/tests/resources/distros/centos7/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/centos7/etc/os-release -@@ -0,0 +1,16 @@ -+NAME="CentOS Linux" -+VERSION="7 (Core)" -+ID="centos" -+ID_LIKE="rhel fedora" -+VERSION_ID="7" -+PRETTY_NAME="CentOS Linux 7 (Core)" -+ANSI_COLOR="0;31" -+CPE_NAME="cpe:/o:centos:centos:7" -+HOME_URL="https://www.centos.org/" -+BUG_REPORT_URL="https://bugs.centos.org/" -+ -+CENTOS_MANTISBT_PROJECT="CentOS-7" -+CENTOS_MANTISBT_PROJECT_VERSION="7" -+REDHAT_SUPPORT_PRODUCT="centos" -+REDHAT_SUPPORT_PRODUCT_VERSION="7" -+ -diff --git a/third_party/python/distro/tests/resources/distros/centos7/etc/redhat-release b/third_party/python/distro/tests/resources/distros/centos7/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/centos7/etc/redhat-release -@@ -0,0 +1,1 @@ -+CentOS Linux release 7.1.1503 (Core) -diff --git a/third_party/python/distro/tests/resources/distros/centos7/etc/system-release b/third_party/python/distro/tests/resources/distros/centos7/etc/system-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/centos7/etc/system-release -@@ -0,0 +1,1 @@ -+CentOS Linux release 7.1.1503 (Core) -diff --git a/third_party/python/distro/tests/resources/distros/cloudlinux5/etc/redhat-release b/third_party/python/distro/tests/resources/distros/cloudlinux5/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/cloudlinux5/etc/redhat-release -@@ -0,0 +1,1 @@ -+CloudLinux Server release 5.11 (Vladislav Volkov) -diff --git a/third_party/python/distro/tests/resources/distros/cloudlinux6/etc/redhat-release b/third_party/python/distro/tests/resources/distros/cloudlinux6/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/cloudlinux6/etc/redhat-release -@@ -0,0 +1,1 @@ -+CloudLinux Server release 6.8 (Oleg Makarov) -diff --git a/third_party/python/distro/tests/resources/distros/cloudlinux7/etc/os-release b/third_party/python/distro/tests/resources/distros/cloudlinux7/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/cloudlinux7/etc/os-release -@@ -0,0 +1,10 @@ -+NAME="CloudLinux" -+VERSION="7.3 (Yury Malyshev)" -+ID="cloudlinux" -+ID_LIKE="rhel fedora centos" -+VERSION_ID="7.3" -+PRETTY_NAME="CloudLinux 7.3 (Yury Malyshev)" -+ANSI_COLOR="0:31" -+CPE_NAME="cpe:/o:cloudlinux:cloudlinux:7.3:GA:server" -+HOME_URL="https://www.cloudlinux.com/" -+BUG_REPORT_URL="https://helpdesk.cloudlinux.com/" -diff --git a/third_party/python/distro/tests/resources/distros/cloudlinux7/etc/redhat-release b/third_party/python/distro/tests/resources/distros/cloudlinux7/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/cloudlinux7/etc/redhat-release -@@ -0,0 +1,1 @@ -+CloudLinux release 7.3 (Yury Malyshev) -diff --git a/third_party/python/distro/tests/resources/distros/coreos/etc/oem-release b/third_party/python/distro/tests/resources/distros/coreos/etc/oem-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/coreos/etc/oem-release -@@ -0,0 +1,5 @@ -+ID=digitalocean -+VERSION_ID=0.0.4 -+NAME="DigitalOcean" -+HOME_URL="https://www.digitalocean.com/" -+BUG_REPORT_URL="https://github.com/coreos/bugs/issues" -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/coreos/etc/os-release b/third_party/python/distro/tests/resources/distros/coreos/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/coreos/etc/os-release -@@ -0,0 +1,9 @@ -+NAME=CoreOS -+ID=coreos -+VERSION=899.15.0 -+VERSION_ID=899.15.0 -+BUILD_ID=2016-04-05-1035 -+PRETTY_NAME="CoreOS 899.15.0" -+ANSI_COLOR="1;32" -+HOME_URL="https://coreos.com/" -+BUG_REPORT_URL="https://github.com/coreos/bugs/issues" -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/debian8/bin/lsb_release b/third_party/python/distro/tests/resources/distros/debian8/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/debian8/bin/lsb_release -@@ -0,0 +1,21 @@ -+#!/bin/bash -+# -+# lsb_release command for testing the ld module. -+# Only the -a option is supported. -+# -+# This version of the lsb_release command works without a corresponding -+# etc/lsb-release file. -+# -+ -+if [[ "$@" != "-a" ]]; then -+ echo "Usage: lsb_release -a" -+ exit 2 -+fi -+ -+echo "No LSB modules are available." -+echo "Distributor ID: Debian" -+echo "Description: Debian GNU/Linux 8.2 (jessie)" -+echo "Release: 8.2" -+echo "Codename: jessie" -+ -+exit 0 -diff --git a/third_party/python/distro/tests/resources/distros/debian8/etc/debian_version b/third_party/python/distro/tests/resources/distros/debian8/etc/debian_version -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/debian8/etc/debian_version -@@ -0,0 +1,1 @@ -+8.2 -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/debian8/etc/os-release b/third_party/python/distro/tests/resources/distros/debian8/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/debian8/etc/os-release -@@ -0,0 +1,8 @@ -+PRETTY_NAME="Debian GNU/Linux 8 (jessie)" -+NAME="Debian GNU/Linux" -+VERSION_ID="8" -+VERSION="8 (jessie)" -+ID=debian -+HOME_URL="http://www.debian.org/" -+SUPPORT_URL="http://www.debian.org/support/" -+BUG_REPORT_URL="https://bugs.debian.org/" -diff --git a/third_party/python/distro/tests/resources/distros/exherbo/etc/os-release b/third_party/python/distro/tests/resources/distros/exherbo/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/exherbo/etc/os-release -@@ -0,0 +1,7 @@ -+NAME="Exherbo" -+PRETTY_NAME="Exherbo Linux" -+ID="exherbo" -+ANSI_COLOR="0;32" -+HOME_URL="https://www.exherbo.org/" -+SUPPORT_URL="irc://irc.freenode.net/#exherbo" -+BUG_REPORT_URL="https://bugs.exherbo.org/" -diff --git a/third_party/python/distro/tests/resources/distros/fedora19/etc/fedora-release b/third_party/python/distro/tests/resources/distros/fedora19/etc/fedora-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora19/etc/fedora-release -@@ -0,0 +1,1 @@ -+Fedora release 19 (SchrΓΆdingerβs Cat) -diff --git a/third_party/python/distro/tests/resources/distros/fedora19/etc/issue b/third_party/python/distro/tests/resources/distros/fedora19/etc/issue -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora19/etc/issue -@@ -0,0 +1,3 @@ -+Fedora release 19 (SchrΓΆdingerβs Cat) -+Kernel \r on an \m (\l) -+ -diff --git a/third_party/python/distro/tests/resources/distros/fedora19/etc/issue.net b/third_party/python/distro/tests/resources/distros/fedora19/etc/issue.net -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora19/etc/issue.net -@@ -0,0 +1,2 @@ -+Fedora release 19 (SchrΓΆdingerβs Cat) -+Kernel \r on an \m (\l) -diff --git a/third_party/python/distro/tests/resources/distros/fedora19/etc/os-release b/third_party/python/distro/tests/resources/distros/fedora19/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora19/etc/os-release -@@ -0,0 +1,7 @@ -+NAME=Fedora -+VERSION="19 (SchrΓΆdingerβs Cat)" -+ID=fedora -+VERSION_ID=19 -+PRETTY_NAME="Fedora 19 (SchrΓΆdingerβs Cat)" -+ANSI_COLOR="0;34" -+CPE_NAME="cpe:/o:fedoraproject:fedora:19" -diff --git a/third_party/python/distro/tests/resources/distros/fedora19/etc/redhat-release b/third_party/python/distro/tests/resources/distros/fedora19/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora19/etc/redhat-release -@@ -0,0 +1,1 @@ -+Fedora release 19 (SchrΓΆdingerβs Cat) -diff --git a/third_party/python/distro/tests/resources/distros/fedora19/etc/system-release b/third_party/python/distro/tests/resources/distros/fedora19/etc/system-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora19/etc/system-release -@@ -0,0 +1,1 @@ -+Fedora release 19 (SchrΓΆdingerβs Cat) -diff --git a/third_party/python/distro/tests/resources/distros/fedora19/etc/system-release-cpe b/third_party/python/distro/tests/resources/distros/fedora19/etc/system-release-cpe -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora19/etc/system-release-cpe -@@ -0,0 +1,1 @@ -+cpe:/o:fedoraproject:fedora:19 -diff --git a/third_party/python/distro/tests/resources/distros/fedora23/etc/fedora-release b/third_party/python/distro/tests/resources/distros/fedora23/etc/fedora-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora23/etc/fedora-release -@@ -0,0 +1,1 @@ -+Fedora release 23 (Twenty Three) -diff --git a/third_party/python/distro/tests/resources/distros/fedora23/etc/os-release b/third_party/python/distro/tests/resources/distros/fedora23/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora23/etc/os-release -@@ -0,0 +1,14 @@ -+NAME=Fedora -+VERSION="23 (Twenty Three)" -+ID=fedora -+VERSION_ID=23 -+PRETTY_NAME="Fedora 23 (Twenty Three)" -+ANSI_COLOR="0;34" -+CPE_NAME="cpe:/o:fedoraproject:fedora:23" -+HOME_URL="https://fedoraproject.org/" -+BUG_REPORT_URL="https://bugzilla.redhat.com/" -+REDHAT_BUGZILLA_PRODUCT="Fedora" -+REDHAT_BUGZILLA_PRODUCT_VERSION=23 -+REDHAT_SUPPORT_PRODUCT="Fedora" -+REDHAT_SUPPORT_PRODUCT_VERSION=23 -+PRIVACY_POLICY_URL=https://fedoraproject.org/wiki/Legal:PrivacyPolicy -diff --git a/third_party/python/distro/tests/resources/distros/fedora23/etc/redhat-release b/third_party/python/distro/tests/resources/distros/fedora23/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora23/etc/redhat-release -@@ -0,0 +1,1 @@ -+Fedora release 23 (Twenty Three) -diff --git a/third_party/python/distro/tests/resources/distros/fedora23/etc/system-release b/third_party/python/distro/tests/resources/distros/fedora23/etc/system-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora23/etc/system-release -@@ -0,0 +1,1 @@ -+Fedora release 23 (Twenty Three) -diff --git a/third_party/python/distro/tests/resources/distros/fedora23/usr/lib/os-release b/third_party/python/distro/tests/resources/distros/fedora23/usr/lib/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora23/usr/lib/os-release -@@ -0,0 +1,14 @@ -+NAME=Fedora -+VERSION="23 (Twenty Three)" -+ID=fedora -+VERSION_ID=23 -+PRETTY_NAME="Fedora 23 (Twenty Three)" -+ANSI_COLOR="0;34" -+CPE_NAME="cpe:/o:fedoraproject:fedora:23" -+HOME_URL="https://fedoraproject.org/" -+BUG_REPORT_URL="https://bugzilla.redhat.com/" -+REDHAT_BUGZILLA_PRODUCT="Fedora" -+REDHAT_BUGZILLA_PRODUCT_VERSION=23 -+REDHAT_SUPPORT_PRODUCT="Fedora" -+REDHAT_SUPPORT_PRODUCT_VERSION=23 -+PRIVACY_POLICY_URL=https://fedoraproject.org/wiki/Legal:PrivacyPolicy -diff --git a/third_party/python/distro/tests/resources/distros/fedora30/etc/fedora-release b/third_party/python/distro/tests/resources/distros/fedora30/etc/fedora-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora30/etc/fedora-release -@@ -0,0 +1,1 @@ -+Fedora release 30 (Thirty) -diff --git a/third_party/python/distro/tests/resources/distros/fedora30/etc/os-release b/third_party/python/distro/tests/resources/distros/fedora30/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora30/etc/os-release -@@ -0,0 +1,19 @@ -+NAME=Fedora -+VERSION="30 (Thirty)" -+ID=fedora -+VERSION_ID=30 -+VERSION_CODENAME="" -+PLATFORM_ID="platform:f30" -+PRETTY_NAME="Fedora 30 (Thirty)" -+ANSI_COLOR="0;34" -+LOGO=fedora-logo-icon -+CPE_NAME="cpe:/o:fedoraproject:fedora:30" -+HOME_URL="https://fedoraproject.org/" -+DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/30/system-administrators-guide/" -+SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help" -+BUG_REPORT_URL="https://bugzilla.redhat.com/" -+REDHAT_BUGZILLA_PRODUCT="Fedora" -+REDHAT_BUGZILLA_PRODUCT_VERSION=30 -+REDHAT_SUPPORT_PRODUCT="Fedora" -+REDHAT_SUPPORT_PRODUCT_VERSION=30 -+PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy" -diff --git a/third_party/python/distro/tests/resources/distros/fedora30/etc/redhat-release b/third_party/python/distro/tests/resources/distros/fedora30/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora30/etc/redhat-release -@@ -0,0 +1,1 @@ -+Fedora release 30 (Thirty) -diff --git a/third_party/python/distro/tests/resources/distros/fedora30/etc/system-release b/third_party/python/distro/tests/resources/distros/fedora30/etc/system-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora30/etc/system-release -@@ -0,0 +1,1 @@ -+Fedora release 30 (Thirty) -diff --git a/third_party/python/distro/tests/resources/distros/fedora30/usr/lib/os-release b/third_party/python/distro/tests/resources/distros/fedora30/usr/lib/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/fedora30/usr/lib/os-release -@@ -0,0 +1,19 @@ -+NAME=Fedora -+VERSION="30 (Thirty)" -+ID=fedora -+VERSION_ID=30 -+VERSION_CODENAME="" -+PLATFORM_ID="platform:f30" -+PRETTY_NAME="Fedora 30 (Thirty)" -+ANSI_COLOR="0;34" -+LOGO=fedora-logo-icon -+CPE_NAME="cpe:/o:fedoraproject:fedora:30" -+HOME_URL="https://fedoraproject.org/" -+DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/30/system-administrators-guide/" -+SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help" -+BUG_REPORT_URL="https://bugzilla.redhat.com/" -+REDHAT_BUGZILLA_PRODUCT="Fedora" -+REDHAT_BUGZILLA_PRODUCT_VERSION=30 -+REDHAT_SUPPORT_PRODUCT="Fedora" -+REDHAT_SUPPORT_PRODUCT_VERSION=30 -+PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy" -diff --git a/third_party/python/distro/tests/resources/distros/freebsd111/bin/uname b/third_party/python/distro/tests/resources/distros/freebsd111/bin/uname -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/freebsd111/bin/uname -@@ -0,0 +1,4 @@ -+#!/bin/sh -+ -+echo "FreeBSD 11.1-RELEASE" -+ -diff --git a/third_party/python/distro/tests/resources/distros/gentoo/etc/gentoo-release b/third_party/python/distro/tests/resources/distros/gentoo/etc/gentoo-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/gentoo/etc/gentoo-release -@@ -0,0 +1,1 @@ -+Gentoo Base System release 2.2 -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/gentoo/etc/os-release b/third_party/python/distro/tests/resources/distros/gentoo/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/gentoo/etc/os-release -@@ -0,0 +1,7 @@ -+NAME=Gentoo -+ID=gentoo -+PRETTY_NAME="Gentoo/Linux" -+ANSI_COLOR="1;32" -+HOME_URL="http://www.gentoo.org/" -+SUPPORT_URL="http://www.gentoo.org/main/en/support.xml" -+BUG_REPORT_URL="https://bugs.gentoo.org/" -diff --git a/third_party/python/distro/tests/resources/distros/kali/etc/os-release b/third_party/python/distro/tests/resources/distros/kali/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/kali/etc/os-release -@@ -0,0 +1,10 @@ -+PRETTY_NAME="Kali GNU/Linux Rolling" -+NAME="Kali GNU/Linux" -+ID=kali -+VERSION="2017.1" -+VERSION_ID="2017.1" -+ID_LIKE=debian -+ANSI_COLOR="1;31" -+HOME_URL="http://www.kali.org/" -+SUPPORT_URL="http://forums.kali.org/" -+BUG_REPORT_URL="http://bugs.kali.org/" -diff --git a/third_party/python/distro/tests/resources/distros/kvmibm1/bin/lsb_release b/third_party/python/distro/tests/resources/distros/kvmibm1/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/kvmibm1/bin/lsb_release -@@ -0,0 +1,21 @@ -+#!/bin/bash -+# -+# lsb_release command for testing the ld module. -+# Only the -a option is supported. -+# -+# This version of the lsb_release command works without a corresponding -+# etc/lsb-release file. -+# -+ -+if [[ "$@" != "-a" ]]; then -+ echo "Usage: lsb_release -a" -+ exit 2 -+fi -+ -+echo "LSB Version: :core-4.1-noarch:core-4.1-s390x" -+echo "Distributor ID: kvmibm" -+echo "Description: KVM for IBM z Systems release 1.1.1 (Z) " -+echo "Release: 1.1.1" -+echo "Codename: Z" -+ -+exit 0 -diff --git a/third_party/python/distro/tests/resources/distros/kvmibm1/etc/base-release b/third_party/python/distro/tests/resources/distros/kvmibm1/etc/base-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/kvmibm1/etc/base-release -@@ -0,0 +1,1 @@ -+KVM for IBM z Systems release 1.1.1 (Z) -diff --git a/third_party/python/distro/tests/resources/distros/kvmibm1/etc/os-release b/third_party/python/distro/tests/resources/distros/kvmibm1/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/kvmibm1/etc/os-release -@@ -0,0 +1,9 @@ -+NAME="KVM for IBM z Systems" -+VERSION="1.1.1 (Z)" -+ID="kvmibm" -+ID_LIKE="rhel fedora" -+VERSION_ID="1.1.1" -+PRETTY_NAME="KVM for IBM z Systems 1.1.1 (Z)" -+ANSI_COLOR="0;34" -+CPE_NAME="cpe:/o:ibm:kvmibm:1.1.1" -+BUILD_ID="20160316" -diff --git a/third_party/python/distro/tests/resources/distros/kvmibm1/etc/redhat-release b/third_party/python/distro/tests/resources/distros/kvmibm1/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/kvmibm1/etc/redhat-release -@@ -0,0 +1,1 @@ -+KVM for IBM z Systems release 1.1.1 (Z) -diff --git a/third_party/python/distro/tests/resources/distros/kvmibm1/etc/system-release b/third_party/python/distro/tests/resources/distros/kvmibm1/etc/system-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/kvmibm1/etc/system-release -@@ -0,0 +1,1 @@ -+KVM for IBM z Systems release 1.1.1 (Z) -diff --git a/third_party/python/distro/tests/resources/distros/linuxmint17/bin/lsb_release b/third_party/python/distro/tests/resources/distros/linuxmint17/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/linuxmint17/bin/lsb_release -@@ -0,0 +1,43 @@ -+#!/bin/bash -+# -+# lsb_release command for testing the ld module. -+# Only the -a option is supported. -+# -+# This version of the lsb_release command reads an lsb-release file. -+# -+# The lsb-release file has the usual format, e.g.: -+# DISTRIB_ID=Ubuntu -+# DISTRIB_RELEASE=14.04 -+# DISTRIB_CODENAME=trusty -+# DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS" -+# Where each line is optional. If a line is missing, the default value -+# will be the empty string. -+# -+ -+if [[ "$@" != "-a" ]]; then -+ echo "Usage: lsb_release -a" -+ exit 2 -+fi -+ -+# Because the PATH is set to just this directory, we cannot use 'dirname' -+# or other external programs, but need to use built-in abilities of bash. -+LSB_FILE="${0%/*}/../etc/lsb-release" -+ -+if [[ ! -f $LSB_FILE ]]; then -+ echo "Error: LSB release file does not exist: $LSB_FILE" -+ exit 1 -+fi -+ -+source $LSB_FILE -+ -+if [[ -n $LSB_VERSION ]]; then -+ echo "LSB Version: $LSB_VERSION" -+else -+ echo "No LSB modules are available." -+fi -+echo "Distributor ID: ${DISTRIB_ID:-}" -+echo "Description: ${DISTRIB_DESCRIPTION:-}" -+echo "Release: ${DISTRIB_RELEASE:-}" -+echo "Codename: ${DISTRIB_CODENAME:-}" -+ -+exit 0 -diff --git a/third_party/python/distro/tests/resources/distros/linuxmint17/etc/debian_version b/third_party/python/distro/tests/resources/distros/linuxmint17/etc/debian_version -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/linuxmint17/etc/debian_version -@@ -0,0 +1,1 @@ -+jessie/sid -diff --git a/third_party/python/distro/tests/resources/distros/linuxmint17/etc/lsb-release b/third_party/python/distro/tests/resources/distros/linuxmint17/etc/lsb-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/linuxmint17/etc/lsb-release -@@ -0,0 +1,4 @@ -+DISTRIB_ID=LinuxMint -+DISTRIB_RELEASE=17.3 -+DISTRIB_CODENAME=rosa -+DISTRIB_DESCRIPTION="Linux Mint 17.3 Rosa" -diff --git a/third_party/python/distro/tests/resources/distros/linuxmint17/etc/os-release b/third_party/python/distro/tests/resources/distros/linuxmint17/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/linuxmint17/etc/os-release -@@ -0,0 +1,9 @@ -+NAME="Ubuntu" -+VERSION="14.04.3 LTS, Trusty Tahr" -+ID=ubuntu -+ID_LIKE=debian -+PRETTY_NAME="Ubuntu 14.04.3 LTS" -+VERSION_ID="14.04" -+HOME_URL="http://www.ubuntu.com/" -+SUPPORT_URL="http://help.ubuntu.com/" -+BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" -diff --git a/third_party/python/distro/tests/resources/distros/linuxmint17/etc/upstream-release/lsb-release b/third_party/python/distro/tests/resources/distros/linuxmint17/etc/upstream-release/lsb-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/linuxmint17/etc/upstream-release/lsb-release -@@ -0,0 +1,4 @@ -+DISTRIB_ID=Ubuntu -+DISTRIB_RELEASE=14.04 -+DISTRIB_CODENAME=trusty -+DISTRIB_DESCRIPTION="Ubuntu 14.04 LTS" -diff --git a/third_party/python/distro/tests/resources/distros/mageia5/bin/lsb_release b/third_party/python/distro/tests/resources/distros/mageia5/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mageia5/bin/lsb_release -@@ -0,0 +1,39 @@ -+#!/bin/bash -+# -+# lsb_release command for testing the ld module. -+# Only the -a option is supported. -+# -+# This version of the lsb_release command reads an lsb-release file. -+# -+# The lsb-release file has the usual format, e.g.: -+# DISTRIB_ID=Ubuntu -+# DISTRIB_RELEASE=14.04 -+# DISTRIB_CODENAME=trusty -+# DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS" -+# Where each line is optional. If a line is missing, the default value -+# will be the empty string. -+# -+ -+if [[ "$@" != "-a" ]]; then -+ echo "Usage: lsb_release -a" -+ exit 2 -+fi -+ -+# Because the PATH is set to just this directory, we cannot use 'dirname' -+# or other external programs, but need to use built-in abilities of bash. -+LSB_FILE="${0%/*}/../etc/lsb-release" -+ -+if [[ ! -f $LSB_FILE ]]; then -+ echo "Error: LSB release file does not exist: $LSB_FILE" -+ exit 1 -+fi -+ -+source $LSB_FILE -+ -+echo "LSB Version: ${LSB_VERSION:-*}" -+echo "Distributor ID: ${DISTRIB_ID:-}" -+echo "Description: ${DISTRIB_DESCRIPTION:-}" -+echo "Release: ${DISTRIB_RELEASE:-}" -+echo "Codename: ${DISTRIB_CODENAME:-}" -+ -+exit 0 -diff --git a/third_party/python/distro/tests/resources/distros/mageia5/etc/lsb-release b/third_party/python/distro/tests/resources/distros/mageia5/etc/lsb-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mageia5/etc/lsb-release -@@ -0,0 +1,5 @@ -+LSB_VERSION= -+DISTRIB_ID="Mageia" -+DISTRIB_RELEASE=5 -+DISTRIB_CODENAME=thornicroft -+DISTRIB_DESCRIPTION="Mageia 5" -diff --git a/third_party/python/distro/tests/resources/distros/mageia5/etc/mageia-release b/third_party/python/distro/tests/resources/distros/mageia5/etc/mageia-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mageia5/etc/mageia-release -@@ -0,0 +1,1 @@ -+Mageia release 5 (Official) for x86_64 -diff --git a/third_party/python/distro/tests/resources/distros/mageia5/etc/mandrake-release b/third_party/python/distro/tests/resources/distros/mageia5/etc/mandrake-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mageia5/etc/mandrake-release -@@ -0,0 +1,1 @@ -+Mageia release 5 (Official) for x86_64 -diff --git a/third_party/python/distro/tests/resources/distros/mageia5/etc/mandrakelinux-release b/third_party/python/distro/tests/resources/distros/mageia5/etc/mandrakelinux-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mageia5/etc/mandrakelinux-release -@@ -0,0 +1,1 @@ -+Mageia release 5 (Official) for x86_64 -diff --git a/third_party/python/distro/tests/resources/distros/mageia5/etc/mandriva-release b/third_party/python/distro/tests/resources/distros/mageia5/etc/mandriva-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mageia5/etc/mandriva-release -@@ -0,0 +1,1 @@ -+Mageia release 5 (Official) for x86_64 -diff --git a/third_party/python/distro/tests/resources/distros/mageia5/etc/os-release b/third_party/python/distro/tests/resources/distros/mageia5/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mageia5/etc/os-release -@@ -0,0 +1,10 @@ -+NAME="Mageia" -+VERSION="5" -+ID=mageia -+VERSION_ID=5 -+ID_LIKE="mandriva fedora" -+PRETTY_NAME="Mageia 5" -+ANSI_COLOR="1;36" -+HOME_URL="http://www.mageia.org/" -+SUPPORT_URL="http://www.mageia.org/support/" -+BUG_REPORT_URL="https://bugs.mageia.org/" -diff --git a/third_party/python/distro/tests/resources/distros/mageia5/etc/redhat-release b/third_party/python/distro/tests/resources/distros/mageia5/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mageia5/etc/redhat-release -@@ -0,0 +1,1 @@ -+Mageia release 5 (Official) for x86_64 -diff --git a/third_party/python/distro/tests/resources/distros/mageia5/etc/release b/third_party/python/distro/tests/resources/distros/mageia5/etc/release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mageia5/etc/release -@@ -0,0 +1,1 @@ -+Mageia release 5 (Official) for x86_64 -diff --git a/third_party/python/distro/tests/resources/distros/mageia5/etc/version b/third_party/python/distro/tests/resources/distros/mageia5/etc/version -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mageia5/etc/version -@@ -0,0 +1,1 @@ -+5 2 official -diff --git a/third_party/python/distro/tests/resources/distros/mageia5/usr/lib/os-release b/third_party/python/distro/tests/resources/distros/mageia5/usr/lib/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mageia5/usr/lib/os-release -@@ -0,0 +1,10 @@ -+NAME="Mageia" -+VERSION="5" -+ID=mageia -+VERSION_ID=5 -+ID_LIKE="mandriva fedora" -+PRETTY_NAME="Mageia 5" -+ANSI_COLOR="1;36" -+HOME_URL="http://www.mageia.org/" -+SUPPORT_URL="http://www.mageia.org/support/" -+BUG_REPORT_URL="https://bugs.mageia.org/" -diff --git a/third_party/python/distro/tests/resources/distros/mandriva2011/bin/lsb_release b/third_party/python/distro/tests/resources/distros/mandriva2011/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mandriva2011/bin/lsb_release -@@ -0,0 +1,39 @@ -+#!/bin/bash -+# -+# lsb_release command for testing the ld module. -+# Only the -a option is supported. -+# -+# This version of the lsb_release command reads an lsb-release file. -+# -+# The lsb-release file has the usual format, e.g.: -+# DISTRIB_ID=Ubuntu -+# DISTRIB_RELEASE=14.04 -+# DISTRIB_CODENAME=trusty -+# DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS" -+# Where each line is optional. If a line is missing, the default value -+# will be the empty string. -+# -+ -+if [[ "$@" != "-a" ]]; then -+ echo "Usage: lsb_release -a" -+ exit 2 -+fi -+ -+# Because the PATH is set to just this directory, we cannot use 'dirname' -+# or other external programs, but need to use built-in abilities of bash. -+LSB_FILE="${0%/*}/../etc/lsb-release" -+ -+if [[ ! -f $LSB_FILE ]]; then -+ echo "Error: LSB release file does not exist: $LSB_FILE" -+ exit 1 -+fi -+ -+source $LSB_FILE -+ -+echo "LSB Version: ${LSB_VERSION:-*}" -+echo "Distributor ID: ${DISTRIB_ID:-}" -+echo "Description: ${DISTRIB_DESCRIPTION:-}" -+echo "Release: ${DISTRIB_RELEASE:-}" -+echo "Codename: ${DISTRIB_CODENAME:-}" -+ -+exit 0 -diff --git a/third_party/python/distro/tests/resources/distros/mandriva2011/etc/lsb-release b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/lsb-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/lsb-release -@@ -0,0 +1,5 @@ -+LSB_VERSION= -+DISTRIB_ID=MandrivaLinux -+DISTRIB_RELEASE=2011.0 -+DISTRIB_CODENAME=turtle -+DISTRIB_DESCRIPTION="Mandriva Linux 2011.0" -diff --git a/third_party/python/distro/tests/resources/distros/mandriva2011/etc/mandrake-release b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/mandrake-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/mandrake-release -@@ -0,0 +1,1 @@ -+Mandriva Linux release 2011.0 (Official) for x86_64 -diff --git a/third_party/python/distro/tests/resources/distros/mandriva2011/etc/mandrakelinux-release b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/mandrakelinux-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/mandrakelinux-release -@@ -0,0 +1,1 @@ -+Mandriva Linux release 2011.0 (Official) for x86_64 -diff --git a/third_party/python/distro/tests/resources/distros/mandriva2011/etc/mandriva-release b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/mandriva-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/mandriva-release -@@ -0,0 +1,1 @@ -+Mandriva Linux release 2011.0 (Official) for x86_64 -diff --git a/third_party/python/distro/tests/resources/distros/mandriva2011/etc/redhat-release b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/redhat-release -@@ -0,0 +1,1 @@ -+Mandriva Linux release 2011.0 (Official) for x86_64 -diff --git a/third_party/python/distro/tests/resources/distros/mandriva2011/etc/release b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/release -@@ -0,0 +1,1 @@ -+Mandriva Linux release 2011.0 (Official) for x86_64 -diff --git a/third_party/python/distro/tests/resources/distros/mandriva2011/etc/version b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/version -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/mandriva2011/etc/version -@@ -0,0 +1,1 @@ -+2011.0.0 2 cooker -diff --git a/third_party/python/distro/tests/resources/distros/manjaro1512/bin/lsb_release b/third_party/python/distro/tests/resources/distros/manjaro1512/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/manjaro1512/bin/lsb_release -@@ -0,0 +1,43 @@ -+#!/bin/bash -+# -+# lsb_release command for testing the ld module. -+# Only the -a option is supported. -+# -+# This version of the lsb_release command reads an lsb-release file. -+# -+# The lsb-release file has the usual format, e.g.: -+# DISTRIB_ID=Ubuntu -+# DISTRIB_RELEASE=14.04 -+# DISTRIB_CODENAME=trusty -+# DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS" -+# Where each line is optional. If a line is missing, the default value -+# will be the empty string. -+# -+ -+if [[ "$@" != "-a" ]]; then -+ echo "Usage: lsb_release -a" -+ exit 2 -+fi -+ -+# Because the PATH is set to just this directory, we cannot use 'dirname' -+# or other external programs, but need to use built-in abilities of bash. -+LSB_FILE="${0%/*}/../etc/lsb-release" -+ -+if [[ ! -f $LSB_FILE ]]; then -+ echo "Error: LSB release file does not exist: $LSB_FILE" -+ exit 1 -+fi -+ -+source $LSB_FILE -+ -+if [[ -n $LSB_VERSION ]]; then -+ echo "LSB Version: $LSB_VERSION" -+else -+ echo "No LSB modules are available." -+fi -+echo "Distributor ID: ${DISTRIB_ID:-}" -+echo "Description: ${DISTRIB_DESCRIPTION:-}" -+echo "Release: ${DISTRIB_RELEASE:-}" -+echo "Codename: ${DISTRIB_CODENAME:-}" -+ -+exit 0 -diff --git a/third_party/python/distro/tests/resources/distros/manjaro1512/etc/lsb-release b/third_party/python/distro/tests/resources/distros/manjaro1512/etc/lsb-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/manjaro1512/etc/lsb-release -@@ -0,0 +1,4 @@ -+DISTRIB_ID=ManjaroLinux -+DISTRIB_RELEASE=15.12 -+DISTRIB_CODENAME=Capella -+DISTRIB_DESCRIPTION="Manjaro Linux" -diff --git a/third_party/python/distro/tests/resources/distros/manjaro1512/etc/manjaro-release b/third_party/python/distro/tests/resources/distros/manjaro1512/etc/manjaro-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/manjaro1512/etc/manjaro-release -@@ -0,0 +1,1 @@ -+Manjaro Linux -diff --git a/third_party/python/distro/tests/resources/distros/manjaro1512/etc/os-release b/third_party/python/distro/tests/resources/distros/manjaro1512/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/manjaro1512/etc/os-release -@@ -0,0 +1,7 @@ -+NAME="Manjaro Linux" -+ID=manjaro -+PRETTY_NAME="Manjaro Linux" -+ANSI_COLOR="1;32" -+HOME_URL="http://www.manjaro.org/" -+SUPPORT_URL="http://www.manjaro.org/" -+BUG_REPORT_URL="http://bugs.manjaro.org/" -diff --git a/third_party/python/distro/tests/resources/distros/netbsd711/bin/uname b/third_party/python/distro/tests/resources/distros/netbsd711/bin/uname -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/netbsd711/bin/uname -@@ -0,0 +1,4 @@ -+#!/bin/sh -+ -+echo "NetBSD 7.1.1" -+ -diff --git a/third_party/python/distro/tests/resources/distros/openbsd62/bin/uname b/third_party/python/distro/tests/resources/distros/openbsd62/bin/uname -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/openbsd62/bin/uname -@@ -0,0 +1,4 @@ -+#!/bin/sh -+ -+echo "OpenBSD 6.2" -+ -diff --git a/third_party/python/distro/tests/resources/distros/openelec6/etc/os-release b/third_party/python/distro/tests/resources/distros/openelec6/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/openelec6/etc/os-release -@@ -0,0 +1,9 @@ -+NAME="OpenELEC" -+VERSION="6.0.3" -+ID="openelec" -+VERSION_ID="6.0" -+PRETTY_NAME="OpenELEC (official) - Version: 6.0.3" -+HOME_URL="http://www.openelec.tv" -+BUG_REPORT_URL="https://github.com/OpenELEC/OpenELEC.tv" -+OPENELEC_ARCH="imx6.arm" -+OPENELEC_BUILD="official" -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/opensuse42/etc/SuSE-release b/third_party/python/distro/tests/resources/distros/opensuse42/etc/SuSE-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/opensuse42/etc/SuSE-release -@@ -0,0 +1,1 @@ -+openSUSE 42.1 (x86_64) -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/opensuse42/etc/os-release b/third_party/python/distro/tests/resources/distros/opensuse42/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/opensuse42/etc/os-release -@@ -0,0 +1,10 @@ -+NAME="openSUSE Leap" -+VERSION="42.1" -+VERSION_ID="42.1" -+PRETTY_NAME="openSUSE Leap 42.1 (x86_64)" -+ID=opensuse -+ANSI_COLOR="0;32" -+CPE_NAME="cpe:/o:opensuse:opensuse:42.1" -+BUG_REPORT_URL="https://bugs.opensuse.org" -+HOME_URL="https://opensuse.org/" -+ID_LIKE="suse" -diff --git a/third_party/python/distro/tests/resources/distros/oracle7/etc/oracle-release b/third_party/python/distro/tests/resources/distros/oracle7/etc/oracle-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/oracle7/etc/oracle-release -@@ -0,0 +1,1 @@ -+Oracle Linux Server release 7.5 -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/oracle7/etc/os-release b/third_party/python/distro/tests/resources/distros/oracle7/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/oracle7/etc/os-release -@@ -0,0 +1,14 @@ -+NAME="Oracle Linux Server" -+VERSION="7.5" -+ID="ol" -+VERSION_ID="7.5" -+PRETTY_NAME="Oracle Linux Server 7.5" -+ANSI_COLOR="0;31" -+CPE_NAME="cpe:/o:oracle:linux:7:5:server" -+HOME_URL="https://linux.oracle.com/" -+BUG_REPORT_URL="https://bugzilla.oracle.com/" -+ -+ORACLE_BUGZILLA_PRODUCT="Oracle Linux 7" -+ORACLE_BUGZILLA_PRODUCT_VERSION=7.5 -+ORACLE_SUPPORT_PRODUCT="Oracle Linux" -+ORACLE_SUPPORT_PRODUCT_VERSION=7.5 -diff --git a/third_party/python/distro/tests/resources/distros/raspbian7/etc/debian_version b/third_party/python/distro/tests/resources/distros/raspbian7/etc/debian_version -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/raspbian7/etc/debian_version -@@ -0,0 +1,1 @@ -+7.1 -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/raspbian7/etc/os-release b/third_party/python/distro/tests/resources/distros/raspbian7/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/raspbian7/etc/os-release -@@ -0,0 +1,10 @@ -+PRETTY_NAME="Raspbian GNU/Linux 7 (wheezy)" -+NAME="Raspbian GNU/Linux" -+VERSION_ID="7" -+VERSION="7 (wheezy)" -+ID=raspbian -+ID_LIKE=debian -+ANSI_COLOR="1;31" -+HOME_URL="http://www.raspbian.org/" -+SUPPORT_URL="http://www.raspbian.org/RaspbianForums" -+BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs" -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/raspbian7/etc/os-release.orig b/third_party/python/distro/tests/resources/distros/raspbian7/etc/os-release.orig -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/raspbian7/etc/os-release.orig -@@ -0,0 +1,9 @@ -+PRETTY_NAME="Debian #OSNAME# 7 (wheezy)" -+NAME="Debian #OSNAME#" -+VERSION_ID="7" -+VERSION="7 (wheezy)" -+ID=debian -+ANSI_COLOR="1;31" -+HOME_URL="http://www.debian.org/" -+SUPPORT_URL="http://www.debian.org/support/" -+BUG_REPORT_URL="http://bugs.debian.org/" -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/raspbian8/etc/debian_version b/third_party/python/distro/tests/resources/distros/raspbian8/etc/debian_version -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/raspbian8/etc/debian_version -@@ -0,0 +1,1 @@ -+8.0 -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/raspbian8/etc/os-release b/third_party/python/distro/tests/resources/distros/raspbian8/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/raspbian8/etc/os-release -@@ -0,0 +1,9 @@ -+PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)" -+NAME="Raspbian GNU/Linux" -+VERSION_ID="8" -+VERSION="8 (jessie)" -+ID=raspbian -+ID_LIKE=debian -+HOME_URL="http://www.raspbian.org/" -+SUPPORT_URL="http://www.raspbian.org/RaspbianForums" -+BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs" -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/rhel5/etc/redhat-release b/third_party/python/distro/tests/resources/distros/rhel5/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/rhel5/etc/redhat-release -@@ -0,0 +1,1 @@ -+Red Hat Enterprise Linux Server release 5.11 (Tikanga) -diff --git a/third_party/python/distro/tests/resources/distros/rhel6/etc/redhat-release b/third_party/python/distro/tests/resources/distros/rhel6/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/rhel6/etc/redhat-release -@@ -0,0 +1,1 @@ -+Red Hat Enterprise Linux Server release 6.5 (Santiago) -diff --git a/third_party/python/distro/tests/resources/distros/rhel6/etc/system-release b/third_party/python/distro/tests/resources/distros/rhel6/etc/system-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/rhel6/etc/system-release -@@ -0,0 +1,1 @@ -+Red Hat Enterprise Linux Server release 6.5 (Santiago) -diff --git a/third_party/python/distro/tests/resources/distros/rhel7/etc/os-release b/third_party/python/distro/tests/resources/distros/rhel7/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/rhel7/etc/os-release -@@ -0,0 +1,15 @@ -+NAME="Red Hat Enterprise Linux Server" -+VERSION="7.0 (Maipo)" -+ID="rhel" -+ID_LIKE="fedora" -+VERSION_ID="7.0" -+PRETTY_NAME="Red Hat Enterprise Linux Server 7.0 (Maipo)" -+ANSI_COLOR="0;31" -+CPE_NAME="cpe:/o:redhat:enterprise_linux:7.0:GA:server" -+HOME_URL="https://www.redhat.com/" -+BUG_REPORT_URL="https://bugzilla.redhat.com/" -+ -+REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7" -+REDHAT_BUGZILLA_PRODUCT_VERSION=7.0 -+REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" -+REDHAT_SUPPORT_PRODUCT_VERSION=7.0 -diff --git a/third_party/python/distro/tests/resources/distros/rhel7/etc/redhat-release b/third_party/python/distro/tests/resources/distros/rhel7/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/rhel7/etc/redhat-release -@@ -0,0 +1,1 @@ -+Red Hat Enterprise Linux Server release 7.0 (Maipo) -diff --git a/third_party/python/distro/tests/resources/distros/rhel7/etc/system-release b/third_party/python/distro/tests/resources/distros/rhel7/etc/system-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/rhel7/etc/system-release -@@ -0,0 +1,1 @@ -+Red Hat Enterprise Linux Server release 7.0 (Maipo) -diff --git a/third_party/python/distro/tests/resources/distros/scientific6/etc/redhat-release b/third_party/python/distro/tests/resources/distros/scientific6/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/scientific6/etc/redhat-release -@@ -0,0 +1,1 @@ -+Scientific Linux release 6.4 (Carbon) -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/scientific6/etc/system-release b/third_party/python/distro/tests/resources/distros/scientific6/etc/system-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/scientific6/etc/system-release -@@ -0,0 +1,1 @@ -+Scientific Linux release 6.4 (Carbon) -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/scientific7/etc/os-release b/third_party/python/distro/tests/resources/distros/scientific7/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/scientific7/etc/os-release -@@ -0,0 +1,15 @@ -+NAME="Scientific Linux" -+VERSION="7.2 (Nitrogen)" -+ID="rhel" -+ID_LIKE="fedora" -+VERSION_ID="7.2" -+PRETTY_NAME="Scientific Linux 7.2 (Nitrogen)" -+ANSI_COLOR="0;31" -+CPE_NAME="cpe:/o:scientificlinux:scientificlinux:7.2:GA" -+HOME_URL="http://www.scientificlinux.org//" -+BUG_REPORT_URL="mailto:scientific-linux-devel@listserv.fnal.gov" -+ -+REDHAT_BUGZILLA_PRODUCT="Scientific Linux 7" -+REDHAT_BUGZILLA_PRODUCT_VERSION=7.2 -+REDHAT_SUPPORT_PRODUCT="Scientific Linux" -+REDHAT_SUPPORT_PRODUCT_VERSION="7.2" -diff --git a/third_party/python/distro/tests/resources/distros/scientific7/etc/redhat-release b/third_party/python/distro/tests/resources/distros/scientific7/etc/redhat-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/scientific7/etc/redhat-release -@@ -0,0 +1,1 @@ -+Scientific Linux release 7.2 (Nitrogen) -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/scientific7/etc/sl-release b/third_party/python/distro/tests/resources/distros/scientific7/etc/sl-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/scientific7/etc/sl-release -@@ -0,0 +1,1 @@ -+Scientific Linux release 7.2 (Nitrogen) -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/scientific7/etc/system-release b/third_party/python/distro/tests/resources/distros/scientific7/etc/system-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/scientific7/etc/system-release -@@ -0,0 +1,1 @@ -+Scientific Linux release 7.2 (Nitrogen) -\ No newline at end of file -diff --git a/third_party/python/distro/tests/resources/distros/slackware14/etc/os-release b/third_party/python/distro/tests/resources/distros/slackware14/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/slackware14/etc/os-release -@@ -0,0 +1,10 @@ -+NAME=Slackware -+VERSION="14.1" -+ID=slackware -+VERSION_ID=14.1 -+PRETTY_NAME="Slackware 14.1" -+ANSI_COLOR="0;34" -+CPE_NAME="cpe:/o:slackware:slackware_linux:14.1" -+HOME_URL="http://slackware.com/" -+SUPPORT_URL="http://www.linuxquestions.org/questions/slackware-14/" -+BUG_REPORT_URL="http://www.linuxquestions.org/questions/slackware-14/" -diff --git a/third_party/python/distro/tests/resources/distros/slackware14/etc/slackware-version b/third_party/python/distro/tests/resources/distros/slackware14/etc/slackware-version -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/slackware14/etc/slackware-version -@@ -0,0 +1,1 @@ -+Slackware 14.1 -diff --git a/third_party/python/distro/tests/resources/distros/sles12/bin/lsb_release b/third_party/python/distro/tests/resources/distros/sles12/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/sles12/bin/lsb_release -@@ -0,0 +1,21 @@ -+#!/bin/bash -+# -+# lsb_release command for testing the ld module. -+# Only the -a option is supported. -+# -+# This version of the lsb_release command works without a corresponding -+# etc/lsb-release file. -+# -+ -+if [[ "$@" != "-a" ]]; then -+ echo "Usage: lsb_release -a" -+ exit 2 -+fi -+ -+echo "LSB Version: n/a" -+echo "Distributor ID: SUSE LINUX" -+echo "Description: SUSE Linux Enterprise Server 12 SP1" -+echo "Release: 12.1" -+echo "Codename: n/a" -+ -+exit 0 -diff --git a/third_party/python/distro/tests/resources/distros/sles12/etc/SuSE-release b/third_party/python/distro/tests/resources/distros/sles12/etc/SuSE-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/sles12/etc/SuSE-release -@@ -0,0 +1,5 @@ -+SUSE Linux Enterprise Server 12 (s390x) -+VERSION = 12 -+PATCHLEVEL = 1 -+# This file is deprecated and will be removed in a future service pack or release. -+# Please check /etc/os-release for details about this release. -diff --git a/third_party/python/distro/tests/resources/distros/sles12/etc/os-release b/third_party/python/distro/tests/resources/distros/sles12/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/sles12/etc/os-release -@@ -0,0 +1,7 @@ -+NAME="SLES" -+VERSION="12-SP1" -+VERSION_ID="12.1" -+PRETTY_NAME="SUSE Linux Enterprise Server 12 SP1" -+ID="sles" -+ANSI_COLOR="0;32" -+CPE_NAME="cpe:/o:suse:sles:12:sp1" -diff --git a/third_party/python/distro/tests/resources/distros/ubuntu14/bin/lsb_release b/third_party/python/distro/tests/resources/distros/ubuntu14/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/ubuntu14/bin/lsb_release -@@ -0,0 +1,39 @@ -+#!/bin/bash -+# -+# lsb_release command for testing the ld module. -+# Only the -a option is supported. -+# -+# This version of the lsb_release command reads an lsb-release file. -+# -+# The lsb-release file has the usual format, e.g.: -+# DISTRIB_ID=Ubuntu -+# DISTRIB_RELEASE=14.04 -+# DISTRIB_CODENAME=trusty -+# DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS" -+# Where each line is optional. If a line is missing, the default value -+# will be the empty string. -+# -+ -+if [[ "$@" != "-a" ]]; then -+ echo "Usage: lsb_release -a" -+ exit 2 -+fi -+ -+# Because the PATH is set to just this directory, we cannot use 'dirname' -+# or other external programs, but need to use built-in abilities of bash. -+LSB_FILE="${0%/*}/../etc/lsb-release" -+ -+if [[ ! -f $LSB_FILE ]]; then -+ echo "Error: LSB release file does not exist: $LSB_FILE" -+ exit 1 -+fi -+ -+source $LSB_FILE -+ -+echo "No LSB modules are available." -+echo "Distributor ID: ${DISTRIB_ID:-}" -+echo "Description: ${DISTRIB_DESCRIPTION:-}" -+echo "Release: ${DISTRIB_RELEASE:-}" -+echo "Codename: ${DISTRIB_CODENAME:-}" -+ -+exit 0 -diff --git a/third_party/python/distro/tests/resources/distros/ubuntu14/etc/debian_version b/third_party/python/distro/tests/resources/distros/ubuntu14/etc/debian_version -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/ubuntu14/etc/debian_version -@@ -0,0 +1,1 @@ -+jessie/sid -diff --git a/third_party/python/distro/tests/resources/distros/ubuntu14/etc/lsb-release b/third_party/python/distro/tests/resources/distros/ubuntu14/etc/lsb-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/ubuntu14/etc/lsb-release -@@ -0,0 +1,4 @@ -+DISTRIB_ID=Ubuntu -+DISTRIB_RELEASE=14.04 -+DISTRIB_CODENAME=trusty -+DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS" -diff --git a/third_party/python/distro/tests/resources/distros/ubuntu14/etc/os-release b/third_party/python/distro/tests/resources/distros/ubuntu14/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/ubuntu14/etc/os-release -@@ -0,0 +1,9 @@ -+NAME="Ubuntu" -+VERSION="14.04.3 LTS, Trusty Tahr" -+ID=ubuntu -+ID_LIKE=debian -+PRETTY_NAME="Ubuntu 14.04.3 LTS" -+VERSION_ID="14.04" -+HOME_URL="http://www.ubuntu.com/" -+SUPPORT_URL="http://help.ubuntu.com/" -+BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" -diff --git a/third_party/python/distro/tests/resources/distros/ubuntu16/bin/lsb_release b/third_party/python/distro/tests/resources/distros/ubuntu16/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/ubuntu16/bin/lsb_release -@@ -0,0 +1,39 @@ -+#!/bin/bash -+# -+# lsb_release command for testing the ld module. -+# Only the -a option is supported. -+# -+# This version of the lsb_release command reads an lsb-release file. -+# -+# The lsb-release file has the usual format, e.g.: -+# DISTRIB_ID=Ubuntu -+# DISTRIB_RELEASE=14.04 -+# DISTRIB_CODENAME=trusty -+# DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS" -+# Where each line is optional. If a line is missing, the default value -+# will be the empty string. -+# -+ -+if [[ "$@" != "-a" ]]; then -+ echo "Usage: lsb_release -a" -+ exit 2 -+fi -+ -+# Because the PATH is set to just this directory, we cannot use 'dirname' -+# or other external programs, but need to use built-in abilities of bash. -+LSB_FILE="${0%/*}/../etc/lsb-release" -+ -+if [[ ! -f $LSB_FILE ]]; then -+ echo "Error: LSB release file does not exist: $LSB_FILE" -+ exit 1 -+fi -+ -+source $LSB_FILE -+ -+echo "No LSB modules are available." -+echo "Distributor ID: ${DISTRIB_ID:-}" -+echo "Description: ${DISTRIB_DESCRIPTION:-}" -+echo "Release: ${DISTRIB_RELEASE:-}" -+echo "Codename: ${DISTRIB_CODENAME:-}" -+ -+exit 0 -diff --git a/third_party/python/distro/tests/resources/distros/ubuntu16/etc/debian_version b/third_party/python/distro/tests/resources/distros/ubuntu16/etc/debian_version -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/ubuntu16/etc/debian_version -@@ -0,0 +1,1 @@ -+stretch/sid -diff --git a/third_party/python/distro/tests/resources/distros/ubuntu16/etc/lsb-release b/third_party/python/distro/tests/resources/distros/ubuntu16/etc/lsb-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/ubuntu16/etc/lsb-release -@@ -0,0 +1,4 @@ -+DISTRIB_ID=Ubuntu -+DISTRIB_RELEASE=16.04 -+DISTRIB_CODENAME=xenial -+DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS" -diff --git a/third_party/python/distro/tests/resources/distros/ubuntu16/etc/os-release b/third_party/python/distro/tests/resources/distros/ubuntu16/etc/os-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/distros/ubuntu16/etc/os-release -@@ -0,0 +1,10 @@ -+NAME="Ubuntu" -+VERSION="16.04.1 LTS (Xenial Xerus)" -+ID=ubuntu -+ID_LIKE=debian -+PRETTY_NAME="Ubuntu 16.04.1 LTS" -+VERSION_ID="16.04" -+HOME_URL="http://www.ubuntu.com/" -+SUPPORT_URL="http://help.ubuntu.com/" -+BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" -+UBUNTU_CODENAME=xenial -diff --git a/third_party/python/distro/tests/resources/special/empty-release b/third_party/python/distro/tests/resources/special/empty-release -new file mode 100644 -diff --git a/third_party/python/distro/tests/resources/testdistros/distro/baduname/bin/uname b/third_party/python/distro/tests/resources/testdistros/distro/baduname/bin/uname -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/testdistros/distro/baduname/bin/uname -@@ -0,0 +1,2 @@ -+#!/bin/sh -+echo "I'm a bad uname file!" -diff --git a/third_party/python/distro/tests/resources/testdistros/distro/unknowndistro/etc/unknowndistro-release b/third_party/python/distro/tests/resources/testdistros/distro/unknowndistro/etc/unknowndistro-release -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/testdistros/distro/unknowndistro/etc/unknowndistro-release -@@ -0,0 +1,1 @@ -+Unknown Distro release 1.0 (Unknown Codename) -diff --git a/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc001/bin/lsb_release b/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc001/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc001/bin/lsb_release -@@ -0,0 +1,5 @@ -+#!/bin/bash -+rc=1 -+msg="General error" -+echo "Test failure - exiting with $rc ($msg)" -+exit $rc -diff --git a/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc002/bin/lsb_release b/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc002/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc002/bin/lsb_release -@@ -0,0 +1,5 @@ -+#!/bin/bash -+rc=2 -+msg="Misuse of shell builtins, or missing keyword or command" -+echo "Test failure - exiting with $rc ($msg)" -+exit $rc -diff --git a/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc126/bin/lsb_release b/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc126/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc126/bin/lsb_release -@@ -0,0 +1,5 @@ -+#!/bin/bash -+rc=126 -+msg="Cannot execute command" -+echo "Test failure - exiting with $rc ($msg)" -+exit $rc -diff --git a/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc130/bin/lsb_release b/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc130/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc130/bin/lsb_release -@@ -0,0 +1,5 @@ -+#!/bin/bash -+rc=130 -+msg="Signal 2 - Script terminated with Ctrl-C" -+echo "Test failure - exiting with $rc ($msg)" -+exit $rc -diff --git a/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc255/bin/lsb_release b/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc255/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/testdistros/lsb/lsb_rc255/bin/lsb_release -@@ -0,0 +1,5 @@ -+#!/bin/bash -+rc=255 -+msg="Exit code out of range" -+echo "Test failure - exiting with $rc ($msg)" -+exit $rc -diff --git a/third_party/python/distro/tests/resources/testdistros/lsb/ubuntu14_nomodules/bin/lsb_release b/third_party/python/distro/tests/resources/testdistros/lsb/ubuntu14_nomodules/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/testdistros/lsb/ubuntu14_nomodules/bin/lsb_release -@@ -0,0 +1,8 @@ -+#!/bin/bash -+/bin/cat <<'EOT' -+No LSB modules are available. -+Distributor ID: Ubuntu -+Description: Ubuntu 14.04.3 LTS -+Release: 14.04 -+Codename: trusty -+EOT -diff --git a/third_party/python/distro/tests/resources/testdistros/lsb/ubuntu14_normal/bin/lsb_release b/third_party/python/distro/tests/resources/testdistros/lsb/ubuntu14_normal/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/testdistros/lsb/ubuntu14_normal/bin/lsb_release -@@ -0,0 +1,7 @@ -+#!/bin/bash -+/bin/cat <<'EOT' -+Distributor ID: Ubuntu -+Description: Ubuntu 14.04.3 LTS -+Release: 14.04 -+Codename: trusty -+EOT -diff --git a/third_party/python/distro/tests/resources/testdistros/lsb/ubuntu14_trailingblanks/bin/lsb_release b/third_party/python/distro/tests/resources/testdistros/lsb/ubuntu14_trailingblanks/bin/lsb_release -new file mode 100755 ---- /dev/null -+++ b/third_party/python/distro/tests/resources/testdistros/lsb/ubuntu14_trailingblanks/bin/lsb_release -@@ -0,0 +1,8 @@ -+#!/bin/bash -+/bin/cat <<'EOT' -+No LSB modules are available. -+Distributor ID: Ubuntu -+Description: Ubuntu 14.04.3 LTS -+Release: 14.04 -+Codename: trusty -+EOT -diff --git a/third_party/python/distro/tests/test_distro.py b/third_party/python/distro/tests/test_distro.py -new file mode 100644 ---- /dev/null -+++ b/third_party/python/distro/tests/test_distro.py -@@ -0,0 +1,2062 @@ -+# Copyright 2015,2016 Nir Cohen -+# -+# Licensed under the Apache License, Version 2.0 (the "License"); -+# you may not use this file except in compliance with the License. -+# You may obtain a copy of the License at -+# -+# http://www.apache.org/licenses/LICENSE-2.0 -+# -+# Unless required by applicable law or agreed to in writing, software -+# distributed under the License is distributed on an "AS IS" BASIS, -+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+# See the License for the specific language governing permissions and -+# limitations under the License. -+ -+import os -+import sys -+import ast -+import subprocess -+try: -+ from StringIO import StringIO # Python 2.x -+except ImportError: -+ from io import StringIO # Python 3.x -+ -+import pytest -+ -+ -+BASE = os.path.abspath(os.path.dirname(__file__)) -+RESOURCES = os.path.join(BASE, 'resources') -+DISTROS_DIR = os.path.join(RESOURCES, 'distros') -+TESTDISTROS = os.path.join(RESOURCES, 'testdistros') -+SPECIAL = os.path.join(RESOURCES, 'special') -+DISTROS = [dist for dist in os.listdir(DISTROS_DIR) if dist != '__shared__'] -+ -+ -+IS_LINUX = sys.platform.startswith('linux') -+if IS_LINUX: -+ import distro -+ -+ RELATIVE_UNIXCONFDIR = distro._UNIXCONFDIR[1:] -+ MODULE_DISTRO = distro._distro -+ -+ -+class TestNonLinuxPlatform: -+ """Obviously, this only tests Windows. Will add OS X tests on Travis -+ Later -+ """ -+ -+ def test_cant_use_on_windows(self): -+ try: -+ import distro # NOQA -+ except ImportError as ex: -+ assert 'Unsupported platform' in str(ex) -+ -+ -+@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') -+class TestCli: -+ -+ def _parse(self, command): -+ sys.argv = command.split() -+ distro.main() -+ -+ def _run(self, command): -+ stdout, _ = subprocess.Popen( -+ command, -+ stdout=subprocess.PIPE, -+ stderr=subprocess.PIPE).communicate() -+ # Need to decode or we get bytes in Python 3.x -+ return stdout.decode('utf-8') -+ -+ def test_cli_for_coverage_yuch(self): -+ self._parse('distro') -+ self._parse('distro -j') -+ -+ def test_cli(self): -+ command = [sys.executable, '-m', 'distro'] -+ desired_output = 'Name: ' + distro.name(pretty=True) -+ distro_version = distro.version(pretty=True) -+ distro_codename = distro.codename() -+ desired_output += '\n' + 'Version: ' + distro_version -+ desired_output += '\n' + 'Codename: ' + distro_codename -+ desired_output += '\n' -+ assert self._run(command) == desired_output -+ -+ def test_cli_json(self): -+ command = [sys.executable, '-m', 'distro', '-j'] -+ assert ast.literal_eval(self._run(command)) == distro.info() -+ -+ -+@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') -+class DistroTestCase(object): -+ """A base class for any testcase classes that test the distributions -+ represented in the `DISTROS` subtree. -+ """ -+ -+ def setup_method(self, test_method): -+ # The environment stays the same across all testcases, so we -+ # save and restore the PATH env var in each test case that -+ # changes it: -+ self._saved_path = os.environ["PATH"] -+ self._saved_UNIXCONFDIR = distro._UNIXCONFDIR -+ -+ def teardown_method(self, test_method): -+ os.environ["PATH"] = self._saved_path -+ distro._UNIXCONFDIR = self._saved_UNIXCONFDIR -+ -+ def _setup_for_distro(self, distro_root): -+ distro_bin = os.path.join(distro_root, 'bin') -+ # We don't want to pick up a possibly present lsb_release in the -+ # distro that runs this test, so we use a PATH with only one entry: -+ os.environ["PATH"] = distro_bin -+ distro._UNIXCONFDIR = os.path.join(distro_root, RELATIVE_UNIXCONFDIR) -+ -+ -+@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') -+class TestOSRelease: -+ -+ def setup_method(self, test_method): -+ dist = test_method.__name__.split('_')[1] -+ os_release = os.path.join(DISTROS_DIR, dist, 'etc', 'os-release') -+ self.distro = distro.LinuxDistribution(False, os_release, 'non') -+ -+ def _test_outcome(self, outcome): -+ assert self.distro.id() == outcome.get('id', '') -+ assert self.distro.name() == outcome.get('name', '') -+ assert self.distro.name(pretty=True) == outcome.get('pretty_name', '') -+ assert self.distro.version() == outcome.get('version', '') -+ assert self.distro.version(pretty=True) == \ -+ outcome.get('pretty_version', '') -+ assert self.distro.version(best=True) == \ -+ outcome.get('best_version', '') -+ assert self.distro.like() == outcome.get('like', '') -+ assert self.distro.codename() == outcome.get('codename', '') -+ -+ def test_arch_os_release(self): -+ desired_outcome = { -+ 'id': 'arch', -+ 'name': 'Arch Linux', -+ 'pretty_name': 'Arch Linux', -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_kali_os_release(self): -+ desired_outcome = { -+ 'id': 'kali', -+ 'name': 'Kali GNU/Linux', -+ 'pretty_name': 'Kali GNU/Linux Rolling', -+ 'version': '2017.1', -+ 'pretty_version': '2017.1', -+ 'best_version': '2017.1', -+ 'like': 'debian' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_centos7_os_release(self): -+ desired_outcome = { -+ 'id': 'centos', -+ 'name': 'CentOS Linux', -+ 'pretty_name': 'CentOS Linux 7 (Core)', -+ 'version': '7', -+ 'pretty_version': '7 (Core)', -+ 'best_version': '7', -+ 'like': 'rhel fedora', -+ 'codename': 'Core' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_coreos_os_release(self): -+ desired_outcome = { -+ 'id': 'coreos', -+ 'name': 'CoreOS', -+ 'pretty_name': 'CoreOS 899.15.0', -+ 'version': '899.15.0', -+ 'pretty_version': '899.15.0', -+ 'best_version': '899.15.0' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_debian8_os_release(self): -+ desired_outcome = { -+ 'id': 'debian', -+ 'name': 'Debian GNU/Linux', -+ 'pretty_name': 'Debian GNU/Linux 8 (jessie)', -+ 'version': '8', -+ 'pretty_version': '8 (jessie)', -+ 'best_version': '8', -+ 'codename': 'jessie' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_fedora19_os_release(self): -+ desired_outcome = { -+ 'id': 'fedora', -+ 'name': 'Fedora', -+ 'pretty_name': u'Fedora 19 (Schr\u00F6dinger\u2019s Cat)', -+ 'version': '19', -+ 'pretty_version': u'19 (Schr\u00F6dinger\u2019s Cat)', -+ 'best_version': '19', -+ 'codename': u'Schr\u00F6dinger\u2019s Cat' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_fedora23_os_release(self): -+ desired_outcome = { -+ 'id': 'fedora', -+ 'name': 'Fedora', -+ 'pretty_name': 'Fedora 23 (Twenty Three)', -+ 'version': '23', -+ 'pretty_version': '23 (Twenty Three)', -+ 'best_version': '23', -+ 'codename': 'Twenty Three' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_fedora30_os_release(self): -+ # Fedora 21 and above no longer have code names but the metadata in os-release was only -+ # changed in a detectable way in Fedora 30+. The piece in parenthesis in the pretty_name -+ # field contains the VARIANT and differs depending on the variant which was installed. -+ desired_outcome = { -+ 'id': 'fedora', -+ 'name': 'Fedora', -+ 'pretty_name': 'Fedora 30 (Thirty)', -+ 'version': '30', -+ 'pretty_version': '30', -+ 'best_version': '30', -+ 'codename': '' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_kvmibm1_os_release(self): -+ desired_outcome = { -+ 'id': 'kvmibm', -+ 'name': 'KVM for IBM z Systems', -+ 'pretty_name': 'KVM for IBM z Systems 1.1.1 (Z)', -+ 'version': '1.1.1', -+ 'pretty_version': '1.1.1 (Z)', -+ 'best_version': '1.1.1', -+ 'like': 'rhel fedora', -+ 'codename': 'Z' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_linuxmint17_os_release(self): -+ # Note: LinuxMint 17 actually *does* have Ubuntu 14.04 data in its -+ # os-release file. See discussion in GitHub issue #78. -+ desired_outcome = { -+ 'id': 'ubuntu', -+ 'name': 'Ubuntu', -+ 'pretty_name': 'Ubuntu 14.04.3 LTS', -+ 'version': '14.04', -+ 'pretty_version': '14.04 (Trusty Tahr)', -+ 'best_version': '14.04.3', -+ 'like': 'debian', -+ 'codename': 'Trusty Tahr' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_mageia5_os_release(self): -+ desired_outcome = { -+ 'id': 'mageia', -+ 'name': 'Mageia', -+ 'pretty_name': 'Mageia 5', -+ 'version': '5', -+ 'pretty_version': '5', -+ 'best_version': '5', -+ 'like': 'mandriva fedora', -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_manjaro1512_os_release(self): -+ self._test_outcome({ -+ 'id': 'manjaro', -+ 'name': 'Manjaro Linux', -+ 'pretty_name': 'Manjaro Linux', -+ }) -+ -+ def test_opensuse42_os_release(self): -+ desired_outcome = { -+ 'id': 'opensuse', -+ 'name': 'openSUSE Leap', -+ 'pretty_name': 'openSUSE Leap 42.1 (x86_64)', -+ 'version': '42.1', -+ 'pretty_version': '42.1', -+ 'best_version': '42.1', -+ 'like': 'suse', -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_raspbian7_os_release(self): -+ desired_outcome = { -+ 'id': 'raspbian', -+ 'name': 'Raspbian GNU/Linux', -+ 'pretty_name': 'Raspbian GNU/Linux 7 (wheezy)', -+ 'version': '7', -+ 'pretty_version': '7 (wheezy)', -+ 'best_version': '7', -+ 'like': 'debian', -+ 'codename': 'wheezy' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_raspbian8_os_release(self): -+ desired_outcome = { -+ 'id': 'raspbian', -+ 'name': 'Raspbian GNU/Linux', -+ 'pretty_name': 'Raspbian GNU/Linux 8 (jessie)', -+ 'version': '8', -+ 'pretty_version': '8 (jessie)', -+ 'best_version': '8', -+ 'like': 'debian', -+ 'codename': 'jessie' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_rhel7_os_release(self): -+ desired_outcome = { -+ 'id': 'rhel', -+ 'name': 'Red Hat Enterprise Linux Server', -+ 'pretty_name': 'Red Hat Enterprise Linux Server 7.0 (Maipo)', -+ 'version': '7.0', -+ 'pretty_version': '7.0 (Maipo)', -+ 'best_version': '7.0', -+ 'like': 'fedora', -+ 'codename': 'Maipo' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_slackware14_os_release(self): -+ desired_outcome = { -+ 'id': 'slackware', -+ 'name': 'Slackware', -+ 'pretty_name': 'Slackware 14.1', -+ 'version': '14.1', -+ 'pretty_version': '14.1', -+ 'best_version': '14.1' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_sles12_os_release(self): -+ desired_outcome = { -+ 'id': 'sles', -+ 'name': 'SLES', -+ 'pretty_name': 'SUSE Linux Enterprise Server 12 SP1', -+ 'version': '12.1', -+ 'pretty_version': '12.1', -+ 'best_version': '12.1' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_ubuntu14_os_release(self): -+ desired_outcome = { -+ 'id': 'ubuntu', -+ 'name': 'Ubuntu', -+ 'pretty_name': 'Ubuntu 14.04.3 LTS', -+ 'version': '14.04', -+ 'pretty_version': '14.04 (Trusty Tahr)', -+ 'best_version': '14.04.3', -+ 'like': 'debian', -+ 'codename': 'Trusty Tahr' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_ubuntu16_os_release(self): -+ desired_outcome = { -+ 'id': 'ubuntu', -+ 'name': 'Ubuntu', -+ 'pretty_name': 'Ubuntu 16.04.1 LTS', -+ 'version': '16.04', -+ 'pretty_version': '16.04 (xenial)', -+ 'best_version': '16.04.1', -+ 'like': 'debian', -+ 'codename': 'xenial' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_amazon2016_os_release(self): -+ desired_outcome = { -+ 'id': 'amzn', -+ 'name': 'Amazon Linux AMI', -+ 'pretty_name': 'Amazon Linux AMI 2016.03', -+ 'version': '2016.03', -+ 'pretty_version': '2016.03', -+ 'best_version': '2016.03', -+ 'like': 'rhel fedora' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_scientific7_os_release(self): -+ desired_outcome = { -+ 'id': 'rhel', -+ 'name': 'Scientific Linux', -+ 'pretty_name': 'Scientific Linux 7.2 (Nitrogen)', -+ 'version': '7.2', -+ 'pretty_version': '7.2 (Nitrogen)', -+ 'best_version': '7.2', -+ 'like': 'fedora', -+ 'codename': 'Nitrogen' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_gentoo_os_release(self): -+ desired_outcome = { -+ 'id': 'gentoo', -+ 'name': 'Gentoo', -+ 'pretty_name': 'Gentoo/Linux', -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_openelec6_os_release(self): -+ desired_outcome = { -+ 'id': 'openelec', -+ 'name': 'OpenELEC', -+ 'pretty_name': 'OpenELEC (official) - Version: 6.0.3', -+ 'version': '6.0', -+ 'pretty_version': '6.0', -+ 'best_version': '6.0.3', -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_cloudlinux7_os_release(self): -+ desired_outcome = { -+ 'id': 'cloudlinux', -+ 'codename': 'Yury Malyshev', -+ 'name': 'CloudLinux', -+ 'pretty_name': 'CloudLinux 7.3 (Yury Malyshev)', -+ 'like': 'rhel fedora centos', -+ 'version': '7.3', -+ 'pretty_version': '7.3 (Yury Malyshev)', -+ 'best_version': '7.3', -+ 'major_version': '7', -+ 'minor_version': '3' -+ } -+ self._test_outcome(desired_outcome) -+ -+ -+@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') -+class TestLSBRelease(DistroTestCase): -+ -+ def setup_method(self, test_method): -+ super(TestLSBRelease, self).setup_method(test_method) -+ dist = test_method.__name__.split('_')[1] -+ self._setup_for_distro(os.path.join(DISTROS_DIR, dist)) -+ self.distro = distro.LinuxDistribution(True, 'non', 'non') -+ -+ def _test_outcome(self, outcome): -+ assert self.distro.id() == outcome.get('id', '') -+ assert self.distro.name() == outcome.get('name', '') -+ assert self.distro.name(pretty=True) == outcome.get('pretty_name', '') -+ assert self.distro.version() == outcome.get('version', '') -+ assert self.distro.version(pretty=True) == \ -+ outcome.get('pretty_version', '') -+ assert self.distro.version(best=True) == \ -+ outcome.get('best_version', '') -+ assert self.distro.like() == outcome.get('like', '') -+ assert self.distro.codename() == outcome.get('codename', '') -+ -+ def test_linuxmint17_lsb_release(self): -+ desired_outcome = { -+ 'id': 'linuxmint', -+ 'name': 'LinuxMint', -+ 'pretty_name': 'Linux Mint 17.3 Rosa', -+ 'version': '17.3', -+ 'pretty_version': '17.3 (rosa)', -+ 'best_version': '17.3', -+ 'codename': 'rosa' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_manjaro1512_lsb_release(self): -+ self._test_outcome({ -+ 'id': 'manjarolinux', -+ 'name': 'ManjaroLinux', -+ 'pretty_name': 'Manjaro Linux', -+ 'version': '15.12', -+ 'pretty_version': '15.12 (Capella)', -+ 'best_version': '15.12', -+ 'codename': 'Capella' -+ }) -+ -+ # @pytest.mark.xfail -+ # def test_openelec6_lsb_release(self): -+ # # TODO: This should be fixed as part of #109 when dealing -+ # # with distro inconsistencies -+ # desired_outcome = { -+ # 'id': 'openelec', -+ # 'name': 'OpenELEC', -+ # 'pretty_name': 'OpenELEC (official) - Version: 6.0.3', -+ # 'version': '6.0.3', -+ # 'pretty_version': '6.0.3', -+ # 'best_version': '6.0.3', -+ # } -+ # self._test_outcome(desired_outcome) -+ -+ def test_openbsd62_uname(self): -+ self._test_outcome({ -+ 'id': 'openbsd', -+ 'name': 'OpenBSD', -+ 'version': '6.2', -+ 'pretty_name': 'OpenBSD 6.2', -+ 'pretty_version': '6.2', -+ 'best_version': '6.2' -+ }) -+ -+ def test_netbsd711_uname(self): -+ self._test_outcome({ -+ 'id': 'netbsd', -+ 'name': 'NetBSD', -+ 'version': '7.1.1', -+ 'pretty_name': 'NetBSD 7.1.1', -+ 'pretty_version': '7.1.1', -+ 'best_version': '7.1.1' -+ }) -+ -+ def test_freebsd111_uname(self): -+ self._test_outcome({ -+ 'id': 'freebsd', -+ 'name': 'FreeBSD', -+ 'version': '11.1', -+ 'pretty_name': 'FreeBSD 11.1', -+ 'pretty_version': '11.1', -+ 'best_version': '11.1' -+ }) -+ -+ def test_ubuntu14normal_lsb_release(self): -+ self._setup_for_distro(os.path.join(TESTDISTROS, 'lsb', -+ 'ubuntu14_normal')) -+ -+ self.distro = distro.LinuxDistribution(True, 'non', 'non') -+ -+ desired_outcome = { -+ 'id': 'ubuntu', -+ 'name': 'Ubuntu', -+ 'pretty_name': 'Ubuntu 14.04.3 LTS', -+ 'version': '14.04', -+ 'pretty_version': '14.04 (trusty)', -+ 'best_version': '14.04.3', -+ 'codename': 'trusty' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_ubuntu14nomodules_lsb_release(self): -+ self._setup_for_distro(os.path.join(TESTDISTROS, 'lsb', -+ 'ubuntu14_nomodules')) -+ -+ self.distro = distro.LinuxDistribution(True, 'non', 'non') -+ -+ desired_outcome = { -+ 'id': 'ubuntu', -+ 'name': 'Ubuntu', -+ 'pretty_name': 'Ubuntu 14.04.3 LTS', -+ 'version': '14.04', -+ 'pretty_version': '14.04 (trusty)', -+ 'best_version': '14.04.3', -+ 'codename': 'trusty' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_trailingblanks_lsb_release(self): -+ self._setup_for_distro(os.path.join(TESTDISTROS, 'lsb', -+ 'ubuntu14_trailingblanks')) -+ -+ self.distro = distro.LinuxDistribution(True, 'non', 'non') -+ -+ desired_outcome = { -+ 'id': 'ubuntu', -+ 'name': 'Ubuntu', -+ 'pretty_name': 'Ubuntu 14.04.3 LTS', -+ 'version': '14.04', -+ 'pretty_version': '14.04 (trusty)', -+ 'best_version': '14.04.3', -+ 'codename': 'trusty' -+ } -+ self._test_outcome(desired_outcome) -+ -+ @pytest.mark.parametrize('errnum', ('001', '002', '126', '130', '255')) -+ def test_lsb_release_error_level(self, errnum): -+ self._setup_for_distro(os.path.join( -+ TESTDISTROS, 'lsb', 'lsb_rc{0}'.format(errnum))) -+ with pytest.raises(subprocess.CalledProcessError) as excinfo: -+ distro.LinuxDistribution(True, 'non', 'non')._lsb_release_info -+ assert excinfo.value.returncode == int(errnum) -+ -+ -+@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') -+class TestSpecialRelease(DistroTestCase): -+ def _test_outcome(self, outcome): -+ assert self.distro.id() == outcome.get('id', '') -+ assert self.distro.name() == outcome.get('name', '') -+ assert self.distro.name(pretty=True) == outcome.get('pretty_name', '') -+ assert self.distro.version() == outcome.get('version', '') -+ assert self.distro.version(pretty=True) == \ -+ outcome.get('pretty_version', '') -+ assert self.distro.version(best=True) == \ -+ outcome.get('best_version', '') -+ assert self.distro.like() == outcome.get('like', '') -+ assert self.distro.codename() == outcome.get('codename', '') -+ assert self.distro.major_version() == outcome.get('major_version', '') -+ assert self.distro.minor_version() == outcome.get('minor_version', '') -+ assert self.distro.build_number() == outcome.get('build_number', '') -+ -+ def test_empty_release(self): -+ distro_release = os.path.join(SPECIAL, 'empty-release') -+ self.distro = distro.LinuxDistribution(False, 'non', distro_release) -+ -+ desired_outcome = { -+ 'id': 'empty' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_unknowndistro_release(self): -+ self._setup_for_distro(os.path.join(TESTDISTROS, 'distro', -+ 'unknowndistro')) -+ -+ self.distro = distro.LinuxDistribution() -+ -+ desired_outcome = { -+ 'id': 'unknowndistro', -+ 'name': 'Unknown Distro', -+ 'pretty_name': 'Unknown Distro 1.0 (Unknown Codename)', -+ 'version': '1.0', -+ 'pretty_version': '1.0 (Unknown Codename)', -+ 'best_version': '1.0', -+ 'codename': 'Unknown Codename', -+ 'major_version': '1', -+ 'minor_version': '0' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_bad_uname(self): -+ self._setup_for_distro(os.path.join(TESTDISTROS, 'distro', -+ 'baduname')) -+ self.distro = distro.LinuxDistribution() -+ -+ assert self.distro.uname_attr('id') == '' -+ assert self.distro.uname_attr('name') == '' -+ assert self.distro.uname_attr('release') == '' -+ -+ -+@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') -+class TestDistroRelease: -+ -+ def _test_outcome(self, -+ outcome, -+ distro_name='', -+ version='', -+ release_file_id='', -+ release_file_suffix='release'): -+ release_file_id = release_file_id or distro_name -+ distro_release = os.path.join( -+ DISTROS_DIR, distro_name + version, 'etc', '{0}-{1}'.format( -+ release_file_id, release_file_suffix)) -+ self.distro = distro.LinuxDistribution(False, 'non', distro_release) -+ -+ assert self.distro.id() == outcome.get('id', '') -+ assert self.distro.name() == outcome.get('name', '') -+ assert self.distro.name(pretty=True) == outcome.get('pretty_name', '') -+ assert self.distro.version() == outcome.get('version', '') -+ assert self.distro.version(pretty=True) == \ -+ outcome.get('pretty_version', '') -+ assert self.distro.version(best=True) == \ -+ outcome.get('best_version', '') -+ assert self.distro.like() == outcome.get('like', '') -+ assert self.distro.codename() == outcome.get('codename', '') -+ assert self.distro.major_version() == outcome.get('major_version', '') -+ assert self.distro.minor_version() == outcome.get('minor_version', '') -+ assert self.distro.build_number() == outcome.get('build_number', '') -+ -+ def test_arch_dist_release(self): -+ desired_outcome = { -+ 'id': 'arch' -+ } -+ self._test_outcome(desired_outcome, 'arch') -+ -+ def test_centos5_dist_release(self): -+ desired_outcome = { -+ 'id': 'centos', -+ 'name': 'CentOS', -+ 'pretty_name': 'CentOS 5.11 (Final)', -+ 'version': '5.11', -+ 'pretty_version': '5.11 (Final)', -+ 'best_version': '5.11', -+ 'codename': 'Final', -+ 'major_version': '5', -+ 'minor_version': '11' -+ } -+ self._test_outcome(desired_outcome, 'centos', '5') -+ -+ def test_centos7_dist_release(self): -+ desired_outcome = { -+ 'id': 'centos', -+ 'name': 'CentOS Linux', -+ 'pretty_name': 'CentOS Linux 7.1.1503 (Core)', -+ 'version': '7.1.1503', -+ 'pretty_version': '7.1.1503 (Core)', -+ 'best_version': '7.1.1503', -+ 'codename': 'Core', -+ 'major_version': '7', -+ 'minor_version': '1', -+ 'build_number': '1503' -+ } -+ self._test_outcome(desired_outcome, 'centos', '7') -+ -+ def test_fedora19_dist_release(self): -+ desired_outcome = { -+ 'id': 'fedora', -+ 'name': 'Fedora', -+ 'pretty_name': u'Fedora 19 (Schr\u00F6dinger\u2019s Cat)', -+ 'version': '19', -+ 'pretty_version': u'19 (Schr\u00F6dinger\u2019s Cat)', -+ 'best_version': '19', -+ 'codename': u'Schr\u00F6dinger\u2019s Cat', -+ 'major_version': '19' -+ } -+ self._test_outcome(desired_outcome, 'fedora', '19') -+ -+ def test_fedora23_dist_release(self): -+ desired_outcome = { -+ 'id': 'fedora', -+ 'name': 'Fedora', -+ 'pretty_name': 'Fedora 23 (Twenty Three)', -+ 'version': '23', -+ 'pretty_version': '23 (Twenty Three)', -+ 'best_version': '23', -+ 'codename': 'Twenty Three', -+ 'major_version': '23' -+ } -+ self._test_outcome(desired_outcome, 'fedora', '23') -+ -+ def test_fedora30_dist_release(self): -+ desired_outcome = { -+ 'id': 'fedora', -+ 'name': 'Fedora', -+ 'pretty_name': 'Fedora 30 (Thirty)', -+ 'version': '30', -+ 'pretty_version': '30 (Thirty)', -+ 'best_version': '30', -+ 'codename': 'Thirty', -+ 'major_version': '30' -+ } -+ self._test_outcome(desired_outcome, 'fedora', '30') -+ -+ def test_gentoo_dist_release(self): -+ desired_outcome = { -+ 'id': 'gentoo', -+ 'name': 'Gentoo Base System', -+ 'pretty_name': 'Gentoo Base System 2.2', -+ 'version': '2.2', -+ 'pretty_version': '2.2', -+ 'best_version': '2.2', -+ 'major_version': '2', -+ 'minor_version': '2', -+ } -+ self._test_outcome(desired_outcome, 'gentoo') -+ -+ def test_kvmibm1_dist_release(self): -+ desired_outcome = { -+ 'id': 'base', -+ 'name': 'KVM for IBM z Systems', -+ 'pretty_name': 'KVM for IBM z Systems 1.1.1 (Z)', -+ 'version': '1.1.1', -+ 'pretty_version': '1.1.1 (Z)', -+ 'best_version': '1.1.1', -+ 'codename': 'Z', -+ 'major_version': '1', -+ 'minor_version': '1', -+ 'build_number': '1' -+ } -+ self._test_outcome(desired_outcome, 'kvmibm', '1', 'base') -+ -+ def test_mageia5_dist_release(self): -+ desired_outcome = { -+ 'id': 'mageia', -+ 'name': 'Mageia', -+ 'pretty_name': 'Mageia 5 (Official)', -+ 'version': '5', -+ 'pretty_version': '5 (Official)', -+ 'best_version': '5', -+ 'codename': 'Official', -+ 'major_version': '5' -+ } -+ self._test_outcome(desired_outcome, 'mageia', '5') -+ -+ def test_manjaro1512_dist_release(self): -+ self._test_outcome({ -+ 'id': 'manjaro', -+ 'name': 'Manjaro Linux', -+ 'pretty_name': 'Manjaro Linux', -+ 'version': '', -+ 'codename': '' -+ }, 'manjaro', '1512') -+ -+ def test_opensuse42_dist_release(self): -+ desired_outcome = { -+ 'id': 'suse', -+ 'name': 'openSUSE', -+ 'pretty_name': 'openSUSE 42.1 (x86_64)', -+ 'version': '42.1', -+ 'pretty_version': '42.1 (x86_64)', -+ 'best_version': '42.1', -+ 'codename': 'x86_64', -+ 'major_version': '42', -+ 'minor_version': '1' -+ } -+ self._test_outcome(desired_outcome, 'opensuse', '42', 'SuSE') -+ -+ def test_oracle7_dist_release(self): -+ desired_outcome = { -+ 'id': 'oracle', -+ 'name': 'Oracle Linux Server', -+ 'pretty_name': 'Oracle Linux Server 7.5', -+ 'version': '7.5', -+ 'pretty_version': '7.5', -+ 'best_version': '7.5', -+ 'major_version': '7', -+ 'minor_version': '5' -+ } -+ self._test_outcome(desired_outcome, 'oracle', '7') -+ -+ def test_rhel6_dist_release(self): -+ desired_outcome = { -+ 'id': 'rhel', -+ 'name': 'Red Hat Enterprise Linux Server', -+ 'pretty_name': 'Red Hat Enterprise Linux Server 6.5 (Santiago)', -+ 'version': '6.5', -+ 'pretty_version': '6.5 (Santiago)', -+ 'best_version': '6.5', -+ 'codename': 'Santiago', -+ 'major_version': '6', -+ 'minor_version': '5' -+ } -+ self._test_outcome(desired_outcome, 'rhel', '6', 'redhat') -+ -+ def test_rhel7_dist_release(self): -+ desired_outcome = { -+ 'id': 'rhel', -+ 'name': 'Red Hat Enterprise Linux Server', -+ 'pretty_name': 'Red Hat Enterprise Linux Server 7.0 (Maipo)', -+ 'version': '7.0', -+ 'pretty_version': '7.0 (Maipo)', -+ 'best_version': '7.0', -+ 'codename': 'Maipo', -+ 'major_version': '7', -+ 'minor_version': '0' -+ } -+ self._test_outcome(desired_outcome, 'rhel', '7', 'redhat') -+ -+ def test_slackware14_dist_release(self): -+ desired_outcome = { -+ 'id': 'slackware', -+ 'name': 'Slackware', -+ 'pretty_name': 'Slackware 14.1', -+ 'version': '14.1', -+ 'pretty_version': '14.1', -+ 'best_version': '14.1', -+ 'major_version': '14', -+ 'minor_version': '1' -+ } -+ self._test_outcome( -+ desired_outcome, -+ 'slackware', -+ '14', -+ release_file_suffix='version') -+ -+ def test_sles12_dist_release(self): -+ desired_outcome = { -+ 'id': 'suse', -+ 'name': 'SUSE Linux Enterprise Server', -+ 'pretty_name': 'SUSE Linux Enterprise Server 12 (s390x)', -+ 'version': '12', -+ 'pretty_version': '12 (s390x)', -+ 'best_version': '12', -+ 'major_version': '12', -+ 'codename': 's390x' -+ } -+ self._test_outcome(desired_outcome, 'sles', '12', 'SuSE') -+ -+ def test_cloudlinux5_dist_release(self): -+ # Uses redhat-release only to get information. -+ # The id of 'rhel' can only be fixed with issue #109. -+ desired_outcome = { -+ 'id': 'cloudlinux', -+ 'codename': 'Vladislav Volkov', -+ 'name': 'CloudLinux Server', -+ 'pretty_name': 'CloudLinux Server 5.11 (Vladislav Volkov)', -+ 'version': '5.11', -+ 'pretty_version': '5.11 (Vladislav Volkov)', -+ 'best_version': '5.11', -+ 'major_version': '5', -+ 'minor_version': '11' -+ } -+ self._test_outcome(desired_outcome, 'cloudlinux', '5', 'redhat') -+ -+ def test_cloudlinux6_dist_release(self): -+ # Same as above, only has redhat-release. -+ desired_outcome = { -+ 'id': 'cloudlinux', -+ 'codename': 'Oleg Makarov', -+ 'name': 'CloudLinux Server', -+ 'pretty_name': 'CloudLinux Server 6.8 (Oleg Makarov)', -+ 'version': '6.8', -+ 'pretty_version': '6.8 (Oleg Makarov)', -+ 'best_version': '6.8', -+ 'major_version': '6', -+ 'minor_version': '8' -+ } -+ self._test_outcome(desired_outcome, 'cloudlinux', '6', 'redhat') -+ -+ def test_cloudlinux7_dist_release(self): -+ desired_outcome = { -+ 'id': 'cloudlinux', -+ 'codename': 'Yury Malyshev', -+ 'name': 'CloudLinux', -+ 'pretty_name': 'CloudLinux 7.3 (Yury Malyshev)', -+ 'version': '7.3', -+ 'pretty_version': '7.3 (Yury Malyshev)', -+ 'best_version': '7.3', -+ 'major_version': '7', -+ 'minor_version': '3' -+ } -+ self._test_outcome(desired_outcome, 'cloudlinux', '7', 'redhat') -+ -+ -+@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') -+class TestOverall(DistroTestCase): -+ """Test a LinuxDistribution object created with default arguments. -+ -+ The direct accessor functions on that object are tested (e.g. `id()`); they -+ implement the precedence between the different sources of information. -+ -+ In addition, because the distro release file is searched when not -+ specified, the information resulting from the distro release file is also -+ tested. The LSB and os-release sources are not tested again, because their -+ test is already done in TestLSBRelease and TestOSRelease, and their -+ algorithm does not depend on whether or not the file is specified. -+ -+ TODO: This class should have testcases for all distros that are claimed -+ to be reliably maintained w.r.t. to their ID (see `id()`). Testcases for -+ the following distros are still missing: -+ * `amazon` - Amazon Linux -+ * `gentoo` - GenToo Linux -+ * `ibm_powerkvm` - IBM PowerKVM -+ * `parallels` - Parallels -+ * `pidora` - Pidora (Fedora remix for Raspberry Pi) -+ * `raspbian` - Raspbian -+ * `scientific` - Scientific Linux -+ * `xenserver` - XenServer -+ """ -+ -+ def setup_method(self, test_method): -+ super(TestOverall, self).setup_method(test_method) -+ dist = test_method.__name__.split('_')[1] -+ self._setup_for_distro(os.path.join(DISTROS_DIR, dist)) -+ self.distro = distro.LinuxDistribution() -+ -+ def _test_outcome(self, outcome): -+ assert self.distro.id() == outcome.get('id', '') -+ assert self.distro.name() == outcome.get('name', '') -+ assert self.distro.name(pretty=True) == outcome.get('pretty_name', '') -+ assert self.distro.version() == outcome.get('version', '') -+ assert self.distro.version(pretty=True) == \ -+ outcome.get('pretty_version', '') -+ assert self.distro.version(best=True) == \ -+ outcome.get('best_version', '') -+ assert self.distro.like() == outcome.get('like', '') -+ assert self.distro.codename() == outcome.get('codename', '') -+ assert self.distro.major_version() == outcome.get('major_version', '') -+ assert self.distro.minor_version() == outcome.get('minor_version', '') -+ assert self.distro.build_number() == outcome.get('build_number', '') -+ -+ def _test_non_existing_release_file(self): -+ # Test the info from the searched distro release file -+ # does not have one. -+ assert self.distro.distro_release_file == '' -+ assert len(self.distro.distro_release_info()) == 0 -+ -+ def _test_release_file_info(self, filename, outcome): -+ # Test the info from the searched distro release file -+ assert os.path.basename(self.distro.distro_release_file) == filename -+ distro_info = self.distro.distro_release_info() -+ for key, value in outcome.items(): -+ assert distro_info[key] == value -+ return distro_info -+ -+ def test_arch_release(self): -+ desired_outcome = { -+ 'id': 'arch', -+ 'name': 'Arch Linux', -+ 'pretty_name': 'Arch Linux', -+ } -+ self._test_outcome(desired_outcome) -+ -+ # Test the info from the searched distro release file -+ # Does not have one; The empty /etc/arch-release file is not -+ # considered a valid distro release file: -+ self._test_non_existing_release_file() -+ -+ def test_centos5_release(self): -+ desired_outcome = { -+ 'id': 'centos', -+ 'name': 'CentOS', -+ 'pretty_name': 'CentOS 5.11 (Final)', -+ 'version': '5.11', -+ 'pretty_version': '5.11 (Final)', -+ 'best_version': '5.11', -+ 'codename': 'Final', -+ 'major_version': '5', -+ 'minor_version': '11' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'centos', -+ 'name': 'CentOS', -+ 'version_id': '5.11', -+ 'codename': 'Final' -+ } -+ self._test_release_file_info('centos-release', desired_info) -+ -+ def test_centos7_release(self): -+ desired_outcome = { -+ 'id': 'centos', -+ 'name': 'CentOS Linux', -+ 'pretty_name': 'CentOS Linux 7 (Core)', -+ 'version': '7', -+ 'pretty_version': '7 (Core)', -+ 'best_version': '7.1.1503', -+ 'like': 'rhel fedora', -+ 'codename': 'Core', -+ 'major_version': '7' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'centos', -+ 'name': 'CentOS Linux', -+ 'version_id': '7.1.1503', -+ 'codename': 'Core' -+ } -+ self._test_release_file_info('centos-release', desired_info) -+ -+ def test_coreos_release(self): -+ desired_outcome = { -+ 'id': 'coreos', -+ 'name': 'CoreOS', -+ 'pretty_name': 'CoreOS 899.15.0', -+ 'version': '899.15.0', -+ 'pretty_version': '899.15.0', -+ 'best_version': '899.15.0', -+ 'major_version': '899', -+ 'minor_version': '15', -+ 'build_number': '0' -+ } -+ self._test_outcome(desired_outcome) -+ self._test_non_existing_release_file() -+ -+ def test_debian8_release(self): -+ desired_outcome = { -+ 'id': 'debian', -+ 'name': 'Debian GNU/Linux', -+ 'pretty_name': 'Debian GNU/Linux 8 (jessie)', -+ 'version': '8', -+ 'pretty_version': '8 (jessie)', -+ 'best_version': '8.2', -+ 'codename': 'jessie', -+ 'major_version': '8' -+ } -+ self._test_outcome(desired_outcome) -+ self._test_non_existing_release_file() -+ -+ def test_exherbo_release(self): -+ desired_outcome = { -+ 'id': 'exherbo', -+ 'name': 'Exherbo', -+ 'pretty_name': 'Exherbo Linux', -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_fedora19_release(self): -+ desired_outcome = { -+ 'id': 'fedora', -+ 'name': 'Fedora', -+ 'pretty_name': u'Fedora 19 (Schr\u00F6dinger\u2019s Cat)', -+ 'version': '19', -+ 'pretty_version': u'19 (Schr\u00F6dinger\u2019s Cat)', -+ 'best_version': '19', -+ 'codename': u'Schr\u00F6dinger\u2019s Cat', -+ 'major_version': '19' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'fedora', -+ 'name': 'Fedora', -+ 'version_id': '19', -+ 'codename': u'Schr\u00F6dinger\u2019s Cat' -+ } -+ self._test_release_file_info('fedora-release', desired_info) -+ -+ def test_fedora23_release(self): -+ desired_outcome = { -+ 'id': 'fedora', -+ 'name': 'Fedora', -+ 'pretty_name': 'Fedora 23 (Twenty Three)', -+ 'version': '23', -+ 'pretty_version': '23 (Twenty Three)', -+ 'best_version': '23', -+ 'codename': 'Twenty Three', -+ 'major_version': '23' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'fedora', -+ 'name': 'Fedora', -+ 'version_id': '23', -+ 'codename': 'Twenty Three' -+ } -+ self._test_release_file_info('fedora-release', desired_info) -+ -+ def test_fedora30_release(self): -+ desired_outcome = { -+ 'id': 'fedora', -+ 'name': 'Fedora', -+ 'pretty_name': 'Fedora 30 (Thirty)', -+ 'version': '30', -+ 'pretty_version': '30', -+ 'best_version': '30', -+ 'codename': '', -+ 'major_version': '30' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'fedora', -+ 'name': 'Fedora', -+ 'version_id': '30', -+ 'codename': 'Thirty' -+ } -+ self._test_release_file_info('fedora-release', desired_info) -+ -+ def test_kvmibm1_release(self): -+ desired_outcome = { -+ 'id': 'kvmibm', -+ 'name': 'KVM for IBM z Systems', -+ 'pretty_name': 'KVM for IBM z Systems 1.1.1 (Z)', -+ 'version': '1.1.1', -+ 'pretty_version': '1.1.1 (Z)', -+ 'best_version': '1.1.1', -+ 'like': 'rhel fedora', -+ 'codename': 'Z', -+ 'major_version': '1', -+ 'minor_version': '1', -+ 'build_number': '1' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'base', -+ 'name': 'KVM for IBM z Systems', -+ 'version_id': '1.1.1', -+ 'codename': 'Z' -+ } -+ self._test_release_file_info('base-release', desired_info) -+ -+ def test_linuxmint17_release(self): -+ desired_outcome = { -+ 'id': 'ubuntu', -+ 'name': 'Ubuntu', -+ 'pretty_name': 'Ubuntu 14.04.3 LTS', -+ 'version': '14.04', -+ 'pretty_version': '14.04 (Trusty Tahr)', -+ 'best_version': '14.04.3', -+ 'like': 'debian', -+ 'codename': 'Trusty Tahr', -+ 'major_version': '14', -+ 'minor_version': '04' -+ } -+ self._test_outcome(desired_outcome) -+ self._test_non_existing_release_file() -+ -+ def test_mageia5_release(self): -+ desired_outcome = { -+ 'id': 'mageia', -+ 'name': 'Mageia', -+ 'pretty_name': 'Mageia 5', -+ 'version': '5', -+ 'pretty_version': '5 (thornicroft)', -+ 'best_version': '5', -+ 'like': 'mandriva fedora', -+ # TODO: Codename differs between distro release and lsb_release. -+ 'codename': 'thornicroft', -+ 'major_version': '5' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'mageia', -+ 'name': 'Mageia', -+ 'version_id': '5', -+ 'codename': 'Official' -+ } -+ self._test_release_file_info('mageia-release', desired_info) -+ -+ def test_manjaro1512_release(self): -+ self._test_outcome({ -+ 'id': 'manjaro', -+ 'name': 'Manjaro Linux', -+ 'pretty_name': 'Manjaro Linux', -+ 'version': '15.12', -+ 'pretty_version': '15.12 (Capella)', -+ 'best_version': '15.12', -+ 'major_version': '15', -+ 'minor_version': '12', -+ 'codename': 'Capella' -+ }) -+ -+ self._test_release_file_info( -+ 'manjaro-release', -+ {'id': 'manjaro', -+ 'name': 'Manjaro Linux'}) -+ -+ def test_opensuse42_release(self): -+ desired_outcome = { -+ 'id': 'opensuse', -+ 'name': 'openSUSE Leap', -+ 'pretty_name': 'openSUSE Leap 42.1 (x86_64)', -+ 'version': '42.1', -+ 'pretty_version': '42.1 (x86_64)', -+ 'best_version': '42.1', -+ 'like': 'suse', -+ 'codename': 'x86_64', -+ 'major_version': '42', -+ 'minor_version': '1' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'SuSE', -+ 'name': 'openSUSE', -+ 'version_id': '42.1', -+ 'codename': 'x86_64' -+ } -+ self._test_release_file_info('SuSE-release', desired_info) -+ -+ def test_oracle7_release(self): -+ desired_outcome = { -+ 'id': 'oracle', -+ 'name': 'Oracle Linux Server', -+ 'pretty_name': 'Oracle Linux Server 7.5', -+ 'version': '7.5', -+ 'pretty_version': '7.5', -+ 'best_version': '7.5', -+ 'major_version': '7', -+ 'minor_version': '5' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'oracle', -+ 'name': 'Oracle Linux Server', -+ 'version_id': '7.5', -+ } -+ distro_info = self._test_release_file_info( -+ 'oracle-release', desired_info) -+ assert 'codename' not in distro_info -+ -+ def test_raspbian7_release(self): -+ desired_outcome = { -+ 'id': 'raspbian', -+ 'name': 'Raspbian GNU/Linux', -+ 'pretty_name': 'Raspbian GNU/Linux 7 (wheezy)', -+ 'version': '7', -+ 'pretty_version': '7 (wheezy)', -+ 'best_version': '7', -+ 'like': 'debian', -+ 'codename': 'wheezy', -+ 'major_version': '7', -+ } -+ self._test_outcome(desired_outcome) -+ self._test_non_existing_release_file() -+ -+ def test_raspbian8_release(self): -+ desired_outcome = { -+ 'id': 'raspbian', -+ 'name': 'Raspbian GNU/Linux', -+ 'pretty_name': 'Raspbian GNU/Linux 8 (jessie)', -+ 'version': '8', -+ 'pretty_version': '8 (jessie)', -+ 'best_version': '8', -+ 'like': 'debian', -+ 'codename': 'jessie', -+ 'major_version': '8', -+ } -+ self._test_outcome(desired_outcome) -+ self._test_non_existing_release_file() -+ -+ def test_rhel5_release(self): -+ desired_outcome = { -+ 'id': 'rhel', -+ 'name': 'Red Hat Enterprise Linux Server', -+ 'pretty_name': 'Red Hat Enterprise Linux Server 5.11 (Tikanga)', -+ 'version': '5.11', -+ 'pretty_version': '5.11 (Tikanga)', -+ 'best_version': '5.11', -+ 'codename': 'Tikanga', -+ 'major_version': '5', -+ 'minor_version': '11' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'redhat', -+ 'name': 'Red Hat Enterprise Linux Server', -+ 'version_id': '5.11', -+ 'codename': 'Tikanga' -+ } -+ self._test_release_file_info('redhat-release', desired_info) -+ -+ def test_rhel6_release(self): -+ desired_outcome = { -+ 'id': 'rhel', -+ 'name': 'Red Hat Enterprise Linux Server', -+ 'pretty_name': 'Red Hat Enterprise Linux Server 6.5 (Santiago)', -+ 'version': '6.5', -+ 'pretty_version': '6.5 (Santiago)', -+ 'best_version': '6.5', -+ 'codename': 'Santiago', -+ 'major_version': '6', -+ 'minor_version': '5' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'redhat', -+ 'name': 'Red Hat Enterprise Linux Server', -+ 'version_id': '6.5', -+ 'codename': 'Santiago' -+ } -+ self._test_release_file_info('redhat-release', desired_info) -+ -+ def test_rhel7_release(self): -+ desired_outcome = { -+ 'id': 'rhel', -+ 'name': 'Red Hat Enterprise Linux Server', -+ 'pretty_name': 'Red Hat Enterprise Linux Server 7.0 (Maipo)', -+ 'version': '7.0', -+ 'pretty_version': '7.0 (Maipo)', -+ 'best_version': '7.0', -+ 'like': 'fedora', -+ 'codename': 'Maipo', -+ 'major_version': '7', -+ 'minor_version': '0' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'redhat', -+ 'name': 'Red Hat Enterprise Linux Server', -+ 'version_id': '7.0', -+ 'codename': 'Maipo' -+ } -+ self._test_release_file_info('redhat-release', desired_info) -+ -+ def test_slackware14_release(self): -+ desired_outcome = { -+ 'id': 'slackware', -+ 'name': 'Slackware', -+ 'pretty_name': 'Slackware 14.1', -+ 'version': '14.1', -+ 'pretty_version': '14.1', -+ 'best_version': '14.1', -+ 'major_version': '14', -+ 'minor_version': '1' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'slackware', -+ 'name': 'Slackware', -+ 'version_id': '14.1', -+ } -+ distro_info = self._test_release_file_info( -+ 'slackware-version', desired_info) -+ assert 'codename' not in distro_info -+ -+ def test_sles12_release(self): -+ desired_outcome = { -+ 'id': 'sles', -+ 'name': 'SLES', -+ 'pretty_name': 'SUSE Linux Enterprise Server 12 SP1', -+ 'version': '12.1', -+ 'pretty_version': '12.1 (n/a)', -+ 'best_version': '12.1', -+ 'codename': 'n/a', -+ 'major_version': '12', -+ 'minor_version': '1' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'SuSE', -+ 'name': 'SUSE Linux Enterprise Server', -+ 'version_id': '12', -+ 'codename': 's390x' -+ } -+ self._test_release_file_info('SuSE-release', desired_info) -+ -+ def test_ubuntu14_release(self): -+ desired_outcome = { -+ 'id': 'ubuntu', -+ 'name': 'Ubuntu', -+ 'pretty_name': 'Ubuntu 14.04.3 LTS', -+ 'version': '14.04', -+ 'pretty_version': '14.04 (Trusty Tahr)', -+ 'best_version': '14.04.3', -+ 'like': 'debian', -+ 'codename': 'Trusty Tahr', -+ 'major_version': '14', -+ 'minor_version': '04' -+ } -+ self._test_outcome(desired_outcome) -+ -+ # Test the info from the searched distro release file -+ # Does not have one; /etc/debian_version is not considered a distro -+ # release file: -+ self._test_non_existing_release_file() -+ -+ def test_ubuntu16_release(self): -+ desired_outcome = { -+ 'id': 'ubuntu', -+ 'name': 'Ubuntu', -+ 'pretty_name': 'Ubuntu 16.04.1 LTS', -+ 'version': '16.04', -+ 'pretty_version': '16.04 (xenial)', -+ 'best_version': '16.04.1', -+ 'like': 'debian', -+ 'codename': 'xenial', -+ 'major_version': '16', -+ 'minor_version': '04' -+ } -+ self._test_outcome(desired_outcome) -+ -+ # Test the info from the searched distro release file -+ # Does not have one; /etc/debian_version is not considered a distro -+ # release file: -+ self._test_non_existing_release_file() -+ -+ def test_amazon2016_release(self): -+ desired_outcome = { -+ 'id': 'amzn', -+ 'name': 'Amazon Linux AMI', -+ 'pretty_name': 'Amazon Linux AMI 2016.03', -+ 'version': '2016.03', -+ 'pretty_version': '2016.03', -+ 'best_version': '2016.03', -+ 'like': 'rhel fedora', -+ 'major_version': '2016', -+ 'minor_version': '03' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_amazon2014_release(self): -+ # Amazon Linux 2014 only contains a system-release file. -+ # distro doesn't currently handle it. -+ desired_outcome = {} -+ self._test_outcome(desired_outcome) -+ -+ def test_scientific6_release(self): -+ desired_outcome = { -+ 'id': 'rhel', -+ 'name': 'Scientific Linux', -+ 'pretty_name': 'Scientific Linux 6.4 (Carbon)', -+ 'version': '6.4', -+ 'pretty_version': '6.4 (Carbon)', -+ 'best_version': '6.4', -+ 'codename': 'Carbon', -+ 'major_version': '6', -+ 'minor_version': '4', -+ -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'redhat', -+ 'name': 'Scientific Linux', -+ 'version_id': '6.4', -+ 'codename': 'Carbon' -+ } -+ self._test_release_file_info('redhat-release', desired_info) -+ -+ def test_scientific7_release(self): -+ desired_outcome = { -+ 'id': 'rhel', -+ 'name': 'Scientific Linux', -+ 'pretty_name': 'Scientific Linux 7.2 (Nitrogen)', -+ 'version': '7.2', -+ 'pretty_version': '7.2 (Nitrogen)', -+ 'best_version': '7.2', -+ 'like': 'fedora', -+ 'codename': 'Nitrogen', -+ 'major_version': '7', -+ 'minor_version': '2', -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'redhat', -+ 'name': 'Scientific Linux', -+ 'version_id': '7.2', -+ 'codename': 'Nitrogen' -+ } -+ self._test_release_file_info('redhat-release', desired_info) -+ -+ def test_gentoo_release(self): -+ desired_outcome = { -+ 'id': 'gentoo', -+ 'name': 'Gentoo', -+ 'pretty_name': 'Gentoo/Linux', -+ 'version': '2.2', -+ 'pretty_version': '2.2', -+ 'best_version': '2.2', -+ 'major_version': '2', -+ 'minor_version': '2', -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'gentoo', -+ 'name': 'Gentoo Base System', -+ 'version_id': '2.2', -+ } -+ self._test_release_file_info('gentoo-release', desired_info) -+ -+ def test_openelec6_release(self): -+ desired_outcome = { -+ 'id': 'openelec', -+ 'name': 'OpenELEC', -+ 'pretty_name': 'OpenELEC (official) - Version: 6.0.3', -+ 'version': '6.0', -+ 'pretty_version': '6.0', -+ 'best_version': '6.0.3', -+ 'major_version': '6', -+ 'minor_version': '0', -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_mandriva2011_release(self): -+ desired_outcome = { -+ 'id': 'mandrivalinux', -+ 'name': 'MandrivaLinux', -+ 'pretty_name': 'Mandriva Linux 2011.0', -+ 'version': '2011.0', -+ 'pretty_version': '2011.0 (turtle)', -+ 'best_version': '2011.0', -+ 'major_version': '2011', -+ 'minor_version': '0', -+ 'codename': 'turtle' -+ } -+ self._test_outcome(desired_outcome) -+ -+ desired_info = { -+ 'id': 'mandrake', -+ 'name': 'Mandriva Linux', -+ 'version_id': '2011.0', -+ } -+ self._test_release_file_info('mandrake-release', desired_info) -+ -+ def test_cloudlinux5_release(self): -+ # Uses redhat-release only to get information. -+ # The id of 'rhel' can only be fixed with issue #109. -+ desired_outcome = { -+ 'id': 'cloudlinux', -+ 'codename': 'Vladislav Volkov', -+ 'name': 'CloudLinux Server', -+ 'pretty_name': 'CloudLinux Server 5.11 (Vladislav Volkov)', -+ 'version': '5.11', -+ 'pretty_version': '5.11 (Vladislav Volkov)', -+ 'best_version': '5.11', -+ 'major_version': '5', -+ 'minor_version': '11' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_cloudlinux6_release(self): -+ # Same as above, only has redhat-release. -+ desired_outcome = { -+ 'id': 'cloudlinux', -+ 'codename': 'Oleg Makarov', -+ 'name': 'CloudLinux Server', -+ 'pretty_name': 'CloudLinux Server 6.8 (Oleg Makarov)', -+ 'version': '6.8', -+ 'pretty_version': '6.8 (Oleg Makarov)', -+ 'best_version': '6.8', -+ 'major_version': '6', -+ 'minor_version': '8' -+ } -+ self._test_outcome(desired_outcome) -+ -+ def test_cloudlinux7_release(self): -+ desired_outcome = { -+ 'id': 'cloudlinux', -+ 'codename': 'Yury Malyshev', -+ 'name': 'CloudLinux', -+ 'pretty_name': 'CloudLinux 7.3 (Yury Malyshev)', -+ 'like': 'rhel fedora centos', -+ 'version': '7.3', -+ 'pretty_version': '7.3 (Yury Malyshev)', -+ 'best_version': '7.3', -+ 'major_version': '7', -+ 'minor_version': '3' -+ } -+ self._test_outcome(desired_outcome) -+ -+ -+def _bad_os_listdir(path='.'): -+ """ This function is used by TestOverallWithEtcNotReadable to simulate -+ a folder that cannot be called with os.listdir() but files are still -+ readable. Forces distro to guess which *-release files are available. """ -+ raise OSError() -+ -+ -+@pytest.mark.skipIf(not IS_LINUX, reason='Irrelevant on non-linx') -+class TestOverallWithEtcNotReadable(TestOverall): -+ def setup_method(self, test_method): -+ self._old_listdir = os.listdir -+ os.listdir = _bad_os_listdir -+ super(TestOverallWithEtcNotReadable, self).setup_method(test_method) -+ -+ def teardown_method(self, test_method): -+ super(TestOverallWithEtcNotReadable, self).teardown_method(test_method) -+ if os.listdir is _bad_os_listdir: -+ os.listdir = self._old_listdir -+ -+ -+@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') -+class TestGetAttr(DistroTestCase): -+ """Test the consistency between the results of -+ `{source}_release_attr()` and `{source}_release_info()` for all -+ distros in `DISTROS`. -+ """ -+ -+ def _test_attr(self, info_method, attr_method): -+ for dist in DISTROS: -+ self._setup_for_distro(os.path.join(DISTROS_DIR, dist)) -+ _distro = distro.LinuxDistribution() -+ info = getattr(_distro, info_method)() -+ for key in info.keys(): -+ try: -+ assert info[key] == getattr(_distro, attr_method)(key) -+ except AssertionError: -+ print("distro: {0}, key: {1}".format(dist, key)) -+ -+ def test_os_release_attr(self): -+ self._test_attr('os_release_info', 'os_release_attr') -+ -+ def test_lsb_release_attr(self): -+ self._test_attr('lsb_release_info', 'lsb_release_attr') -+ -+ def test_distro_release_attr(self): -+ self._test_attr('distro_release_info', 'distro_release_attr') -+ -+ -+@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') -+class TestInfo(DistroTestCase): -+ -+ def setup_method(self, test_method): -+ super(TestInfo, self).setup_method(test_method) -+ self.ubuntu14_os_release = os.path.join( -+ DISTROS_DIR, 'ubuntu14', 'etc', 'os-release') -+ -+ def test_info(self): -+ _distro = distro.LinuxDistribution( -+ False, self.ubuntu14_os_release, 'non') -+ -+ desired_info = { -+ 'id': 'ubuntu', -+ 'version': '14.04', -+ 'like': 'debian', -+ 'version_parts': { -+ 'major': '14', -+ 'minor': '04', -+ 'build_number': '' -+ }, -+ 'codename': 'Trusty Tahr' -+ } -+ -+ info = _distro.info() -+ assert info == desired_info -+ -+ desired_info_diff = { -+ 'version': '14.04 (Trusty Tahr)' -+ } -+ desired_info.update(desired_info_diff) -+ info = _distro.info(pretty=True) -+ assert info == desired_info -+ -+ desired_info_diff = { -+ 'version': '14.04.3', -+ 'version_parts': { -+ 'major': '14', -+ 'minor': '04', -+ 'build_number': '3' -+ } -+ } -+ desired_info.update(desired_info_diff) -+ info = _distro.info(best=True) -+ assert info == desired_info -+ -+ desired_info_diff = { -+ 'version': '14.04.3 (Trusty Tahr)' -+ } -+ desired_info.update(desired_info_diff) -+ info = _distro.info(pretty=True, best=True) -+ assert info == desired_info -+ -+ def test_none(self): -+ -+ def _test_none(info): -+ assert info['id'] == '' -+ assert info['version'] == '' -+ assert info['like'] == '' -+ assert info['version_parts']['major'] == '' -+ assert info['version_parts']['minor'] == '' -+ assert info['version_parts']['build_number'] == '' -+ assert info['codename'] == '' -+ -+ _distro = distro.LinuxDistribution(False, 'non', 'non') -+ -+ info = _distro.info() -+ _test_none(info) -+ -+ info = _distro.info(best=True) -+ _test_none(info) -+ -+ info = _distro.info(pretty=True) -+ _test_none(info) -+ -+ info = _distro.info(pretty=True, best=True) -+ _test_none(info) -+ -+ def test_linux_distribution(self): -+ _distro = distro.LinuxDistribution(False, self.ubuntu14_os_release) -+ i = _distro.linux_distribution() -+ assert i == ('Ubuntu', '14.04', 'Trusty Tahr') -+ -+ def test_linux_distribution_full_false(self): -+ _distro = distro.LinuxDistribution(False, self.ubuntu14_os_release) -+ i = _distro.linux_distribution(full_distribution_name=False) -+ assert i == ('ubuntu', '14.04', 'Trusty Tahr') -+ -+ def test_all(self): -+ """Test info() by comparing its results with the results of specific -+ consolidated accessor functions. -+ """ -+ def _test_all(info, best=False, pretty=False): -+ assert info['id'] == _distro.id() -+ assert info['version'] == _distro.version(pretty=pretty, best=best) -+ assert info['version_parts']['major'] == \ -+ _distro.major_version(best=best) -+ assert info['version_parts']['minor'] == \ -+ _distro.minor_version(best=best) -+ assert info['version_parts']['build_number'] == \ -+ _distro.build_number(best=best) -+ assert info['like'] == _distro.like() -+ assert info['codename'] == _distro.codename() -+ assert len(info['version_parts']) == 3 -+ assert len(info) == 5 -+ -+ for dist in DISTROS: -+ self._setup_for_distro(os.path.join(DISTROS_DIR, dist)) -+ -+ _distro = distro.LinuxDistribution() -+ -+ info = _distro.info() -+ _test_all(info) -+ -+ info = _distro.info(best=True) -+ _test_all(info, best=True) -+ -+ info = _distro.info(pretty=True) -+ _test_all(info, pretty=True) -+ -+ info = _distro.info(pretty=True, best=True) -+ _test_all(info, pretty=True, best=True) -+ -+ -+@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') -+class TestOSReleaseParsing: -+ """Test the parsing of os-release files. -+ """ -+ -+ def setup_method(self, test_method): -+ self.distro = distro.LinuxDistribution(False, None, None) -+ self.distro.debug = True -+ -+ def _get_props(self, input): -+ return self.distro._parse_os_release_content(StringIO( -+ input, -+ )) -+ -+ def _test_zero_length_props(self, input): -+ props = self._get_props(input) -+ assert len(props) == 0 -+ -+ def _test_empty_value(self, input): -+ props = self._get_props(input) -+ assert props.get('key', None) == '' -+ -+ def _test_parsed_value(self, input): -+ props = self._get_props(input) -+ assert props.get('key', None) == 'value' -+ -+ def test_kv_01_empty_file(self): -+ self._test_zero_length_props('') -+ -+ def test_kv_02_empty_line(self): -+ self._test_zero_length_props('\n') -+ -+ def test_kv_03_empty_line_with_crlf(self): -+ self._test_zero_length_props('\r\n') -+ -+ def test_kv_04_empty_line_with_just_cr(self): -+ self._test_zero_length_props('\r') -+ -+ def test_kv_05_comment(self): -+ self._test_zero_length_props('# KEY=value\n') -+ -+ def test_kv_06_empty_value(self): -+ self._test_empty_value('KEY=\n') -+ -+ def test_kv_07_empty_value_single_quoted(self): -+ self._test_empty_value('KEY=\'\'\n') -+ -+ def test_kv_08_empty_value_double_quoted(self): -+ self._test_empty_value('KEY=""\n') -+ -+ def test_kv_09_word(self): -+ self._test_parsed_value('KEY=value\n') -+ -+ def test_kv_10_word_no_newline(self): -+ self._test_parsed_value('KEY=value') -+ -+ def test_kv_11_word_with_crlf(self): -+ self._test_parsed_value('KEY=value\r\n') -+ -+ def test_kv_12_word_with_just_cr(self): -+ self._test_parsed_value('KEY=value\r') -+ -+ def test_kv_13_word_with_multi_blanks(self): -+ self._test_empty_value('KEY= cmd \n') -+ # Note: Without quotes, this assigns the empty string, and 'cmd' is -+ # a separate token that is being ignored (it would be a command -+ # in the shell). -+ -+ def test_kv_14_unquoted_words(self): -+ self._test_parsed_value('KEY=value cmd\n') -+ -+ def test_kv_15_double_quoted_words(self): -+ props = self._get_props('KEY="a simple value" cmd\n') -+ assert props.get('key', None) == 'a simple value' -+ -+ def test_kv_16_double_quoted_words_with_multi_blanks(self): -+ props = self._get_props('KEY=" a simple value "\n') -+ assert props.get('key', None) == ' a simple value ' -+ -+ def test_kv_17_double_quoted_word_with_single_quote(self): -+ props = self._get_props('KEY="it\'s value"\n') -+ assert props.get('key', None) == 'it\'s value' -+ -+ def test_kv_18_double_quoted_word_with_double_quote(self): -+ props = self._get_props('KEY="a \\"bold\\" move"\n') -+ assert props.get('key', None) == 'a "bold" move' -+ -+ def test_kv_19_single_quoted_words(self): -+ props = self._get_props('KEY=\'a simple value\'\n') -+ assert props.get('key', None) == 'a simple value' -+ -+ def test_kv_20_single_quoted_words_with_multi_blanks(self): -+ props = self._get_props('KEY=\' a simple value \'\n') -+ assert props.get('key', None) == ' a simple value ' -+ -+ def test_kv_21_single_quoted_word_with_double_quote(self): -+ props = self._get_props('KEY=\'a "bold" move\'\n') -+ assert props.get('key', None) == 'a "bold" move' -+ -+ def test_kv_22_quoted_unicode_wordchar(self): -+ # "wordchar" means it is in the shlex.wordchars variable. -+ props = self._get_props(u'KEY="wordchar: \u00CA (E accent grave)"\n') -+ assert props.get('key', None) == u'wordchar: \u00CA (E accent grave)' -+ -+ def test_kv_23_quoted_unicode_non_wordchar(self): -+ # "non-wordchar" means it is not in the shlex.wordchars variable. -+ props = self._get_props( -+ u'KEY="non-wordchar: \u00A1 (inverted exclamation mark)"\n') -+ assert (props.get('key', None) == -+ u'non-wordchar: \u00A1 (inverted exclamation mark)') -+ -+ def test_kv_24_double_quoted_entire_single_quoted_word(self): -+ props = self._get_props('KEY="\'value\'"\n') -+ assert props.get('key', None) == "'value'" -+ -+ def test_kv_25_single_quoted_entire_double_quoted_word(self): -+ props = self._get_props('KEY=\'"value"\'\n') -+ assert props.get('key', None) == '"value"' -+ -+ def test_kv_26_double_quoted_multiline(self): -+ props = self.distro._parse_os_release_content(StringIO( -+ 'KEY="a multi\n' -+ 'line value"\n' -+ )) -+ assert props.get('key', None) == 'a multi\nline value' -+ # TODO: Find out why the result is not 'a multi line value' -+ -+ def test_kv_27_double_quoted_multiline_2(self): -+ props = self._get_props('KEY=\' a simple value \'\n') -+ props = self.distro._parse_os_release_content(StringIO( -+ 'KEY="a multi\n' -+ 'line=value"\n' -+ )) -+ assert props.get('key', None) == 'a multi\nline=value' -+ # TODO: Find out why the result is not 'a multi line=value' -+ -+ def test_kv_28_double_quoted_word_with_equal(self): -+ props = self._get_props('KEY="var=value"\n') -+ assert props.get('key', None) == 'var=value' -+ -+ def test_kv_29_single_quoted_word_with_equal(self): -+ props = self._get_props('KEY=\'var=value\'\n') -+ assert props.get('key', None) == 'var=value' -+ -+ def test_kx_01(self): -+ props = self.distro._parse_os_release_content(StringIO( -+ 'KEY1=value1\n' -+ 'KEY2="value 2"\n' -+ )) -+ assert props.get('key1', None) == 'value1' -+ assert props.get('key2', None) == 'value 2' -+ -+ def test_kx_02(self): -+ props = self.distro._parse_os_release_content(StringIO( -+ '# KEY1=value1\n' -+ 'KEY2="value 2"\n' -+ )) -+ assert props.get('key1', None) is None -+ assert props.get('key2', None) == 'value 2' -+ -+ -+@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') -+class TestGlobal: -+ """Test the global module-level functions, and default values of their -+ arguments. -+ """ -+ -+ def setup_method(self, test_method): -+ pass -+ -+ def test_global(self): -+ # Because the module-level functions use the module-global -+ # LinuxDistribution instance, it would influence the tested -+ # code too much if we mocked that in order to use the distro -+ # specific release files. Instead, we let the functions use -+ # the release files of the distro this test runs on, and -+ # compare the result of the global functions with the result -+ # of the methods on the global LinuxDistribution object. -+ -+ def _test_consistency(function, kwargs=None): -+ kwargs = kwargs or {} -+ method_result = getattr(MODULE_DISTRO, function)(**kwargs) -+ function_result = getattr(distro, function)(**kwargs) -+ assert method_result == function_result -+ -+ kwargs = {'full_distribution_name': True} -+ _test_consistency('linux_distribution', kwargs) -+ kwargs = {'full_distribution_name': False} -+ _test_consistency('linux_distribution', kwargs) -+ -+ kwargs = {'pretty': False} -+ _test_consistency('name', kwargs) -+ _test_consistency('version', kwargs) -+ _test_consistency('info', kwargs) -+ -+ kwargs = {'pretty': True} -+ _test_consistency('name', kwargs) -+ _test_consistency('version', kwargs) -+ _test_consistency('info', kwargs) -+ -+ kwargs = {'best': False} -+ _test_consistency('version', kwargs) -+ _test_consistency('version_parts', kwargs) -+ _test_consistency('major_version', kwargs) -+ _test_consistency('minor_version', kwargs) -+ _test_consistency('build_number', kwargs) -+ _test_consistency('info', kwargs) -+ -+ kwargs = {'best': True} -+ _test_consistency('version', kwargs) -+ _test_consistency('version_parts', kwargs) -+ _test_consistency('major_version', kwargs) -+ _test_consistency('minor_version', kwargs) -+ _test_consistency('build_number', kwargs) -+ _test_consistency('info', kwargs) -+ -+ _test_consistency('id') -+ _test_consistency('like') -+ _test_consistency('codename') -+ _test_consistency('info') -+ -+ _test_consistency('os_release_info') -+ _test_consistency('lsb_release_info') -+ _test_consistency('distro_release_info') -+ _test_consistency('uname_info') -+ -+ os_release_keys = [ -+ 'name', -+ 'version', -+ 'id', -+ 'id_like', -+ 'pretty_name', -+ 'version_id', -+ 'codename', -+ ] -+ for key in os_release_keys: -+ _test_consistency('os_release_attr', {'attribute': key}) -+ -+ lsb_release_keys = [ -+ 'distributor_id', -+ 'description', -+ 'release', -+ 'codename', -+ ] -+ for key in lsb_release_keys: -+ _test_consistency('lsb_release_attr', {'attribute': key}) -+ -+ distro_release_keys = [ -+ 'id', -+ 'name', -+ 'version_id', -+ 'codename', -+ ] -+ for key in distro_release_keys: -+ _test_consistency('distro_release_attr', {'attribute': key}) -+ -+ uname_keys = [ -+ 'id', -+ 'name', -+ 'release' -+ ] -+ for key in uname_keys: -+ _test_consistency('uname_attr', {'attribute': key}) -+ -+ -+@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') -+class TestRepr: -+ """Test the __repr__() method. -+ """ -+ -+ def test_repr(self): -+ # We test that the class name and the names of all instance attributes -+ # show up in the repr() string. -+ repr_str = repr(distro._distro) -+ assert "LinuxDistribution" in repr_str -+ for attr in MODULE_DISTRO.__dict__.keys(): -+ assert attr + '=' in repr_str -diff --git a/third_party/python/enum34/enum/doc/enum.pdf b/third_party/python/enum34/enum/doc/enum.pdf ---- a/third_party/python/enum34/enum/doc/enum.pdf -+++ b/third_party/python/enum34/enum/doc/enum.pdf -@@ -1,10 +1,10 @@ - %PDF-1.4
--%ζ±δΊ¬ ReportLab Generated PDF document http://www.reportlab.com
-+% ReportLab Generated PDF document http://www.reportlab.com
- 1 0 obj
- << /F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R /F5 8 0 R /F6 15 0 R >>
- endobj
- 2 0 obj
- << /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >>
- endobj
- 3 0 obj
- << /BaseFont /Courier-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font >>
-diff --git a/third_party/python/psutil/psutil/_pslinux.py b/third_party/python/psutil/psutil/_pslinux.py ---- a/third_party/python/psutil/psutil/_pslinux.py -+++ b/third_party/python/psutil/psutil/_pslinux.py -@@ -1046,30 +1046,28 @@ def disk_io_counters(): - # On Linux 2.4 each line has always 15 fields, e.g.: - # "3 0 8 hda 8 8 8 8 8 8 8 8 8 8 8" - # On Linux 2.6+ each line *usually* has 14 fields, and the disk - # name is in another position, like this: - # "3 0 hda 8 8 8 8 8 8 8 8 8 8 8" - # ...unless (Linux 2.6) the line refers to a partition instead - # of a disk, in which case the line has less fields (7): - # "3 1 hda1 8 8 8 8" -- # 4.18+ has 4 fields added: -- # "3 0 hda 8 8 8 8 8 8 8 8 8 8 8 0 0 0 0" - # See: - # https://www.kernel.org/doc/Documentation/iostats.txt - # https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats - fields = line.split() - fields_len = len(fields) - if fields_len == 15: - # Linux 2.4 - name = fields[3] - reads = int(fields[2]) - (reads_merged, rbytes, rtime, writes, writes_merged, - wbytes, wtime, _, busy_time, _) = map(int, fields[4:14]) -- elif fields_len == 14 or fields_len == 18: -+ elif fields_len == 14: - # Linux 2.6+, line referring to a disk - name = fields[2] - (reads, reads_merged, rbytes, rtime, writes, writes_merged, - wbytes, wtime, _, busy_time, _) = map(int, fields[3:14]) - elif fields_len == 7: - # Linux 2.6+, line referring to a partition - name = fields[2] - reads, rbytes, writes, wbytes = map(int, fields[3:]) -diff --git a/third_party/python/requirements.in b/third_party/python/requirements.in ---- a/third_party/python/requirements.in -+++ b/third_party/python/requirements.in -@@ -1,11 +1,12 @@ - attrs==18.1.0 - biplist==1.0.3 - blessings==1.7 -+distro==1.4.0 - jsmin==2.1.0 - json-e==2.7.0 - mozilla-version==0.3.0 - pathlib2==2.3.2 - pip-tools==3.0.0 - pipenv==2018.5.18 - psutil==5.4.3 - pytest==3.6.2 -diff --git a/third_party/python/requirements.txt b/third_party/python/requirements.txt ---- a/third_party/python/requirements.txt -+++ b/third_party/python/requirements.txt -@@ -14,16 +14,19 @@ blessings==1.7 \ - certifi==2018.4.16 \ - --hash=sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7 \ - --hash=sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0 \ - # via pipenv - click==7.0 \ - --hash=sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13 \ - --hash=sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7 \ - # via pip-tools -+distro==1.4.0 \ -+ --hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57 \ -+ --hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4 - enum34==1.1.6 \ - --hash=sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850 \ - --hash=sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a \ - --hash=sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79 \ - --hash=sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1 \ - # via mozilla-version - funcsigs==1.0.2 \ - --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \ - |