Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
python-poetry
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
python-poetry
Commits
c7825820
Unverified
Commit
c7825820
authored
May 02, 2018
by
Sébastien Eustace
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for directory dependencies
parent
d8b15dd9
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
329 additions
and
16 deletions
+329
-16
.gitignore
+1
-0
CHANGELOG.md
+2
-1
poetry/installation/pip_installer.py
+1
-1
poetry/packages/__init__.py
+1
-0
poetry/packages/dependency.py
+3
-0
poetry/packages/directory_dependency.py
+159
-0
poetry/packages/package.py
+30
-12
poetry/puzzle/provider.py
+15
-1
tests/fixtures/project_with_setup/my_package/__init__.py
+0
-0
tests/fixtures/project_with_setup/setup.py
+24
-0
tests/fixtures/sample_project/pyproject.toml
+6
-0
tests/fixtures/simple_project/pyproject.toml
+1
-1
tests/fixtures/simple_project/simple_project/__init__.py
+0
-0
tests/installation/fixtures/with-directory-dependency.test
+45
-0
tests/installation/test_installer.py
+23
-0
tests/test_poetry.py
+18
-0
No files found.
.gitignore
View file @
c7825820
...
@@ -29,3 +29,4 @@ MANIFEST.in
...
@@ -29,3 +29,4 @@ MANIFEST.in
/setup.py
/setup.py
/docs/site/*
/docs/site/*
pyproject.lock
pyproject.lock
/tests/fixtures/simple_project/setup.py
CHANGELOG.md
View file @
c7825820
...
@@ -6,8 +6,9 @@
...
@@ -6,8 +6,9 @@
-
Added the
`cache:clear`
command.
-
Added the
`cache:clear`
command.
-
Added support for
`git`
dependencies in the
`add`
command.
-
Added support for
`git`
dependencies in the
`add`
command.
-
Added support for
`
file
`
dependencies in the
`add`
command.
-
Added support for
`
path
`
dependencies in the
`add`
command.
-
Added support for extras in the
`add`
command.
-
Added support for extras in the
`add`
command.
-
Added support for directory dependencies.
-
Added support for
`src/`
layout for packages.
-
Added support for
`src/`
layout for packages.
-
Added automatic detection of
`.venv`
virtualenvs.
-
Added automatic detection of
`.venv`
virtualenvs.
...
...
poetry/installation/pip_installer.py
View file @
c7825820
...
@@ -68,7 +68,7 @@ class PipInstaller(BaseInstaller):
...
@@ -68,7 +68,7 @@ class PipInstaller(BaseInstaller):
return
req
return
req
if
package
.
source_type
==
'file'
:
if
package
.
source_type
in
[
'file'
,
'directory'
]
:
return
os
.
path
.
realpath
(
package
.
source_reference
)
return
os
.
path
.
realpath
(
package
.
source_reference
)
if
package
.
source_type
==
'git'
:
if
package
.
source_type
==
'git'
:
...
...
poetry/packages/__init__.py
View file @
c7825820
...
@@ -4,6 +4,7 @@ import re
...
@@ -4,6 +4,7 @@ import re
from
poetry.version.requirements
import
Requirement
from
poetry.version.requirements
import
Requirement
from
.dependency
import
Dependency
from
.dependency
import
Dependency
from
.directory_dependency
import
DirectoryDependency
from
.file_dependency
import
FileDependency
from
.file_dependency
import
FileDependency
from
.locker
import
Locker
from
.locker
import
Locker
from
.package
import
Package
from
.package
import
Package
...
...
poetry/packages/dependency.py
View file @
c7825820
...
@@ -109,6 +109,9 @@ class Dependency(object):
...
@@ -109,6 +109,9 @@ class Dependency(object):
def
is_file
(
self
):
def
is_file
(
self
):
return
False
return
False
def
is_directory
(
self
):
return
False
def
accepts
(
self
,
package
):
# type: (poetry.packages.Package) -> bool
def
accepts
(
self
,
package
):
# type: (poetry.packages.Package) -> bool
"""
"""
Determines if the given package matches this dependency.
Determines if the given package matches this dependency.
...
...
poetry/packages/directory_dependency.py
0 → 100644
View file @
c7825820
import
os
import
pkginfo
from
pkginfo.distribution
import
HEADER_ATTRS
from
pkginfo.distribution
import
HEADER_ATTRS_2_0
from
poetry.io
import
NullIO
from
poetry.utils._compat
import
Path
from
poetry.utils._compat
import
to_str
from
poetry.utils.helpers
import
parse_requires
from
poetry.utils.toml_file
import
TomlFile
from
poetry.utils.venv
import
NullVenv
from
poetry.utils.venv
import
Venv
from
.dependency
import
Dependency
# Patching pkginfo to support Metadata version 2.1 (PEP 566)
HEADER_ATTRS
.
update
(
{
'2.1'
:
HEADER_ATTRS_2_0
+
(
(
'Provides-Extra'
,
'provides_extra'
,
True
),
)
}
)
class
DirectoryDependency
(
Dependency
):
def
__init__
(
self
,
path
,
# type: Path
category
=
'main'
,
# type: str
optional
=
False
,
# type: bool
base
=
None
,
# type: Path
develop
=
False
# type: bool
):
from
.
import
dependency_from_pep_508
self
.
_path
=
path
self
.
_base
=
base
self
.
_full_path
=
path
self
.
_develop
=
develop
if
self
.
_base
and
not
self
.
_path
.
is_absolute
():
self
.
_full_path
=
self
.
_base
/
self
.
_path
if
not
self
.
_full_path
.
exists
():
raise
ValueError
(
'Directory {} does not exist'
.
format
(
self
.
_path
))
if
self
.
_full_path
.
is_file
():
raise
ValueError
(
'{} is a file, expected a directory'
.
format
(
self
.
_path
)
)
# Checking content to dertermine actions
setup
=
self
.
_full_path
/
'setup.py'
pyproject
=
TomlFile
(
self
.
_full_path
/
'pyproject.toml'
)
has_poetry
=
False
if
pyproject
.
exists
():
pyproject_content
=
pyproject
.
read
(
True
)
has_poetry
=
(
'tool'
in
pyproject_content
and
'poetry'
in
pyproject_content
[
'tool'
]
)
if
not
setup
.
exists
()
and
not
has_poetry
:
raise
ValueError
(
'Directory {} does not seem to be a Python package'
.
format
(
self
.
_full_path
)
)
if
has_poetry
:
from
poetry.masonry.builders
import
SdistBuilder
from
poetry.poetry
import
Poetry
poetry
=
Poetry
.
create
(
self
.
_full_path
)
builder
=
SdistBuilder
(
poetry
,
NullVenv
(),
NullIO
())
with
setup
.
open
(
'w'
)
as
f
:
f
.
write
(
to_str
(
builder
.
build_setup
()))
self
.
_package
=
poetry
.
package
else
:
from
poetry.packages
import
Package
# Execute egg_info
current_dir
=
os
.
getcwd
()
os
.
chdir
(
str
(
self
.
_full_path
))
try
:
cwd
=
base
venv
=
Venv
.
create
(
NullIO
(),
cwd
=
cwd
)
venv
.
run
(
'python'
,
'setup.py'
,
'egg_info'
)
finally
:
os
.
chdir
(
current_dir
)
egg_info
=
list
(
self
.
_full_path
.
glob
(
'*.egg-info'
))[
0
]
meta
=
pkginfo
.
UnpackedSDist
(
str
(
egg_info
))
if
meta
.
requires_dist
:
reqs
=
list
(
meta
.
requires_dist
)
else
:
reqs
=
[]
requires
=
egg_info
/
'requires.txt'
if
requires
.
exists
():
with
requires
.
open
()
as
f
:
reqs
=
parse_requires
(
f
.
read
())
package
=
Package
(
meta
.
name
,
meta
.
version
)
package
.
description
=
meta
.
summary
for
req
in
reqs
:
package
.
requires
.
append
(
dependency_from_pep_508
(
req
))
if
meta
.
requires_python
:
package
.
python_versions
=
meta
.
requires_python
if
meta
.
platforms
:
platforms
=
[
p
for
p
in
meta
.
platforms
if
p
.
lower
()
!=
'unknown'
]
if
platforms
:
package
.
platform
=
' || '
.
join
(
platforms
)
self
.
_package
=
package
self
.
_package
.
source_type
=
'directory'
self
.
_package
.
source_reference
=
str
(
self
.
_path
)
super
(
DirectoryDependency
,
self
)
.
__init__
(
self
.
_package
.
name
,
self
.
_package
.
version
,
category
=
category
,
optional
=
optional
,
allows_prereleases
=
True
)
@property
def
path
(
self
):
return
self
.
_path
@property
def
full_path
(
self
):
return
self
.
_full_path
.
resolve
()
@property
def
package
(
self
):
return
self
.
_package
@property
def
develop
(
self
):
return
self
.
_develop
def
is_directory
(
self
):
return
True
poetry/packages/package.py
View file @
c7825820
...
@@ -15,6 +15,7 @@ from poetry.version import parse as parse_version
...
@@ -15,6 +15,7 @@ from poetry.version import parse as parse_version
from
.constraints.generic_constraint
import
GenericConstraint
from
.constraints.generic_constraint
import
GenericConstraint
from
.dependency
import
Dependency
from
.dependency
import
Dependency
from
.directory_dependency
import
DirectoryDependency
from
.file_dependency
import
FileDependency
from
.file_dependency
import
FileDependency
from
.vcs_dependency
import
VCSDependency
from
.vcs_dependency
import
VCSDependency
...
@@ -273,20 +274,37 @@ class Package(object):
...
@@ -273,20 +274,37 @@ class Package(object):
rev
=
constraint
.
get
(
'rev'
,
None
),
rev
=
constraint
.
get
(
'rev'
,
None
),
optional
=
optional
,
optional
=
optional
,
)
)
if
python_versions
:
dependency
.
python_versions
=
python_versions
if
platform
:
dependency
.
platform
=
platform
elif
'file'
in
constraint
:
elif
'file'
in
constraint
:
file_path
=
Path
(
constraint
[
'file'
])
file_path
=
Path
(
constraint
[
'file'
])
dependency
=
FileDependency
(
file_path
,
base
=
self
.
cwd
)
dependency
=
FileDependency
(
file_path
,
category
=
category
,
base
=
self
.
cwd
)
elif
'path'
in
constraint
:
elif
'path'
in
constraint
:
path
=
Path
(
constraint
[
'path'
])
path
=
Path
(
constraint
[
'path'
])
dependency
=
FileDependency
(
path
,
base
=
self
.
cwd
)
if
self
.
cwd
:
is_file
=
(
self
.
cwd
/
path
)
.
is_file
()
else
:
is_file
=
path
.
is_file
()
if
is_file
:
dependency
=
FileDependency
(
path
,
category
=
category
,
optional
=
optional
,
base
=
self
.
cwd
)
else
:
dependency
=
DirectoryDependency
(
path
,
category
=
category
,
optional
=
optional
,
base
=
self
.
cwd
,
develop
=
constraint
.
get
(
'develop'
,
False
)
)
else
:
else
:
version
=
constraint
[
'version'
]
version
=
constraint
[
'version'
]
...
@@ -297,11 +315,11 @@ class Package(object):
...
@@ -297,11 +315,11 @@ class Package(object):
allows_prereleases
=
allows_prereleases
allows_prereleases
=
allows_prereleases
)
)
if
python_versions
:
if
python_versions
:
dependency
.
python_versions
=
python_versions
dependency
.
python_versions
=
python_versions
if
platform
:
if
platform
:
dependency
.
platform
=
platform
dependency
.
platform
=
platform
if
'extras'
in
constraint
:
if
'extras'
in
constraint
:
for
extra
in
constraint
[
'extras'
]:
for
extra
in
constraint
[
'extras'
]:
...
...
poetry/puzzle/provider.py
View file @
c7825820
...
@@ -14,6 +14,7 @@ from poetry.mixology.contracts import SpecificationProvider
...
@@ -14,6 +14,7 @@ from poetry.mixology.contracts import SpecificationProvider
from
poetry.mixology.contracts
import
UI
from
poetry.mixology.contracts
import
UI
from
poetry.packages
import
Dependency
from
poetry.packages
import
Dependency
from
poetry.packages
import
DirectoryDependency
from
poetry.packages
import
FileDependency
from
poetry.packages
import
FileDependency
from
poetry.packages
import
Package
from
poetry.packages
import
Package
from
poetry.packages
import
VCSDependency
from
poetry.packages
import
VCSDependency
...
@@ -84,6 +85,8 @@ class Provider(SpecificationProvider, UI):
...
@@ -84,6 +85,8 @@ class Provider(SpecificationProvider, UI):
packages
=
self
.
search_for_vcs
(
dependency
)
packages
=
self
.
search_for_vcs
(
dependency
)
elif
dependency
.
is_file
():
elif
dependency
.
is_file
():
packages
=
self
.
search_for_file
(
dependency
)
packages
=
self
.
search_for_file
(
dependency
)
elif
dependency
.
is_directory
():
packages
=
self
.
search_for_directory
(
dependency
)
else
:
else
:
constraint
=
dependency
.
constraint
constraint
=
dependency
.
constraint
...
@@ -237,9 +240,20 @@ class Provider(SpecificationProvider, UI):
...
@@ -237,9 +240,20 @@ class Provider(SpecificationProvider, UI):
return
[
package
]
return
[
package
]
def
search_for_directory
(
self
,
dependency
):
# type: (DirectoryDependency) -> List[Package]
package
=
dependency
.
package
if
dependency
.
extras
:
for
extra
in
dependency
.
extras
:
if
extra
in
package
.
extras
:
for
dep
in
package
.
extras
[
extra
]:
dep
.
activate
()
return
[
package
]
def
dependencies_for
(
self
,
package
def
dependencies_for
(
self
,
package
):
# type: (Package) -> Union[List[Dependency], Dependencies]
):
# type: (Package) -> Union[List[Dependency], Dependencies]
if
package
.
source_type
in
[
'git'
,
'file'
]:
if
package
.
source_type
in
[
'git'
,
'file'
,
'directory'
]:
# Information should already be set
# Information should already be set
return
[
return
[
r
for
r
in
package
.
requires
r
for
r
in
package
.
requires
...
...
tests/fixtures/project_with_setup/my_package/__init__.py
0 → 100644
View file @
c7825820
tests/fixtures/project_with_setup/setup.py
0 → 100644
View file @
c7825820
# -*- coding: utf-8 -*-
from
setuptools
import
setup
kwargs
=
dict
(
name
=
'my-package'
,
license
=
'MIT'
,
version
=
'0.1.2'
,
description
=
'Demo project.'
,
author
=
'Sébastien Eustace'
,
author_email
=
'sebastien@eustace.io'
,
url
=
'https://github.com/demo/demo'
,
packages
=
[
'my_package'
,
],
install_requires
=
[
'pendulum>=1.4.4'
,
'cachy[msgpack]>=0.2.0,<0.3.0'
,
],
)
setup
(
**
kwargs
)
tests/fixtures/sample_project/pyproject.toml
View file @
c7825820
...
@@ -33,6 +33,12 @@ orator = { version = "^0.9", optional = true }
...
@@ -33,6 +33,12 @@ orator = { version = "^0.9", optional = true }
# File dependency
# File dependency
demo
=
{
path
=
"../distributions/demo-0.1.0-py2.py3-none-any.whl"
}
demo
=
{
path
=
"../distributions/demo-0.1.0-py2.py3-none-any.whl"
}
# Dir dependency with setup.py
my-package
=
{
path
=
"../project_with_setup/"
}
# Dir dependency with pyproject.toml
simple-project
=
{
path
=
"../simple_project/"
}
[tool.poetry.extras]
[tool.poetry.extras]
db
=
[
"orator"
]
db
=
[
"orator"
]
...
...
tests/fixtures/simple_project/pyproject.toml
View file @
c7825820
[tool.poetry]
[tool.poetry]
name
=
"
my-package
"
name
=
"
simple-project
"
version
=
"1.2.3"
version
=
"1.2.3"
description
=
"Some description."
description
=
"Some description."
authors
=
[
authors
=
[
...
...
tests/fixtures/simple_project/simple_project/__init__.py
0 → 100644
View file @
c7825820
tests/installation/fixtures/with-directory-dependency.test
0 → 100644
View file @
c7825820
[[
package
]]
name
=
"cachy"
version
=
"0.2.0"
description
=
""
category
=
"main"
optional
=
false
python
-
versions
=
"*"
platform
=
"*"
[[
package
]]
name
=
"my-package"
version
=
"0.1.2"
description
=
"Demo project."
category
=
"main"
optional
=
false
python
-
versions
=
"*"
platform
=
"*"
[
package
.
source
]
type
=
"directory"
reference
=
"tests/fixtures/project_with_setup"
url
=
""
[
package
.
dependencies
]
cachy
=
"< 0.3.0.0, >= 0.2.0.0"
pendulum
=
">= 1.4.4.0"
[[
package
]]
name
=
"pendulum"
version
=
"1.4.4"
description
=
""
category
=
"main"
optional
=
false
python
-
versions
=
"*"
platform
=
"*"
[
metadata
]
python
-
versions
=
"*"
platform
=
"*"
content
-
hash
=
"123456789"
[
metadata
.
hashes
]
cachy
=
[]
my
-
package
=
[]
pendulum
=
[]
tests/installation/test_installer.py
View file @
c7825820
...
@@ -549,3 +549,26 @@ def test_run_installs_with_local_file(installer, locker, repo, package):
...
@@ -549,3 +549,26 @@ def test_run_installs_with_local_file(installer, locker, repo, package):
assert
locker
.
written_data
==
expected
assert
locker
.
written_data
==
expected
assert
len
(
installer
.
installer
.
installs
)
==
2
assert
len
(
installer
.
installer
.
installs
)
==
2
def
test_run_installs_with_local_directory
(
installer
,
locker
,
repo
,
package
):
file_path
=
Path
(
'tests/fixtures/project_with_setup/'
)
package
.
add_dependency
(
'demo'
,
{
'path'
:
str
(
file_path
)
}
)
repo
.
add_package
(
get_package
(
'pendulum'
,
'1.4.4'
))
repo
.
add_package
(
get_package
(
'cachy'
,
'0.2.0'
))
installer
.
run
()
expected
=
fixture
(
'with-directory-dependency'
)
assert
locker
.
written_data
==
expected
assert
len
(
installer
.
installer
.
installs
)
==
3
tests/test_poetry.py
View file @
c7825820
...
@@ -63,6 +63,24 @@ def test_poetry():
...
@@ -63,6 +63,24 @@ def test_poetry():
assert
demo
.
name
==
'demo'
assert
demo
.
name
==
'demo'
assert
demo
.
pretty_constraint
==
'0.1.0'
assert
demo
.
pretty_constraint
==
'0.1.0'
demo
=
dependencies
[
'my-package'
]
assert
not
demo
.
is_file
()
assert
demo
.
is_directory
()
assert
not
demo
.
is_vcs
()
assert
demo
.
name
==
'my-package'
assert
demo
.
pretty_constraint
==
'0.1.2'
assert
demo
.
package
.
requires
[
0
]
.
name
==
'pendulum'
assert
demo
.
package
.
requires
[
1
]
.
name
==
'cachy'
assert
demo
.
package
.
requires
[
1
]
.
extras
==
[
'msgpack'
]
simple_project
=
dependencies
[
'simple-project'
]
assert
not
simple_project
.
is_file
()
assert
simple_project
.
is_directory
()
assert
not
simple_project
.
is_vcs
()
assert
simple_project
.
name
==
'simple-project'
assert
simple_project
.
pretty_constraint
==
'1.2.3'
assert
simple_project
.
package
.
requires
==
[]
assert
'db'
in
package
.
extras
assert
'db'
in
package
.
extras
classifiers
=
package
.
classifiers
classifiers
=
package
.
classifiers
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment