diff --git a/docs/docs/pyproject.md b/docs/docs/pyproject.md
index 679ad824a22..7a2e6698ecb 100644
--- a/docs/docs/pyproject.md
+++ b/docs/docs/pyproject.md
@@ -40,6 +40,15 @@ The recommended notation for the most common licenses is (alphabetical):
Optional, but it is highly recommended to supply this.
More identifiers are listed at the [SPDX Open Source License Registry](https://www.spdx.org/licenses/).
+## license-files
+
+The license file(s) belonging to this package. **optional**
+
+Poetry will automatically include files matching `LICENSE*` and `COPYING*`,
+but if you have licenses files that do not fit these patterns,
+you can configure `poetry` to include one or more files as the license files.
+These paths should be relative to the project root directory, where the `pyproject.toml` lives.
+
## authors
The authors of the package. **Required**
diff --git a/poetry/factory.py b/poetry/factory.py
index 93361f24dd0..c61f492edcc 100644
--- a/poetry/factory.py
+++ b/poetry/factory.py
@@ -81,6 +81,16 @@ def create_poetry(
if "readme" in local_config:
package.readme = Path(poetry_file.parent) / local_config["readme"]
+ # Add any manually defined or automatically discovered license files.
+ if "license-files" in local_config:
+ for license_file in local_config["license-files"]:
+ package.license_files.add(Path(poetry_file.parent) / license_file)
+ else:
+ for license_file in poetry_file.parent.glob("LICENSE*"):
+ package.license_files.add(license_file.relative_to(poetry_file.parent))
+ for license_file in poetry_file.parent.glob("COPYING*"):
+ package.license_files.add(license_file.relative_to(poetry_file.parent))
+
if "platform" in local_config:
package.platform = local_config["platform"]
diff --git a/poetry/json/schemas/poetry-schema.json b/poetry/json/schemas/poetry-schema.json
index 10aff39e502..3e86fe7f5eb 100644
--- a/poetry/json/schemas/poetry-schema.json
+++ b/poetry/json/schemas/poetry-schema.json
@@ -47,6 +47,9 @@
"type": "string",
"description": "License name."
},
+ "license-files": {
+ "$ref": "#/definitions/license-files"
+ },
"authors": {
"$ref": "#/definitions/authors"
},
@@ -183,6 +186,13 @@
"type": "string"
}
},
+ "license-files": {
+ "type": "array",
+ "description": "A list of license files applicable to this packages. This accepts multiple files for situations involving more complicated licensing situations.",
+ "items": {
+ "type": "string"
+ }
+ },
"maintainers": {
"type": "array",
"description": "List of maintainers, other than the original author(s), that upkeep the package.",
diff --git a/poetry/masonry/builders/builder.py b/poetry/masonry/builders/builder.py
index af1a05a29d4..899e367a7aa 100644
--- a/poetry/masonry/builders/builder.py
+++ b/poetry/masonry/builders/builder.py
@@ -154,8 +154,9 @@ def find_files_to_add(self, exclude_build=True): # type: (bool) -> list
)
to_add.append(Path("pyproject.toml"))
- # If a license file exists, add it
- for license_file in self._path.glob("LICENSE*"):
+ # If any license files exist, add them.
+ for license_filename in self._package.license_files:
+ license_file = self._path / license_filename
self._io.write_line(
" - Adding: {}".format(
license_file.relative_to(self._path)
diff --git a/poetry/masonry/builders/sdist.py b/poetry/masonry/builders/sdist.py
index e1fadc0b7cb..b6774385d6d 100644
--- a/poetry/masonry/builders/sdist.py
+++ b/poetry/masonry/builders/sdist.py
@@ -136,6 +136,11 @@ def build_setup(self): # type: () -> bytes
else:
pass
+ license_files = list(map(str, self._package.license_files))
+ if license_files:
+ before.append("license_files = \\\n{}\n".format(pformat(license_files)))
+ extra.append("'license_files': license_files,")
+
if package_dir:
before.append("package_dir = \\\n{}\n".format(pformat(package_dir)))
extra.append("'package_dir': package_dir,")
diff --git a/poetry/masonry/builders/wheel.py b/poetry/masonry/builders/wheel.py
index 058679edb4e..823d3737817 100644
--- a/poetry/masonry/builders/wheel.py
+++ b/poetry/masonry/builders/wheel.py
@@ -181,9 +181,11 @@ def _write_metadata(self, wheel):
with self._write_to_zip(wheel, self.dist_info + "/entry_points.txt") as f:
self._write_entry_points(f)
- 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))
+ for relative_license_path in self._package.license_files:
+ license_path = self._path / relative_license_path
+ self._add_file(
+ wheel, license_path, "%s/%s" % (self.dist_info, license_path.name)
+ )
with self._write_to_zip(wheel, self.dist_info + "/WHEEL") as f:
self._write_wheel_file(f)
diff --git a/poetry/packages/package.py b/poetry/packages/package.py
index 0811c54bf88..4a9c0dfee00 100644
--- a/poetry/packages/package.py
+++ b/poetry/packages/package.py
@@ -58,6 +58,7 @@ def __init__(self, name, version, pretty_version=None):
self.documentation_url = None
self.keywords = []
self._license = None
+ self.license_files = set()
self.readme = None
self.source_name = ""
diff --git a/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/README.rst b/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/README.rst
new file mode 100644
index 00000000000..a7508bd515e
--- /dev/null
+++ b/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/README.rst
@@ -0,0 +1,2 @@
+Module 1
+========
diff --git a/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/pyproject.toml b/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/pyproject.toml
new file mode 100644
index 00000000000..1bcf1ccac41
--- /dev/null
+++ b/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/pyproject.toml
@@ -0,0 +1,18 @@
+[tool.poetry]
+name = "the-package"
+version = "4.5.6"
+description = "Some description."
+authors = [
+ "Sébastien Eustace "
+]
+license-files = [
+ "the-first-license.txt",
+ "the-second-license.txt"
+]
+
+
+readme = "README.rst"
+
+
+[tool.poetry.dependencies]
+python = "3.6"
diff --git a/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/the-first-license.txt b/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/the-first-license.txt
new file mode 100644
index 00000000000..44cf2b30e68
--- /dev/null
+++ b/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/the-first-license.txt
@@ -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/explicit-license-config-multiple-licenses/the-second-license.txt b/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/the-second-license.txt
new file mode 100644
index 00000000000..44cf2b30e68
--- /dev/null
+++ b/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/the-second-license.txt
@@ -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/explicit-license-config-multiple-licenses/the_package/__init__.py b/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/the_package/__init__.py
new file mode 100644
index 00000000000..7ef41c5d4ea
--- /dev/null
+++ b/tests/masonry/builders/fixtures/explicit-license-config-multiple-licenses/the_package/__init__.py
@@ -0,0 +1,3 @@
+"""Example module"""
+
+__version__ = "0.1"
diff --git a/tests/masonry/builders/fixtures/explicit-license-config-single-license/README.rst b/tests/masonry/builders/fixtures/explicit-license-config-single-license/README.rst
new file mode 100644
index 00000000000..a7508bd515e
--- /dev/null
+++ b/tests/masonry/builders/fixtures/explicit-license-config-single-license/README.rst
@@ -0,0 +1,2 @@
+Module 1
+========
diff --git a/tests/masonry/builders/fixtures/explicit-license-config-single-license/pyproject.toml b/tests/masonry/builders/fixtures/explicit-license-config-single-license/pyproject.toml
new file mode 100644
index 00000000000..d6ff5c859ff
--- /dev/null
+++ b/tests/masonry/builders/fixtures/explicit-license-config-single-license/pyproject.toml
@@ -0,0 +1,16 @@
+[tool.poetry]
+name = "the-package"
+version = "4.5.6"
+description = "Some description."
+authors = [
+ "Sébastien Eustace "
+]
+license-files = [
+ "the-license.txt"
+]
+
+readme = "README.rst"
+
+
+[tool.poetry.dependencies]
+python = "3.6"
diff --git a/tests/masonry/builders/fixtures/explicit-license-config-single-license/the-license.txt b/tests/masonry/builders/fixtures/explicit-license-config-single-license/the-license.txt
new file mode 100644
index 00000000000..44cf2b30e68
--- /dev/null
+++ b/tests/masonry/builders/fixtures/explicit-license-config-single-license/the-license.txt
@@ -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/explicit-license-config-single-license/the_package/__init__.py b/tests/masonry/builders/fixtures/explicit-license-config-single-license/the_package/__init__.py
new file mode 100644
index 00000000000..7ef41c5d4ea
--- /dev/null
+++ b/tests/masonry/builders/fixtures/explicit-license-config-single-license/the_package/__init__.py
@@ -0,0 +1,3 @@
+"""Example module"""
+
+__version__ = "0.1"
diff --git a/tests/masonry/builders/fixtures/multiple-licenses/COPYING.txt b/tests/masonry/builders/fixtures/multiple-licenses/COPYING.txt
new file mode 100644
index 00000000000..44cf2b30e68
--- /dev/null
+++ b/tests/masonry/builders/fixtures/multiple-licenses/COPYING.txt
@@ -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/multiple-licenses/LICENSE.txt b/tests/masonry/builders/fixtures/multiple-licenses/LICENSE.txt
new file mode 100644
index 00000000000..44cf2b30e68
--- /dev/null
+++ b/tests/masonry/builders/fixtures/multiple-licenses/LICENSE.txt
@@ -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/multiple-licenses/README.rst b/tests/masonry/builders/fixtures/multiple-licenses/README.rst
new file mode 100644
index 00000000000..a7508bd515e
--- /dev/null
+++ b/tests/masonry/builders/fixtures/multiple-licenses/README.rst
@@ -0,0 +1,2 @@
+Module 1
+========
diff --git a/tests/masonry/builders/fixtures/multiple-licenses/pyproject.toml b/tests/masonry/builders/fixtures/multiple-licenses/pyproject.toml
new file mode 100644
index 00000000000..26a226218e0
--- /dev/null
+++ b/tests/masonry/builders/fixtures/multiple-licenses/pyproject.toml
@@ -0,0 +1,13 @@
+[tool.poetry]
+name = "the-package"
+version = "4.5.6"
+description = "Some description."
+authors = [
+ "Sébastien Eustace "
+]
+
+readme = "README.rst"
+
+
+[tool.poetry.dependencies]
+python = "3.6"
diff --git a/tests/masonry/builders/fixtures/multiple-licenses/the_package/__init__.py b/tests/masonry/builders/fixtures/multiple-licenses/the_package/__init__.py
new file mode 100644
index 00000000000..fdac64b9433
--- /dev/null
+++ b/tests/masonry/builders/fixtures/multiple-licenses/the_package/__init__.py
@@ -0,0 +1,3 @@
+"""Example module"""
+
+__version__ = "4.5.6"
diff --git a/tests/masonry/builders/test_complete.py b/tests/masonry/builders/test_complete.py
index 05ae2e17824..6216736538a 100644
--- a/tests/masonry/builders/test_complete.py
+++ b/tests/masonry/builders/test_complete.py
@@ -395,6 +395,79 @@ def test_package_src():
zip.close()
+def test_multiple_licenses():
+ module_path = fixtures_dir / "multiple-licenses"
+ builder = CompleteBuilder(
+ Factory().create_poetry(module_path), NullEnv(execute=True), NullIO()
+ )
+ builder.build()
+
+ sdist = module_path / "dist" / "the-package-4.5.6.tar.gz"
+ wheel = module_path / "dist" / "the_package-4.5.6-py3-none-any.whl"
+
+ assert sdist.exists()
+ with tarfile.open(str(sdist), "r") as tar:
+ names = tar.getnames()
+ assert len(names) == len(set(names))
+ assert "the-package-4.5.6/LICENSE.txt" in names
+ assert "the-package-4.5.6/COPYING.txt" in names
+
+ assert wheel.exists()
+ with zipfile.ZipFile(str(wheel)) as z:
+ names = z.namelist()
+ assert len(names) == len(set(names))
+ assert "the_package-4.5.6.dist-info/LICENSE.txt" in names
+ assert "the_package-4.5.6.dist-info/COPYING.txt" in names
+
+
+def test_explicit_license_config_single_license():
+ module_path = fixtures_dir / "explicit-license-config-single-license"
+ builder = CompleteBuilder(
+ Factory().create_poetry(module_path), NullEnv(execute=True), NullIO()
+ )
+ builder.build()
+
+ sdist = module_path / "dist" / "the-package-4.5.6.tar.gz"
+ wheel = module_path / "dist" / "the_package-4.5.6-py3-none-any.whl"
+
+ assert sdist.exists()
+ with tarfile.open(str(sdist), "r") as tar:
+ names = tar.getnames()
+ assert len(names) == len(set(names))
+ assert "the-package-4.5.6/the-license.txt" in names
+
+ assert wheel.exists()
+ with zipfile.ZipFile(str(wheel)) as z:
+ names = z.namelist()
+ assert len(names) == len(set(names))
+ assert "the_package-4.5.6.dist-info/the-license.txt" in names
+
+
+def test_explicit_license_config_multiple_licenses():
+ module_path = fixtures_dir / "explicit-license-config-multiple-licenses"
+ builder = CompleteBuilder(
+ Factory().create_poetry(module_path), NullEnv(execute=True), NullIO()
+ )
+ builder.build()
+
+ sdist = module_path / "dist" / "the-package-4.5.6.tar.gz"
+ wheel = module_path / "dist" / "the_package-4.5.6-py3-none-any.whl"
+
+ assert sdist.exists()
+ with tarfile.open(str(sdist), "r") as tar:
+ names = tar.getnames()
+ assert len(names) == len(set(names))
+ assert "the-package-4.5.6/the-first-license.txt" in names
+ assert "the-package-4.5.6/the-second-license.txt" in names
+
+ assert wheel.exists()
+ with zipfile.ZipFile(str(wheel)) as z:
+ names = z.namelist()
+ assert len(names) == len(set(names))
+ assert "the_package-4.5.6.dist-info/the-first-license.txt" in names
+ assert "the_package-4.5.6.dist-info/the-second-license.txt" in names
+
+
def test_package_with_include(mocker):
module_path = fixtures_dir / "with-include"