From 789be2a254466b2301996a2c58e3b4cef8b9d106 Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Mon, 10 Aug 2020 11:43:03 +0200 Subject: [PATCH 01/13] Respect REUSE spec when including licenses * REUSE spec states that a LICENSES folder should exist with copies of all of the licenses used in this project. * Previously, poetry tried to include all files like LICENSE*, but this didn't respect directories, meaning that poetry would fail if a LICENSES folder existed. * Now poetry is a bit more specific about the "correct" license files to add * LICENSE or COPYING * LICENSE.* or COPYING.* * LICENSES/** * In addition, if a suggested licensing file doesn't exist, or isn't a file, poetry will simply ignore it. --- poetry/core/masonry/builders/wheel.py | 15 +++++- .../fixtures/licenses_and_copying/COPYING | 0 .../fixtures/licenses_and_copying/COPYING.txt | 0 .../fixtures/licenses_and_copying/LICENSE | 20 ++++++++ .../fixtures/licenses_and_copying/LICENSE.md | 0 .../licenses_and_copying/LICENSES/BSD-3.md | 0 .../LICENSES/CUSTOM-LICENSE | 0 .../licenses_and_copying/LICENSES/MIT.txt | 0 .../fixtures/licenses_and_copying/README.rst | 2 + .../my_package/__init__.py | 1 + .../licenses_and_copying/pyproject.toml | 49 +++++++++++++++++++ tests/masonry/builders/test_wheel.py | 16 ++++++ 12 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 tests/masonry/builders/fixtures/licenses_and_copying/COPYING create mode 100644 tests/masonry/builders/fixtures/licenses_and_copying/COPYING.txt create mode 100644 tests/masonry/builders/fixtures/licenses_and_copying/LICENSE create mode 100644 tests/masonry/builders/fixtures/licenses_and_copying/LICENSE.md create mode 100644 tests/masonry/builders/fixtures/licenses_and_copying/LICENSES/BSD-3.md create mode 100644 tests/masonry/builders/fixtures/licenses_and_copying/LICENSES/CUSTOM-LICENSE create mode 100644 tests/masonry/builders/fixtures/licenses_and_copying/LICENSES/MIT.txt create mode 100644 tests/masonry/builders/fixtures/licenses_and_copying/README.rst create mode 100644 tests/masonry/builders/fixtures/licenses_and_copying/my_package/__init__.py create mode 100644 tests/masonry/builders/fixtures/licenses_and_copying/pyproject.toml diff --git a/poetry/core/masonry/builders/wheel.py b/poetry/core/masonry/builders/wheel.py index 08d0423e2..6c2d4b2f3 100644 --- a/poetry/core/masonry/builders/wheel.py +++ b/poetry/core/masonry/builders/wheel.py @@ -166,9 +166,20 @@ def _write_metadata(self, wheel): with self._write_to_zip(wheel, self.dist_info + "/entry_points.txt") as f: self._write_entry_points(f) + license_files_to_add = [] for base in ("COPYING", "LICENSE"): - for path in sorted(self._path.glob(base + "*")): - self._add_file(wheel, path, "%s/%s" % (self.dist_info, path.name)) + license_files_to_add.append(self._path / base) + license_files_to_add.extend(self._path.glob(base + ".*")) + + license_files_to_add.extend((self._path / "LICENSES").glob("**" + os.sep + "*")) + + for path in license_files_to_add: + if not path.is_file(): + continue + + self._add_file( + wheel, path, "%s/%s" % (self.dist_info, path.relative_to(self._path)) + ) with self._write_to_zip(wheel, self.dist_info + "/WHEEL") as f: self._write_wheel_file(f) diff --git a/tests/masonry/builders/fixtures/licenses_and_copying/COPYING b/tests/masonry/builders/fixtures/licenses_and_copying/COPYING new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/licenses_and_copying/COPYING.txt b/tests/masonry/builders/fixtures/licenses_and_copying/COPYING.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/licenses_and_copying/LICENSE b/tests/masonry/builders/fixtures/licenses_and_copying/LICENSE new file mode 100644 index 000000000..44cf2b30e --- /dev/null +++ b/tests/masonry/builders/fixtures/licenses_and_copying/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2018 Sébastien Eustace + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tests/masonry/builders/fixtures/licenses_and_copying/LICENSE.md b/tests/masonry/builders/fixtures/licenses_and_copying/LICENSE.md new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/licenses_and_copying/LICENSES/BSD-3.md b/tests/masonry/builders/fixtures/licenses_and_copying/LICENSES/BSD-3.md new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/licenses_and_copying/LICENSES/CUSTOM-LICENSE b/tests/masonry/builders/fixtures/licenses_and_copying/LICENSES/CUSTOM-LICENSE new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/licenses_and_copying/LICENSES/MIT.txt b/tests/masonry/builders/fixtures/licenses_and_copying/LICENSES/MIT.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/masonry/builders/fixtures/licenses_and_copying/README.rst b/tests/masonry/builders/fixtures/licenses_and_copying/README.rst new file mode 100644 index 000000000..f7fe15470 --- /dev/null +++ b/tests/masonry/builders/fixtures/licenses_and_copying/README.rst @@ -0,0 +1,2 @@ +My Package +========== diff --git a/tests/masonry/builders/fixtures/licenses_and_copying/my_package/__init__.py b/tests/masonry/builders/fixtures/licenses_and_copying/my_package/__init__.py new file mode 100644 index 000000000..10aa336ce --- /dev/null +++ b/tests/masonry/builders/fixtures/licenses_and_copying/my_package/__init__.py @@ -0,0 +1 @@ +__version__ = "1.2.3" diff --git a/tests/masonry/builders/fixtures/licenses_and_copying/pyproject.toml b/tests/masonry/builders/fixtures/licenses_and_copying/pyproject.toml new file mode 100644 index 000000000..b56bbe637 --- /dev/null +++ b/tests/masonry/builders/fixtures/licenses_and_copying/pyproject.toml @@ -0,0 +1,49 @@ +[tool.poetry] +name = "my-package" +version = "1.2.3" +description = "Some description." +authors = [ + "Sébastien Eustace " +] +maintainers = [ + "People Everywhere " +] +license = "MIT" + +readme = "README.rst" + +homepage = "https://python-poetry.org/" +repository = "https://github.com/python-poetry/poetry" +documentation = "https://python-poetry.org/docs" + +keywords = ["packaging", "dependency", "poetry"] + +classifiers = [ + "Topic :: Software Development :: Build Tools", + "Topic :: Software Development :: Libraries :: Python Modules" +] + +# Requirements +[tool.poetry.dependencies] +python = "^3.6" +cleo = "^0.6" +cachy = { version = "^0.2.0", extras = ["msgpack"] } + +[tool.poetry.dependencies.pendulum] +version = "^1.4" +markers= 'python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5"' +optional = true + +[tool.poetry.dev-dependencies] +pytest = "~3.4" + +[tool.poetry.extras] +time = ["pendulum"] + +[tool.poetry.scripts] +my-script = "my_package:main" +my-2nd-script = "my_package:main2" +extra-script = {callable = "my_package.extra:main", extras = ["time"]} + +[tool.poetry.urls] +"Issue Tracker" = "https://github.com/python-poetry/poetry/issues" diff --git a/tests/masonry/builders/test_wheel.py b/tests/masonry/builders/test_wheel.py index 2fd81bc23..cd51a5731 100644 --- a/tests/masonry/builders/test_wheel.py +++ b/tests/masonry/builders/test_wheel.py @@ -198,3 +198,19 @@ def test_wheel_package_pep_561_stub_only_includes_typed_marker(): with zipfile.ZipFile(str(whl)) as z: assert "pkg-stubs/py.typed" in z.namelist() + +def test_wheel_includes_licenses_in_correct_paths(): + root = fixtures_dir / "licenses_and_copying" + WheelBuilder.make(Factory().create_poetry(root), NullEnv(), NullIO()) + + whl = root / "dist" / "my_package-1.2.3-py3-none-any.whl" + + assert whl.exists() + with zipfile.ZipFile(str(whl)) as z: + assert "my_package-1.2.3.dist-info/COPYING" in z.namelist() + assert "my_package-1.2.3.dist-info/COPYING.txt" in z.namelist() + assert "my_package-1.2.3.dist-info/LICENSE" in z.namelist() + assert "my_package-1.2.3.dist-info/LICENSE.md" in z.namelist() + assert "my_package-1.2.3.dist-info/LICENSES/CUSTOM-LICENSE" in z.namelist() + assert "my_package-1.2.3.dist-info/LICENSES/BSD-3.md" in z.namelist() + assert "my_package-1.2.3.dist-info/LICENSES/MIT.txt" in z.namelist() From d8ebac03b8cc9cb3c991162f6222ca7facd60ed9 Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Mon, 10 Aug 2020 11:56:51 +0200 Subject: [PATCH 02/13] Remove unnecessary null environment/io usage --- tests/masonry/builders/test_wheel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/masonry/builders/test_wheel.py b/tests/masonry/builders/test_wheel.py index cd51a5731..f6f9d0d29 100644 --- a/tests/masonry/builders/test_wheel.py +++ b/tests/masonry/builders/test_wheel.py @@ -201,7 +201,7 @@ def test_wheel_package_pep_561_stub_only_includes_typed_marker(): def test_wheel_includes_licenses_in_correct_paths(): root = fixtures_dir / "licenses_and_copying" - WheelBuilder.make(Factory().create_poetry(root), NullEnv(), NullIO()) + WheelBuilder.make(Factory().create_poetry(root)) whl = root / "dist" / "my_package-1.2.3-py3-none-any.whl" From 8ed0092113a6287fb31fbd97f49c2a13cc3b7152 Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Mon, 10 Aug 2020 11:59:17 +0200 Subject: [PATCH 03/13] Fix formatting according to black --- tests/masonry/builders/test_wheel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/masonry/builders/test_wheel.py b/tests/masonry/builders/test_wheel.py index f6f9d0d29..3a6da686d 100644 --- a/tests/masonry/builders/test_wheel.py +++ b/tests/masonry/builders/test_wheel.py @@ -199,6 +199,7 @@ def test_wheel_package_pep_561_stub_only_includes_typed_marker(): with zipfile.ZipFile(str(whl)) as z: assert "pkg-stubs/py.typed" in z.namelist() + def test_wheel_includes_licenses_in_correct_paths(): root = fixtures_dir / "licenses_and_copying" WheelBuilder.make(Factory().create_poetry(root)) From 8435a273e1224084c5ac3a29d81c7b5617620f5c Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Mon, 17 Aug 2020 12:04:46 +0200 Subject: [PATCH 04/13] Remove a mistakenly-pasted line of text --- tests/masonry/builders/test_wheel.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/masonry/builders/test_wheel.py b/tests/masonry/builders/test_wheel.py index ee7e8fcb6..32fb05169 100644 --- a/tests/masonry/builders/test_wheel.py +++ b/tests/masonry/builders/test_wheel.py @@ -21,9 +21,6 @@ def setup(): clear_samples_dist() -The development of an archived package is complete, and it has been archived on CRAN and on GitHub. - - def clear_samples_dist(): for dist in fixtures_dir.glob("**/dist"): if dist.is_dir(): From 5ddc10685b5c908a2ec4efe1fae740ef305c4216 Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Mon, 17 Aug 2020 14:43:21 +0200 Subject: [PATCH 05/13] Apply suggestions from code review Co-authored-by: Arun Babu Neelicattu --- poetry/core/masonry/builders/wheel.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry/core/masonry/builders/wheel.py b/poetry/core/masonry/builders/wheel.py index d4c8d657d..d3fd58faa 100644 --- a/poetry/core/masonry/builders/wheel.py +++ b/poetry/core/masonry/builders/wheel.py @@ -170,18 +170,18 @@ def _write_metadata(self, wheel): license_files_to_add = [] for base in ("COPYING", "LICENSE"): - license_files_to_add.append(self._path / base) + license_files_to_add.append(base) license_files_to_add.extend(self._path.glob(base + ".*")) license_files_to_add.extend((self._path / "LICENSES").glob("**" + os.sep + "*")) for path in license_files_to_add: - if not path.is_file(): - continue - - self._add_file( - wheel, path, "%s/%s" % (self.dist_info, path.relative_to(self._path)) - ) + if path.is_file(): + self._add_file( + wheel, path, "%s/%s" % (self.dist_info, path.as_posix()) + ) + else: + logger.debug("Skipping: %s", path.as_posix()) with self._write_to_zip(wheel, self.dist_info + "/WHEEL") as f: self._write_wheel_file(f) From f796b6905cd7d96f6aea5deb73ea8940df80f9db Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Mon, 17 Aug 2020 14:56:30 +0200 Subject: [PATCH 06/13] Fix formatting issues with suggested changes --- poetry/core/masonry/builders/wheel.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/poetry/core/masonry/builders/wheel.py b/poetry/core/masonry/builders/wheel.py index d3fd58faa..aec436e25 100644 --- a/poetry/core/masonry/builders/wheel.py +++ b/poetry/core/masonry/builders/wheel.py @@ -177,11 +177,9 @@ def _write_metadata(self, wheel): for path in license_files_to_add: if path.is_file(): - self._add_file( - wheel, path, "%s/%s" % (self.dist_info, path.as_posix()) - ) + self._add_file(wheel, path, "%s/%s" % (self.dist_info, path.as_posix())) else: - logger.debug("Skipping: %s", path.as_posix()) + logger.debug("Skipping: %s", path.as_posix()) with self._write_to_zip(wheel, self.dist_info + "/WHEEL") as f: self._write_wheel_file(f) From 8d8653034196f33bce4af0bbfe5fe0f7a2be0c98 Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Mon, 17 Aug 2020 15:07:49 +0200 Subject: [PATCH 07/13] Ensure all license files are Path objects --- poetry/core/masonry/builders/wheel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/poetry/core/masonry/builders/wheel.py b/poetry/core/masonry/builders/wheel.py index aec436e25..eba17326c 100644 --- a/poetry/core/masonry/builders/wheel.py +++ b/poetry/core/masonry/builders/wheel.py @@ -170,10 +170,10 @@ def _write_metadata(self, wheel): license_files_to_add = [] for base in ("COPYING", "LICENSE"): - license_files_to_add.append(base) + license_files_to_add.append(self._path / base) license_files_to_add.extend(self._path.glob(base + ".*")) - license_files_to_add.extend((self._path / "LICENSES").glob("**" + os.sep + "*")) + license_files_to_add.extend(self._path.glob("LICENSES/**/*")) for path in license_files_to_add: if path.is_file(): From 0653cb86d223c5205021f358804570f2ed8770d9 Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Mon, 17 Aug 2020 15:17:55 +0200 Subject: [PATCH 08/13] Ensure all paths added to wheel are relative --- poetry/core/masonry/builders/wheel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/poetry/core/masonry/builders/wheel.py b/poetry/core/masonry/builders/wheel.py index eba17326c..cbeaba10d 100644 --- a/poetry/core/masonry/builders/wheel.py +++ b/poetry/core/masonry/builders/wheel.py @@ -177,7 +177,8 @@ def _write_metadata(self, wheel): for path in license_files_to_add: if path.is_file(): - self._add_file(wheel, path, "%s/%s" % (self.dist_info, path.as_posix())) + relative_path = "%s/%s" % (self.dist_info, path.relative_to(self._path)) + self._add_file(wheel, path, relative_path) else: logger.debug("Skipping: %s", path.as_posix()) From 6e77e3b343b6221c541e964a1fbe8aa26448b732 Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Mon, 17 Aug 2020 15:30:11 +0200 Subject: [PATCH 09/13] Add pathsep for Windows path matching --- poetry/core/masonry/builders/wheel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/poetry/core/masonry/builders/wheel.py b/poetry/core/masonry/builders/wheel.py index cbeaba10d..5f6e6d570 100644 --- a/poetry/core/masonry/builders/wheel.py +++ b/poetry/core/masonry/builders/wheel.py @@ -173,7 +173,7 @@ def _write_metadata(self, wheel): license_files_to_add.append(self._path / base) license_files_to_add.extend(self._path.glob(base + ".*")) - license_files_to_add.extend(self._path.glob("LICENSES/**/*")) + license_files_to_add.extend((self._path / "LICENSES").glob("**" + os.pathsep + "*")) for path in license_files_to_add: if path.is_file(): From 61e6525730631af77d71ac9ac0be57011171ad70 Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Mon, 17 Aug 2020 15:31:18 +0200 Subject: [PATCH 10/13] Format according to black --- poetry/core/masonry/builders/wheel.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/poetry/core/masonry/builders/wheel.py b/poetry/core/masonry/builders/wheel.py index 5f6e6d570..a3907c675 100644 --- a/poetry/core/masonry/builders/wheel.py +++ b/poetry/core/masonry/builders/wheel.py @@ -173,7 +173,9 @@ def _write_metadata(self, wheel): license_files_to_add.append(self._path / base) license_files_to_add.extend(self._path.glob(base + ".*")) - license_files_to_add.extend((self._path / "LICENSES").glob("**" + os.pathsep + "*")) + license_files_to_add.extend( + (self._path / "LICENSES").glob("**" + os.pathsep + "*") + ) for path in license_files_to_add: if path.is_file(): From 8e83c035c595f972a47d9e45c326f09ece53f9b2 Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Mon, 17 Aug 2020 15:38:28 +0200 Subject: [PATCH 11/13] Use sep instead of pathsep --- poetry/core/masonry/builders/wheel.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/poetry/core/masonry/builders/wheel.py b/poetry/core/masonry/builders/wheel.py index a3907c675..1e3362b27 100644 --- a/poetry/core/masonry/builders/wheel.py +++ b/poetry/core/masonry/builders/wheel.py @@ -173,9 +173,7 @@ def _write_metadata(self, wheel): license_files_to_add.append(self._path / base) license_files_to_add.extend(self._path.glob(base + ".*")) - license_files_to_add.extend( - (self._path / "LICENSES").glob("**" + os.pathsep + "*") - ) + license_files_to_add.extend((self._path / "LICENSES").glob("**" + os.sep + "*")) for path in license_files_to_add: if path.is_file(): From f617feffa0c0334a2d9755f30726f180ca2b5c4c Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Mon, 17 Aug 2020 15:48:17 +0200 Subject: [PATCH 12/13] Add suggested change to poetry/core/masonry/builders/wheel.py Co-authored-by: Arun Babu Neelicattu --- poetry/core/masonry/builders/wheel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/poetry/core/masonry/builders/wheel.py b/poetry/core/masonry/builders/wheel.py index 1e3362b27..63f742eb0 100644 --- a/poetry/core/masonry/builders/wheel.py +++ b/poetry/core/masonry/builders/wheel.py @@ -175,7 +175,7 @@ def _write_metadata(self, wheel): license_files_to_add.extend((self._path / "LICENSES").glob("**" + os.sep + "*")) - for path in license_files_to_add: + for path in set(license_files_to_add): if path.is_file(): relative_path = "%s/%s" % (self.dist_info, path.relative_to(self._path)) self._add_file(wheel, path, relative_path) From de1c8b65d364c272b4b95c1d6f64d5dca3b506c4 Mon Sep 17 00:00:00 2001 From: Jonathan Frere Date: Thu, 20 Aug 2020 14:35:13 +0200 Subject: [PATCH 13/13] Update poetry/core/masonry/builders/wheel.py Co-authored-by: Arun Babu Neelicattu --- poetry/core/masonry/builders/wheel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/poetry/core/masonry/builders/wheel.py b/poetry/core/masonry/builders/wheel.py index 63f742eb0..4deb05473 100644 --- a/poetry/core/masonry/builders/wheel.py +++ b/poetry/core/masonry/builders/wheel.py @@ -173,7 +173,7 @@ def _write_metadata(self, wheel): license_files_to_add.append(self._path / base) license_files_to_add.extend(self._path.glob(base + ".*")) - license_files_to_add.extend((self._path / "LICENSES").glob("**" + os.sep + "*")) + license_files_to_add.extend(self._path.joinpath("LICENSES").glob("**/*")) for path in set(license_files_to_add): if path.is_file():